本文講的是<b>CVE-2013-2551樣本分析及漏洞利用和防禦</b>,
0x0 寫在前面
VUPEN團隊在Pwn2Own 2013黑客大賽上使用漏洞攻破Windows 8環境下的IE10,随後在其部落格上公開了技術細節。根據VUPEN描述,該漏洞産生于VGX.DLL子產品,在VML語言中處理圖形标簽的stroke子元素的dashstyle存在安全隐患
微軟在安全公告MS13-037中詳細列舉了受影響軟體範圍從IE6-IE10,并給出相應平台的安全更新
本文調試的Poc由4B5F5F4B根據VUPEN在部落格中公開的資訊構造
調試思路是對IE開啟頁堆,利用調試器支援,實時檢測到溢出之後,根據函數調用關系往上一層一層跟蹤資料來源和閱讀反彙編代碼,尋找漏洞觸發的關鍵點
0x1 調試環境 & 樣本資訊
1.1 調試環境
[作業系統]:Windows 7 Ultimate SP1(X64)、 Windows 7 Ultimate SP1(X86)
[浏覽器]:Internet Explorer 8.0.7601.17514
[調試器]:Windbg 6.11.0001.402 X86
[反彙編器]:IDA Pro 6.8.150423(32-bit)
1.2 樣本資訊
[樣本名]:poc.html
[MD5]:0B8CBEE6465D1D22B79866DE997C509A
[SHA1]:161621EF49A453692537DBC33D10DDC73EB5133D
[CRC32]:FAE274A5
0x2 樣本調試
2.1 對IE浏覽器開啟頁堆
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SN4gTOxETMzgDNxQjM5QTMvw1NxQDM3EDMy8CXzRWYvxGc19CXt92YuU3boRjL3d3dvw1LcpDc0RHaiojIsJye.png)
2.2 運作樣本
使用Windbg附加IE,然後運作樣本,允許加載ActiveX控件,并點選頁面中的crash按鈕
2.3 檢視崩潰時資訊
崩潰語句資訊
棧的調用關系
檢視vgx子產品的詳細資訊
2.4 使用IDA檢視崩潰點附近代碼
msvcrt!memcpy函數經過千錘百煉幾乎不用去懷疑,直接檢視上層調用
計算偏移:0x72a3cfa4 – 0x72a10000 = 0x2CFA4
該版本vgx.dll子產品在IDA中的基址為:0x198C0000
經過計算,memcpy函數在位址0x198ECFA4處被調用
經過分析,src為結構體第4項資料 + (結構體第2項資料 && 0xFFFF)* arg_8
2.5 繼續檢視上層函數
在Windbg中檢視(vgx!COALineDashStyleArray::get_item+0x89)
計算該語句在IDA中的位址
使用IDA檢視該函數
使用Windbg跟蹤vgx!COALineDashStyleArray::get_item的執行流程
重新運作樣本
經過調試,在vgx!COALineDashStyleArray::get_item+0x70處調用vgx!ORG::CElements函數
單步步入vgx!ORG::CElements函數
根據movzx指令判斷,該數值為無符号數
函數傳回後,對使用0擴充之後的無符号數進行了有符号的條件判斷
之前的unsigned short int 0擴充之後被強轉為 int,且樣本傳入的數值為0xFFFF,造成整數溢出
0x3 漏洞利用
本文漏洞利用針對沒打任何更新檔的Windows 7 Ultimate SP1(X86) 環境,結合源碼和調試分析利用過程
本文中漏洞利用代碼主要參考調試的Poc樣本代碼、以及網上的公開代碼整理編寫
漏洞利用成功截圖
Poc源碼中溢出的關鍵語句:
3.1 過ASLR
過ASLR的源碼大緻如下:
在指派之後,加入彈框把流程中斷下來
使用Windbg附加運作,彈出視窗後在Windbg上點選暫停,然後搜尋數值0x7ffe0300
搜尋的記錄太多無法驗證,那麼我們再搜尋字元串"Khwarezm111"
接着搜尋數值0x0044df04
結合以上三個搜尋結果,可以猜測位址0x04be5c78就是我們尋找的儲存數值0x7ffe0300的地方
在記憶體視窗驗證猜測
往前翻,其記憶體布局如下
檢視圈紅處的資料
可以看見,上訴代碼在一片對象中間利用dashstyle屬性插入了和一個對象相同大小的數組,利用溢出,定位到數組後一個對象儲存字元串首位址的地方,通過越界寫入任意值,然後利用對象的屬性定位到該任意值
本文利用固定偏移洩露NTDLL.DLL的基址
3.2 精确噴射
精确堆噴到位址0x0c0c0c0c,源碼大緻如下:
3.3 過DEP
使用ROP鍊過DEP,源碼大緻如下:
3.4 劫持EIP
劫持EIP的源碼大緻如下:
由于0x0c0c0c0c在記憶體中存在太多,不友善搜尋,将其修改為一個比較特殊的值0x0eeeee0e,然後加入彈框
使用windbg附加運作,在彈框後暫停,然後搜尋數值0x0eeeee0e
根據對其,可以排除第一個搜尋結果,由于搜尋到的結果不多,可以根據其分布在數組{1,2,3,4}之後尋找
經過在記憶體中往上尋找數組,位址0x12b60280符合條件
檢視附近記憶體布局
我們看到,一個COAShape對象緊接着一個COAReturnedPointsForAnchor對象,它們占用的記憶體空間都是一樣的。根據源碼,我們可以知道,通過布置跟對象大小相同的數組,利用溢出,定位到後一個對象(此處是COAShape對象)的虛表
檢視COAShape虛表的内容
此時我們知道虛表指針被改寫了
對0x0eeeee0e下執行斷點,中斷時檢視函數的調用關系
檢視上層調用
位址0x6a23f20f是在調用虛表第二項,正常情況是Release函數,溢出後,劫持了EIP
構造的利用樣本将在此處執行換棧操作
3.5 不使用0x7ffe0300洩露NTDLL.DLL基址過ASLR
使用固定偏移洩露NTDLL.DLL的基址在打過更新檔的Windows 7系統上已經不能使用了,實際利用中局限性比較大。我們可以考慮洩露其他子產品的基址,或者換種思路洩露NTDLL.DLL基址
對于已有的利用代碼來講換種方式洩露NTDLL.DLL基址對代碼的改動量比較小
檢視漏洞子產品自身的導入表資訊
好吧,沒有導入NTDLL.DLL的函數。那麼我也比較懶,洩露VGX.DLL子產品的基址,通過導入表找到KERNEL32.DLL,針對其中某個函數到NTDLL.DLL基址的固定偏移洩露NTDLL.DLL基址。簡單可行,源碼改動小。當然,缺點是VGX.DLL子產品版本限定太死
源碼大緻如下:
0x4 漏洞檢測
通過本文第二部分分析,已經知道在vgx!ORG::CElements函數内造成溢出
源碼中的關鍵溢出語句:
從資料關系的角度來看,銀行櫃台辦理存款業務時,櫃員收到現金的時候,應該先驗鈔還是先辦理存款登記再驗證鈔票真僞?答案顯然是前者。那麼我們的檢測點也應該提前到資料輸入的地方。
4.1 根據微軟安全公告下載下傳更新檔
根據微軟的安全公告MS13-037下載下傳到更新檔KB2829530,更新檔前後的VGX.DLL檔案版本分别為
[更新檔前]:8.0.7601.18106
[更新檔後]:8.0.7601.18126
4.2 使用Bindiff對比檔案
使用Bindiff對比vgx.dll之後,根據符号名稱猜測是在COALineDashStyleArray::put_length函數進行的修補
進行對比
通過Windbg調試驗證
走到判斷數值是否小于0
G一下,利用樣本正常運作,沒有觸發漏洞
我們可以鈎取COALineDashStyleArray::put_length函數前五位元組,插入判斷代碼,判斷參數的值是否小于0,如果小于0提示使用者觸發CVE-2013-2551,否則還原流程
檢測代碼編寫略
檢測效果截圖
0x5 總結
該漏洞屬于整數溢出漏洞。其漏洞原因在于VGX.DLL子產品中處理dashstyle.array.length屬性時未對輸入參數進行有效檢查。利用溢出造成任意位址讀寫,改寫虛表指針劫持EIP獲得任意代碼執行的能力
根據參考代碼,筆者通過洩露NTDLL.DLL子產品基址的方式繞過ASLR,當然,此次繞過的方式并不具有通用性,漏洞利用技巧也是筆者需要更多學習、思考以及參考野外樣本利用方式待以提升的地方
最後編碼對該漏洞利用樣本進行動态檢測,從資料關系的角度來看,一定是在擷取外部資料的位置部署檢測代碼。筆者對關鍵函數進行API HOOK,一旦外部資料不合法立即提示給使用者
原文釋出時間為:2017年4月17日
本文作者:興華永恒
本文來自雲栖社群合作夥伴嘶吼,了解相關資訊可以關注嘶吼網站。
<a href="http://www.4hou.com/technology/4241.html" target="_blank">原文連結</a>