來源:http://bbs.ichunqiu.com/thread-10108-1-1.html?from=ch
試想:某一天,你的基友給你了一個視頻文件,號稱是陳老師拍的蒼老師的老師題材的最新電影.avi,你滿心歡喜,在確定文件格式確實為avi格式后,愉快的脫下褲子準(zhǔn)備欣賞,打開后卻發(fā)現(xiàn)什么也沒有,而隨后你的基友就控制了你的電腦,把你辛辛苦苦珍藏了二十年的片源全部偷走了…….
今天我們分析的漏洞就是一個利用播放器解壓縮時處理不當(dāng)引起的遠(yuǎn)程執(zhí)行漏洞,這個漏洞并沒有大規(guī)模流行,我們只是從技術(shù)角度解析漏洞成因。
0x 00漏洞介紹
CVE 2010-2553漏洞,也稱為MicrosoftWindows Cinepak 編碼解碼器解壓縮漏洞,影響的操作系統(tǒng)版本有:Microsoft Windows XP SP2和SP3,WindowsVista SP1和SP2,以及Windows 7。
漏洞原因在于Cinepak 編碼解碼器對媒體文件解壓縮時代碼控制不恰當(dāng),可導(dǎo)致遠(yuǎn)程代碼執(zhí)行。如果用戶打開特制的媒體文件,此漏洞可能允許執(zhí)行代碼。如果用戶使用管理用戶權(quán)限登錄,成功利用此漏洞的攻擊者便可完全控制受影響的系統(tǒng)。
漏洞利用wmplay.exe,而wmplay.exe這個播放器在國內(nèi)很少有人使用,如果被攻擊者使用了第三方的視頻播放軟件,很難攻擊成功,這可能也是這一漏洞不被分析重視的一大原因。
0x 01漏洞觸發(fā)
本文分析環(huán)境如下:
操作系統(tǒng)
Xp sp3
iccvid.dll版本
1.10.0.12
通過在exploit-db網(wǎng)站上得到觸發(fā)漏洞的python腳本,運行python腳本后,生成可觸發(fā)漏洞的poc.avi,這就是我們分析的樣本文件。(python腳本在文末的附件中)
通過公告可知,這個漏洞是個堆溢出漏洞,在分析堆漏洞時,肯定是hpa + ust大法好。所以,首先我們要開啟hpa、ust
使用windbg加載wmplay.exe,使用g命令,運行wmplay.exe
將poc.avi拖入wmplay中,windbg會觸發(fā)異常
通過崩潰信息猜測是堆中的內(nèi)存被破壞了,我們看下edi的值,并看下這個值是不是堆地址
可以看到堆底地址為: 76ad000+600=76b3000,這個地址也正好是edi的地址,這正是由于我們使用glags.exe開啟了頁堆檢查,堆管理器會在堆塊中增加不可訪問的柵欄頁,當(dāng)溢出覆蓋到柵欄頁時就觸發(fā)了異常。
崩潰的指令為rep movs指令,我們看下此時movs的內(nèi)存大小保存在ecx,內(nèi)存大小為:
只能知道此時,是因為向edi中拷貝800大小字節(jié)的內(nèi)容時,導(dǎo)致了堆溢出。
在rep movs這條指令的上一條指令下斷,重新運行
bu iccvid!CVDecompress+0x118:
第一次斷下后,查看edi,ecx的值:
走過rep movs指令后,此時并沒有崩潰,這就說明,并不是一次rep movs就導(dǎo)致了堆溢出,而是通過多次運行rep movs指令,逐漸到到達(dá)堆尾,然后就溢出了。。。。
第二次斷下的,
第二次調(diào)用rep movs時,還是沒有到達(dá)堆尾,還沒有溢出
第三次斷下時,
這時,可以看到,edi=76b3000, 76b3000這個就是我們在一開始崩潰的地方啊!!!
在這里,可以看下esi的值
可以看到,現(xiàn)在用來覆蓋目標(biāo)地址的數(shù)據(jù)并不直接就是我們在poc.avi中填充的數(shù)據(jù),而是一些不知來自何處去向哪里的數(shù)據(jù)。這點就造成了我們對這個漏洞的利用不能向cve 2010 0158之類的漏洞利用一樣通過修改文件內(nèi)容即可實現(xiàn)覆蓋。
0x 02 漏洞分析
定位函數(shù)
現(xiàn)在我們就定位到漏洞所在的函數(shù),然后通過ida分析漏洞所在函數(shù)的功能。
在崩潰位置通過kb進(jìn)行棧回溯來定位所在的函數(shù)
我們so easy的就把漏洞所在的函數(shù)找到了,這個函數(shù)就是iccvid!CVDecompress函數(shù)。
使用IDA查看iccvid.dll文件,找到函數(shù)73b7cbee,發(fā)現(xiàn)ida并不能識別出函數(shù)為CVDecompress函數(shù),納尼??這一定是在逗我
這是因為IDA沒有找到pdb文件,但是我們windbg卻找到了pdb文件,我們將windbg的pdb文件拷貝出來,
在windbg中查看pdb文件路徑
使用ida file --- load file ---pdb file選擇pdb文件路徑,就可以在ida中看到函數(shù)名稱了。
效果如圖
分析函數(shù)
在函數(shù)73B7CAD6頭下斷點后,重新加載程序,斷下后,可以看到CVDecompress函數(shù)有七個參數(shù):
還記得上面分析的rep movs指令嗎?調(diào)用它第三次后就會崩潰,而第一次調(diào)用這條指令時的edi的值為076af000,這個076af000是什么鬼呢?來自于哪里呢?
答案就是它是CVDecompress函數(shù)的從第一個參數(shù),偏移1c的值(076ad000)加上2000后得到的……
CVDecompress函數(shù)的第三個參數(shù)68,代表了未解壓的數(shù)據(jù)長度。
這個函數(shù)首先會對cinepak的壓縮格式結(jié)構(gòu)進(jìn)行判斷,隨后會按照cinepak壓縮格式解析結(jié)構(gòu)。
Cinepak壓縮格式的總體框架如下:
+-----------------------+
| Frame Header? ?? ?? ? |
+-----------------------+
| Strip 1 Header? ?? ???|
+-----------------------+
| Strip 1 Codebooks? ???|
+-----------------------+
| Strip 1 Frame Vectors |
+-----------------------+
| Strip 2 Header? ?? ???|
+-----------------------+
| Strip 2 Codebooks? ???|
+-----------------------+
| Strip 2 Frame Vectors |
+-----------------------+
| Strip 3 Header? ?? ???|
其中Frame Header的結(jié)構(gòu)如下:
7 6 5 4 3 2 1 0? ?? ???Field Name? ?? ?? ?? ?? ?? ???Type
+---------------+
0??|? ?? ?? ?? ? | |? ?? ? Flags? ?? ?? ?? ?? ?? ?? ?? ? Byte
+---------------+
1??|? ?? ?? ?? ?? ?|? ?? ? Length of CVID data? ?? ?? ???Unsigned
+-? ?? ?? ?? ? -+
2??|? ?? ?? ?? ?? ?|
+-? ?? ?? ?? ? -+
3??|? ?? ?? ?? ?? ?|
+---------------+
4??|? ?? ?? ?? ?? ?|? ?? ? Width of coded frame? ?? ?? ? Unsigned
+-? ?? ?? ?? ? -+
5??|? ?? ?? ?? ?? ?|
+---------------+
6??|? ?? ?? ?? ?? ?|? ?? ? Height of coded frame? ?? ?? ?Unsigned
+-? ?? ?? ?? ? -+
7??|? ?? ?? ?? ?? ?|
+---------------+
8??|? ?? ?? ?? ?? ?|? ?? ? Number of coded strips? ?? ???Unsigned
+-? ?? ?? ?? ? -+
9??|? ?? ?? ?? ?? ?|
+---------------+
函數(shù)首先判斷未解壓縮的數(shù)據(jù)長度是不是小于20H大小
再判斷未解壓縮的數(shù)據(jù)長度是不是小于FrameHeader中的數(shù)據(jù)長度
比較Frame Header中的Number of coded strips是不是小于0
然后就會對每個strip進(jìn)行遍歷,以下都是在對每個strip的處理中
對未解壓的數(shù)據(jù)大小做比較
對編碼條數(shù)據(jù)大小做判斷
判斷編碼條ID為10還是11:
對strip header中的底部Y坐標(biāo)與頂部Y坐標(biāo)做差,結(jié)果乘以一個數(shù)后存儲起來。
當(dāng)strip header中的編碼條ID為10時,會向堆中拷貝數(shù)據(jù)。
最后,會指向下一個stripHeader結(jié)構(gòu)。上面這些是對每個strip的處理
結(jié)合poc.avi的內(nèi)容,與上面IDA中的結(jié)果
每次當(dāng)解析到chunkID為20時,此時,不會向堆里覆蓋內(nèi)容,當(dāng)解析到chunkid=0x1100時,就會向堆數(shù)據(jù)中復(fù)制數(shù)據(jù)。
因為poc.avi中有三處chunkid為11的數(shù)據(jù)塊,因此向堆中復(fù)制了三次數(shù)據(jù),而正是第三交復(fù)制時,使堆溢出而崩潰。
0x 04 漏洞利用
在metasploit 平臺中暫時沒有該漏洞利用的相關(guān)模塊,在互聯(lián)網(wǎng)搜索引擎中也暫未找到相關(guān)利用樣本。本人感覺這個漏洞利用最大的難點在于,拷貝時觸發(fā)堆溢出時,拷貝的內(nèi)容很難通過文件內(nèi)容進(jìn)行控制,因而無法很好的控制EIP指針,無法精準(zhǔn)的執(zhí)行payload。怎樣精準(zhǔn)的控制esi中的內(nèi)容,是我以后將在研究學(xué)習(xí)的內(nèi)容。本文不再深入。
附件:鏈接:http://pan.baidu.com/s/1bLLx98密碼:mlbj
0x 05 參考資料
http://www.cvedetails.com/cve/CVE-2010-2553/
https://technet.microsoft.com/library/security/ms10-055
http://www.cnblogs.com/Ox9A82/p/5715673.html
http://cve.scap.org.cn/CVE-2010-2553.html
https://www.exploit-db.com/moaub-26-microsoft-cinepak-codec-cvdecompress-heap-overflow-ms10-055/
http://multimedia.cx/mirror/cinepak.txt
《漏洞戰(zhàn)爭》83頁-90頁