作者:xd0ol1@知道創宇404實驗室
0 引子
在上一篇文章中,我們分析了 Office 文檔型漏洞 CVE-2015-1641 的利用,本文將繼續對此類漏洞中的另一常見案例 CVE-2015-2545(MS15-099)展開分析。相較而言,這些 Exp 的威脅性更大,例如可采用“Word EPS + Windows EoP”的組合,且很多地方借鑒了瀏覽器漏洞的利用思路,因此還是很值得我們學習研究的。
1 樣本信息
分析中用到的樣本信息如下:
SHA256:3a65d4b3bc18352675cd02154ffb388035463089d59aad36cadb1646f3a3b0fc
Size:420,577 bytes
Type:Office Open XML Document
我們將此文件的后綴名改為 zip,解壓后可得到如下目錄結構:
其中,image1.eps 是精心設計的漏洞利用文件,即由 PostScript 語言編寫的特殊圖形文件,這里 Word 和 PostScript 的關系一定層度上可類比為 IE 瀏覽器和 JavaScript 的關系,更多關于 PostScript 語言的說明可參考該手冊。
此外,本文的分析環境為 Win7 x86+Office 2007 SP3,EPSIMP32 模塊的版本信息如下:
2 漏洞原理分析
首先我們看下原理,簡單來說就是 Word 程序在解析 EPS(Encapsulated PostScript)圖形文件時存在一個 UAF(Use-After-Free)的漏洞,其錯誤代碼位于 EPSIMP32 模塊。為了便于理解,我們給出樣本中觸發此漏洞的那部分 PostScript 代碼,當然有經過一定的反混淆處理:
其中操作符 copy 和 forall 的定義如下:
結合上述代碼,我們給出漏洞原理更為具體的描述:當通過 forall 操作 dict2 對象時,將對 dict2 中的 ‘key-value’ 進行迭代處理,且 pNext 指針指向下一對待處理的 ‘key-value’。然而,proc 中存在 dict1 dict2 copy 的操作,此過程會先釋放掉 dict2 原有的 ‘key-value’ 空間,之后再申請新空間進行接下來的拷貝,即原先 pNext 指向的 ‘key-value’ 空間被釋放了。而后在 putinterval 操作中將重新用到原先 pNext 指向的空間,并向其中寫入特定的字符串。因此,在下一次迭代時,pNext 指向的數據就變成了我們所構造的 ‘key-value’。
接著我們來完整分析下此過程,這里給出 PostScript 對象和 dict 下 ‘key-value’ 對象的定義,它們在后面會涉及到:
//PostScript對象的定義
struct PostScript_object {
dword type;
dword attr;
dword value1;
dword value2;
} ps_obj;
//字典‘key-value’對象的定義
struct Dictionary_key_value {
dword *pNext;
dword dwIndex;
ps_obj key;
ps_obj value;
} dict_kv;
就每個 PostScript 操作符而言,都有一個具體的處理函數與之對應,我們可以很方便的由 IDA 進行查看,之后通過相對偏移的計算就可以在 OllyDBG 中定位到關鍵點了:
借助如下斷點我們將在進程加載 EPSIMP32 模塊時斷下來:
bp LoadLibraryW, UNICODE [dword ptr [esp + 0x04] + 0x6e] == “EPSIMP32.FLT”
很自然的我們會想到在 forall 的對應函數上下斷,可以得到與 dict 操作迭代處理相關的代碼段如下,其中 EPSIMP32 的模塊基址為 0x73790000:
此過程包含4個 call 調用,其中第一個 call 用于獲取當前要處理的 ‘key-value’ 和指針 pNext,即指向下次處理的 ‘key-value’,而第二個和第三個 call 分別用于將 key 和 value 存儲到操作棧上,最后的第四個 call 則用于處理 proc 中的操作。
我們來跟一下,在第一個 call 調用時,ecx 寄存器指向的內容為 dict2 內部 hash-table的 指針、hash-table 的大小以及包含的 ‘key-value’ 個數:
此調用執行完成后,我們會得到 keyZ1 和指向 keyZ2 的指針:
而當第二個和第三個 call 調用完成后,我們可以看到 keyZ1 的 key 和 value 被存儲到了操作棧上:
在第四個 call 調用中,對于 proc 的各操作符,首先會獲取對應處理函數的地址,而后以虛函數的方式進行調用,相關代碼片段如下:
這里我們主要關注 copy 操作,由分析可知,在其處理過程中會將 dict2 內部 hash-table 上對應的所有 ‘key-value’ 空間都釋放掉,即上述 pNext 指向的 keyZ2 空間被釋放掉了,如下給出的是進行該 delete 操作的函數入口:
同樣,此時入參 ecx 寄存器指向的內容中包含了 dict2 的 hash-table 指針,接下去的操作將逐次釋放 keyZ1~keyZ8 的空間,最后 hash-table 也會被釋放掉:
而釋放的 keyZ2 空間,即 pNext 指向的空間,將在隨后的 putinterval 操作中被重新寫入特定的偽造數據:
因此,在 forall 的下一次迭代過程中,根據 pNext 指針獲取的 ‘key-value’ 就變成了我們所偽造的數據,并且之后同樣被存儲到了操作棧上:
3 漏洞利用分析
這里我們接著上一節的內容來繼續跟下漏洞的利用,此時偽造的 ‘key-value’ 已經被存儲到了操作棧上,下述給出的是本次迭代中 forall 操作所處理的 proc 代碼:
也就是將操作棧上的 key 和 value 分別賦給 xx_19169 以及 xx_26500,操作完成后得到的
xx_19169 如下:
可以看到,xx_19169 的 type 字段為 0x00000003,即表示的是整型,所以對于本文的分析環境來說,接下去的處理過程將會按照 “old version” 的分支來進行:
而 xx_26500 則是實現漏洞利用的關鍵,由圖18可知它的 type 字段為 0x00000500,表明這是一個string類型,且 value2 字段為泄露出來的指針,在此基礎上經過一系列構造后,可得到 string 對象如下:
在 PostScript 中會為每個 string 對象分配專門的 buffer 用于存儲實際的字符串內容,其基址及大小就保存在該 string 對象中。就最終樣本偽造的 string 對象來說,其 buffer 基址為 0x00000000,且大小為 0x7fffffff,因此借助此對象可以實現任意內存的讀寫。之后代碼會通過獲取的 RW primitives 來查找 ROP gadgets,從而創建 ROP 鏈,同時由 putinterval 操作將 shellcode 和 payload 寫入內存:
之后再通過修改操作符 bytesavailable 處理函數中的如下 call 指針跳轉到 ROP 鏈上:
其中,ROP 鏈包含的指令如下,可以看到首先進行的是 stack pivot 操作,接著會將 shellcode 所在的頁屬性置為可執行,最后跳轉到 shellcode 的入口:
這里借助了一個小技巧來繞過保護程序對 ZwProtectVirtualMemory 調用的檢測,對于 ntdll 模塊中的 Nt/Zw 函數,除了賦給 eax 寄存器的 id 不同外,其余部分都是相同的。ROP 鏈在完成 eax 的賦值后,也就是將 ZwProtectVirtualMemory 函數中的 id 賦給 eax 后,會直接跳過 ZwCreateEvent 函數(該函數未被 hook)的前5字節并執行余下的那部分指令,通過這種方式能實現任意的系統調用而不會被檢測到:
下面我們再來簡單看下 shellcode,和大多數情況一樣,它的主要作用就是獲取相關的 API 函數,然后創建并執行 payload 文件。樣本中 shellcode 的部分數據經過了加密處理,因此會有一個解密的操作:
而后,代碼通過查找 LDR 鏈的方式來獲取 msvcrt 模塊的基址:
之后從 msvcrt 模塊的導入表中得到函數 GetModuleHandleA 和 GetProcAddress 的入口地址,由 GetModuleHandleA 函數可以獲取到 kernel32 模塊的句柄,最后再借助 GetProcAddress 調用來逐個獲取下述的導出函數地址:
緊接著 payload 的內容,即圖19所示代碼中介于首尾字符串 “5555555566666666” 之間的那部分數據,會被寫入到臨時目錄下的 plugin.dll 文件中,分析可知這是一個惡意的程序:
通過 LoadLibraryA 函數加載該 plugin.dll 模塊后,將會在臨時目錄下另外再釋放一個名為 igfxe.exe 的程序,其作用是獲取遠程文件并執行之:
4 結語
本文基于樣本文檔分析了 CVE-2015-2545 的利用,然鑒于筆者就 PostScript 語言所知尚少,固有些點也是沒能給講透徹,希望能有更多這類漏洞的分析文章出現。另外,錯誤之處還望各位加以斧正,歡迎一起交流:P
5 參考
[1] The EPS Awakens
[2] Microsoft Office Encapsulated PostScript and Windows Privilege Escalation Zero-Days
[3] 警惕利用Microsoft Office EPS漏洞進行的攻擊
[4] 針對CVE-2015-2545漏洞研究分析
[5] 文檔型漏洞攻擊研究報告
[6] PostScript Language Reference Manual
[7] How the EPS File Exploit Works to Bypass EMET (CVE-2015-2545)
[8] CVE-2015-2545 ITW EMET Evasion
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/368/
暫無評論