CVE-2012-1889 暴雷漏洞分析與利用小記

本文為看雪論壇優秀???文章
看雪論壇作者ID:JokerMss
漏洞信息
“雷暴”是CVE-2012-1889漏洞,在2012年曝光的一種微軟的XML核心組件漏洞,該漏洞源于未初始化內存的位置。遠程攻擊者可以借此漏洞執行任意代碼或者導致拒絕服務。很重要的是該漏洞的影響非常廣,存在此漏洞的系統版本很多,所以在當時危害級別特別高。剛開始接觸漏洞利用知識的我今天來記錄一下它的分析和利用過程。
環境和工具
系統環境:winXP IE6
工具:WinDbg、OllyDbg、EditPlus3
漏洞分析
3.1 Step One 成因
我們可以先觀察一下漏洞觸發的現象:

可以認定是msxml3.dll模塊內部出現了問題,那我們再看看代碼,探查一下是哪里出發了異常:

3.2 注1 clsid
這個clsid屬性是一個類標識符,因為我們這里是利用了xml對象來執行代碼,所以值是xml3的標識(UUID):

3.3 注2 definition()
這個對象的成員definition()便是該漏洞的觸發條件,如果將其視為一個方法(函數),括號中有參數那么它就會觸發漏洞:

首先觸發異常的地方在EIP=0x5DD8D772,原因是call了一個沒有數據的地址[ecx+18h],然后順著往上看,找到了ecx來源于eax,而eax來源于ebp,也就是棧空間。
如果將其視為一個屬性,那么就不會觸發漏洞,該代碼執行完成后就會無事發生:


3.4 Step Two 猜想
如果我們將棧空間替換成我們想要的地址,那么最后call的地方就會是我們想要的代碼。
漏洞利用
我們先來驗證一下上一個環節的猜想,先填充一下棧空間,讓eax也就是ebp-14h的地址上存一個我們想要的地址然后讓它訪問。
那么問題來了,怎么才能讓目的地址是我們構造的數據呢,我想到了兩種方法
- 無腦填充棧:將棧空間全部填充為我們想要的數據,重復填充就行,反正地址也就4個字節,把棧填滿就行
- 精準填充棧:通過獲取當前ebp的值,然后使用__asm將匯編代碼內聯進c代碼,然后mov就行
這里為了方便就使用了無腦填充法:
注:這里只是填充了棧,也就是讓eax獲取到了值,并不代表最后的call是正確的,后面會講到call的值怎么改,別急別急~~

我們使用WinDbg再來觀察一下堆棧和寄存器的情況:

可以看到確實棧已經被我們填充成了0C0C0C0C,然后在讀取這個地址的內容的時候觸發了異常,為啥呢?因為這個地址并沒有訪問權限。
好的,第一步已經邁出去了,接下來就是要讓0C0C0C0C這個地址有數據,要能正常訪問到且不觸發異常。如何能在這個地址構造填充數據呢?這里就要用到堆噴射(Heap Spray)技術了。
簡單來說就是將堆空間覆蓋成我們想要的內容,從而達到執行shellcode的目的。接下來我用該漏洞的邏輯圖來說明一下堆噴的原理和能利用的方向。

首先我們訪問棧,訪問0C0C0C0C這個地址,然后經過我們的代碼可以讓它去堆空間找,IE進程有很多模塊,但是不影響,通過js的字符串拼接我們可以申請很多堆空間占據js執行模塊的堆空間,然后為了確保shellcode能夠執行,我們在每一個堆空間填充的數據塊都經過了一定的調整,前面放一堆滑板指令,比如9090=>nop或者0C0C=>OR AL,0C,他們會執行但是不影響任何環境,然后就會順利執行到我們的shellcode完成目的。
上面是一段shellcode,也就是彈個MessageBox而已,目的是驗證漏洞能否就此被利用。



最后也是最重要的一步來了,成功call到我們精心構造的數據塊中:


直接運行,成功彈窗!

知道了利用方法后能不能加點功能進去呢?比如說bindshell?說干就干。首先還是先編譯一份能在XP系統上跑起來的程序。
起始也就是一個bindshell的小demo,然后把它的opcode扒下來,轉換成js能識別的unicode編碼,再構造出自己的字符串也就是前面說的數據塊就行了。
上圖!

以上,就完成了CVE-2012-1889漏洞的分析和利用。