漏洞丨實(shí)例分析cve2012-0158

作者:黑蛋
一、漏洞簡(jiǎn)介
CVE-2012-0158是一個(gè)office棧溢出漏洞,Microsoft Office 2003 sp3是2007年9月18日由微軟公司創(chuàng)作的一個(gè)辦公軟件,他的MSCOMCTL.ocx中的MSCOMCTL.ListView控件檢查失誤,由于讀取長(zhǎng)度和驗(yàn)證長(zhǎng)度都在文件中,這樣參數(shù)可以人為修改,觸發(fā)緩沖區(qū)溢出漏洞。
二、漏洞環(huán)境準(zhǔn)備
系統(tǒng)版本
目標(biāo)程序
調(diào)試軟件
16進(jìn)制編輯器
XP SP3
Microsoft Office 2003
od、x32dbg
010Editor
三、漏洞驗(yàn)證
這里我借用了一個(gè)帖子的POC,借用POC帖子(https://bbs.pediy.com/thread-207638.htm)
在XP SP3中安裝office2003:
之后下載POC。拖到虛擬機(jī)中,用office打開(kāi),彈出個(gè)計(jì)算機(jī)(注意這個(gè)POC用一次會(huì)損壞,需要備份):
四、漏洞分析
首先用OD附加office,F(xiàn)9運(yùn)行,然后用office打開(kāi)POC文件(新的):
查看堆棧:
啥也沒(méi)看出來(lái),堆棧前后看了一下也沒(méi)發(fā)現(xiàn)形似shellcode的東西,下了幾個(gè)斷點(diǎn)也沒(méi)有,只能另尋他法!
倆個(gè)辦法
(1)把POC拖到010Editor看看有沒(méi)有特征可以看看
(2)對(duì)彈出計(jì)算器用到的函數(shù)下斷點(diǎn)
先用第一個(gè)辦法:
拖到010Editor中,搜搜有沒(méi)有9090(nop滑板指令,大部分會(huì)有這種指令用來(lái)湊數(shù)或者保護(hù)數(shù)據(jù)等)之類的,運(yùn)氣不錯(cuò),找到相似的。
9090909090909090前面有四個(gè)字節(jié),像一個(gè)庫(kù)里面的地址7FFA4512,后面一堆看著像shellcode,附加office,看看這個(gè)地址是個(gè)啥東西:
一個(gè)jmp esp,典型的跳板指令,差不多就是這個(gè)地方溢出返回值,我們嘗試改一下這里,驗(yàn)證一下:
把這個(gè)跳板改成11111111試試:
保存,OD附加office,打開(kāi)poc,EIP果然等于11111111:
這就算撞到了溢出點(diǎn),我們用原來(lái)的POC,在jmp esp這里下硬件斷點(diǎn)看看堆棧情況:
斷點(diǎn)斷在jmpesp,繼續(xù)運(yùn)行,到了shellcode的地方:
從這里也能夠看出溢出函數(shù)末尾是ret 8,esp直接+8,F(xiàn)8運(yùn)行幾步,彈出計(jì)算器:
我們?cè)囍鎿Qshellcode,改成自己的彈窗shellcode,不改變文件原來(lái)大小,替換掉9090909090909090后面的shellcode就行,因?yàn)槲业膕hellcode結(jié)尾會(huì)自動(dòng)退出程序,所以不需要管原來(lái)shellcode長(zhǎng)度過(guò)長(zhǎng)的問(wèn)題,但是這里卡了一個(gè)bug,修改完shellcode之后,并沒(méi)有出現(xiàn)彈窗,猜想可能是我們自己的shellcode結(jié)尾接了原來(lái)的字節(jié)碼,導(dǎo)致識(shí)別出錯(cuò),于是我把我們的彈窗shellcode后面8字節(jié)改成90,成功彈窗(這里發(fā)現(xiàn)改過(guò)得POC不再是一次性的了,可能是因?yàn)閺棿皊hellcode長(zhǎng)度較小,不會(huì)被破壞):
下面給出我剛才替換的彈窗shellcode:
FC 68 6A 0A 38 1E 68 63 89 D1 4F 68 32 74 91 0C
8B F4 8D 7E F4 33 DB B7 04 2B E3 66 BB 33 32 53
68 75 73 65 72 54 33 D2 64 8B 5A 30 8B 4B 0C 8B
49 1C 8B 09 8B 69 08 AD 3D 6A 0A 38 1E 75 05 95
FF 57 F8 95 60 8B 45 3C 8B 4C 05 78 03 CD 8B 59
20 03 DD 33 FF 47 8B 34 BB 03 F5 99 0F BE 06 3A
C4 74 08 C1 CA 07 03 D0 46 EB F1 3B 54 24 1C 75
E4 8B 59 24 03 DD 66 8B 3C 7B 8B 59 1C 03 DD 03
2C BB 95 5F AB 57 61 3D 6A 0A 38 1E 75 A9 33 DB
53 68 66 66 66 66 68 66 66 66 66 8B C4 53 50 50
53 FF 57 FC 53 FF 57 F8
這是替換shellcode結(jié)尾部分:
這是一次簡(jiǎn)單的替換,接下來(lái)我們繼續(xù)分析這個(gè)漏洞的前因后果,我們使用改過(guò)的的彈窗POC,我們?cè)趈mp esp處下斷點(diǎn):
斷點(diǎn)斷在jmp esp處,我們?cè)跅5那懊姘l(fā)現(xiàn)調(diào)用了一個(gè)MSCOMTL模塊的函數(shù),我們調(diào)到對(duì)應(yīng)的地址上面,記錄這個(gè)地址275C8A0A,并下斷點(diǎn):
重新運(yùn)行,斷在了斷點(diǎn)處:
F8單步調(diào)試,發(fā)現(xiàn)這個(gè)函數(shù)結(jié)束后,彈窗彈出,說(shuō)明這個(gè)函數(shù)就是關(guān)鍵函數(shù),而結(jié)尾也如我們之前所想,是ret 8:
接下來(lái)就是著重分析這個(gè)函數(shù),重新調(diào)試,斷在這個(gè)函數(shù)頭部(push ebp是函數(shù)頭):
我們發(fā)現(xiàn)執(zhí)行完下面這個(gè)函數(shù),返回值被修改,我們shellcode拷貝進(jìn)去,也即是說(shuō)這個(gè)拷貝函數(shù)是關(guān)鍵函數(shù):
繼續(xù)分析這個(gè)函數(shù),下斷點(diǎn),重新運(yùn)行,斷在關(guān)鍵函數(shù)
這里:
F7跟進(jìn)去,分析函數(shù):
拷貝參數(shù)ECX=8282,這是一個(gè)關(guān)鍵點(diǎn),拷貝之后,返回地址被淹沒(méi),因?yàn)檫@個(gè)漏洞就是因?yàn)榭截愰L(zhǎng)度都在文本中存著,所以我們?cè)囍赑OC中搜索8282:
這里有倆個(gè)8282,我們都修改一下,分別改成1111和2222,再回到這個(gè)函數(shù)觀察:
可以看到數(shù)據(jù)已經(jīng)不同,有點(diǎn)缺陷是我們改的姿勢(shì)不對(duì),數(shù)據(jù)變成02001111和02022,接下來(lái)運(yùn)行會(huì)卡住,所以這里是一個(gè)驗(yàn)證代碼,倆個(gè)數(shù)值只能相等,繼續(xù)把倆處地址改成2222,直接觀察關(guān)鍵函數(shù)里面拷貝那塊的ECX賦值結(jié)果:
和我們預(yù)期一樣,文本中原來(lái)2個(gè)8282是拷貝字符串長(zhǎng)度還有其驗(yàn)證,倆者必須一樣,其次會(huì)根據(jù)這個(gè)數(shù)值對(duì)字符串進(jìn)行拷貝。下面給一張圖解:
前倆個(gè)紅線處是拷貝長(zhǎng)度還有其驗(yàn)證數(shù)值,第三個(gè)紅線是一個(gè)jmp esp跳板,之后隔八字節(jié)就可以放shellcode。
五、結(jié)束
CVE-2012-0158這個(gè)漏洞分析到此結(jié)束。