\x01 前言
CVE-2017-11826
據說是 360 在 2017 年 9 月底發現的一個關於 XML 格式解析的一個漏洞,之後微軟在10
月份發佈了關於CVE-2017-11826
的補丁,補丁地址:https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2017-11826
- 該漏洞的成因是由於在解析閉合元素時,沒有對元素的完整性做出判斷,導致將當前元素的嵌套關係加上
1
。這樣的話wwlib
模塊在處理閉合標籤時,會錯誤的使用父級元素w:name
屬性+44
的地址進行虛函數調用,攻擊者通過修改w:name
屬性,就可以進行任意地址調用。 - 受影響的
Office
版本。
\x02 調試環境
- 操作系統:Windows 7 + VMware
- 調試工具:x64dbg
- 漏洞樣本:POC(提取碼:lxx6)
\x03 調試分析
- 從
GitHub
上下載關於CVE-2017-11826
漏洞的文件夾,解壓後發現包括解壓過的docx
文件、README
文件、俄文文檔,俄文文檔沒有仔細看,好像是關於漏洞利用的。
- 包含漏洞的
XML
文件爲document.xml
,文件在word
路徑下。打開document.xml
文件,分析後發現<w:font>
標籤使用了</o:idmap>
標籤進行閉合,而<w:font>
標籤的w:name
屬性有點奇怪,可能是用於控制某一個地址的值。
- 將解壓過的
docx
文檔重新壓縮,之後使用註冊表附加調試器準備調試。
- 附加完成之後打開含有漏洞的文檔,運行後觸發異常,其中
call [ecx+4]
指令是利用虛函數表調用虛函數,而ecx
爲虛函數表指針,通過wwlib.41249DA0
函數返回。
- 查看堆棧調用,發現用於處理
XML
格式的msxml
模塊,msxml
模塊通過間接調用wwlib
模塊去協助解析XML
格式。暫且將wwlib.3161309E
函數定爲漏洞函數。
- 對漏洞函數下記錄斷點後查看日誌內容,發現漏洞函數被調用了
6
次,結合document.xml
文件中的標籤元素分析漏洞函數很有可能是用於解析元素標籤的,至於解析的是什麼,目前還不清楚。
- 選取最後一次調用漏洞函數的
esp
下條件斷點,分析漏洞函數處理流程。
- 函數斷下後從傳入的參數可以發現,
esi
可能是儲存標籤信息的數據結構。
- 單步進入該函數,在如圖所示的位置會取出元素的嵌套關係,此時
<o:idmap>
標籤已經插到了w:font
標籤的後面(以":"
符號爲分隔符)。而<w:font>
標籤在未閉合的情況插入了<o:idmap>
標籤,說明嵌套關係已經被錯誤的解析。
- 調試到
0x31613084
地址時發現會調用wwlib.31249DA0
函數,經過分析後發現該函數的返回值和異常處的虛函數表調用有關,所以進入這個函數看看。
- 通過分析發現該函數對
ecx
和edx
做了一些簡單的計算,算法爲[[ecx]+8]*edx + [[ecx]+C] + [ecx]
,計算結果爲0x0751D140
;而ecx
是由esi
傳入,edx
又等於[[esi]]
,所以算法變爲[[esi]+8]*([[esi]]-2) + [[esi]+C] + [esi]
,由傳入的esi
控制,經過後面的分析可以得出[[esi]]
其實就是當前元素的嵌套等級。
- 調用完
wwlib.31249DA0
後會將[[0x0751D140+44]+44]
地址的值作爲虛函數表指針進行虛函數調用,進而觸發異常。如圖所示可以看出[0x0751D140+44]
地址被覆蓋成了<w:font>
元素的w:name
屬性,所以攻擊者通過修改<w:font>
標籤的w:name
屬性就可以做到調用任意地址。
- 接下來更改樣本中的
document.xml
文件,手動添加</w:font>
閉合標籤,看看是否會觸發異常。
- 在漏洞函數處斷下,這時的嵌套等級爲 5。
- 之後通過
wwlib.31249DA0
計算虛函數調用地址爲0x075098F4
。由於嵌套等級爲5
,所以計算出的結果爲F4
(4C*(5 - 2) + 10
),之前的爲140
(4C*(6 - 2) + 10
)。
- 虛函數調用後程序並沒有觸發異常。
\x04 分析 msxml 模塊處理步驟
- 爲了快速瞭解
msxml
模塊的處理流程,對調用堆棧中的所有msxml
模塊函數下記錄斷點,查看日誌。
- 從日誌中可以發現漏洞函數的調用都是通過
sub_78887830
函數中的call [ebx+200]
的指令實現的,但是倒數第二個漏洞函數的調用卻沒有經過call [ebx+200]
而是直接跳到了MSO
模塊。
- 對倒數第二個漏洞函數下斷點。斷下後分析堆棧調用,發現
msxml.78887830
函數中的call [ecx+20]
的指令也會調用漏洞函數。
- 這樣的話函數調用流程圖就能分析出來了,函數調用流程如下圖所示:
- 下面根據
msxml.78887830
函數的最後一次調用,簡單分析call [ebx+200]
下的函數鏈調用。
- 在
msxml.78887830
函數開頭會將元素標籤對象儲存在ebx
中,元素標籤對象儲存當前解析元素的信息,主要是元素的嵌套關係,嵌套等級等。
- 向下調試後發現
msxml.788872F7
函數會獲取<w:font>
元素的w:name
屬性字符的指針。
- 而下面的
msxml.78887335
函數會獲取o:idmap
元素字符的指針
- 獲取完
o:idmap
元素字符的指針後,調用msxml.788872F7
函數解析o:idmap
元素,在內存窗口可以看出字符指針已經指向了incer
的位置,說明已經把idmap
標籤解析出來了。
- 之後調用
msxml.788873F0
計算元素的嵌套等級,可以看出元素的嵌套等級計算出爲6
,但此時元素的嵌套等級依舊是5
,還沒有更新爲6
。
- 在將
[ebx+1e8]
賦值給eax
之後,發生了跳轉,從而跳過了call [ecx+20]
的調用轉而進行call [ebx+200]
的調用。
- 調用的函數爲
mso.32751CAA
,其實MSO
模塊的函數調用沒有太大的作用,只是給後面wwlib
模塊的做間接處理。
- 到達
0x32751D5C
的位置後執行call [ecx+20]
指令調用sub_3277FAC0
函數,此時esi = [esi+60]
。
- 接着
sub_3277FAC0
函數中會執行call [eax+10]
指令調用wwlib.3127D3FB
。
- 進入
wwlib.3127D3FB
函數之後繼續向下調試,此時[[esi+b14]]
的地址中儲存着元素的嵌套關係。
- 之後調用完
wwlib.3127E6B3
函數後會進行一個判斷,如果ebx
等於0x80004001
就跳轉。
- 跳轉完成之後調用漏洞函數,下面的流程剛剛已經分析過了。
- 根據上面調試分析的結果對其中幾個位置下記錄斷點。查看日誌可以發現
msxml.78887830
函數會逐一對元素進行解析,當解析到<idmap>
標籤時嵌套關係爲5
。
- 但是在異常處嵌套關係爲
6
,對最後一次調用msxml.78887830
函數下斷點,查看嵌套關係是何時變爲6
的。
- 重新運行後斷下,此時嵌套關係爲
5
。
- 當調試到
wwlib.3127D3FB
函數中的0x3128E3AD
位置時,嵌套關係變爲了6
,說明wwlib.312C6142
函數更新了嵌套關係。
- 接着分析一下
w:name
屬性是何時被複制的。通過對漏洞異常處的分析發現w:name
屬性儲存在元素對象中,通過對元素對象儲存w:name
位置下寫入斷點發現在WWLIB.sub_3127D3FB
函數中會調用wwlib.3127E773
函數複製w:name
到元素對象當中,之後漏洞函數中會把w:name
屬性取出來進行虛函數表調用。
- 需要注意的是再上面的分析中該跳轉並沒有實現,也就是說這裏在複製完
w:name
屬性之後直接返回了。而判斷跳轉的值是由wwlib.3127E6B3
返回的,進入該函數,分析後發現在函數末尾處會將0x80004001
賦值給eax
,在這之前會以0x3149BFA3
作爲基址,以eax * 4
做爲偏移地址進行調用,而eax
是通過[ebp-1c]
傳進來的,對該位置下記錄斷點後查看日誌。
- 根據日誌可以發現當
[ebp+1c]
的值爲0xFFFF
時纔會調用漏洞函數。而且解析<w:font>
標籤前調用一次,解析<o:idmap>
標籤後調用一次。
- 之後把
<o:idmap>
標籤刪除,再對比日誌信息。
- 可以發現只有在
<w:font>
標籤解析前纔會將此值設置爲0xFFFF
,所以這一個值可能是用於判斷元素是否閉合。
\x05 總結
- 當
msxml.78887830
函數解析到<w:font>
標籤時,會誤以爲標籤已經閉合,從而將<w:font>
標籤的w:name
屬性(假如有的話)添加到對象之中,同時更新元素的嵌套關係(嵌套關係變爲6
),導致最後使用call [ecx+4]
進行虛函數表調用時虛表指針被錯誤的覆蓋成了w:name
屬性中的數據觸發了異常。
關於 CVE-2017-11826 的漏洞分析到此結束,如有錯誤,歡迎指正