阿里基礎安全威脅情報中心
今年4月份微軟修補了一個名為CVE-2015-1641的word類型混淆漏洞,攻擊者可以構造嵌入了docx的rtf文檔進行攻擊。word在解析docx文檔處理displacedByCustomXML屬性時未對customXML對象進行驗證,可以傳入其他標簽對象進行處理,造成類型混淆,導致任意內存寫入,最終經過精心構造的標簽以及對應的屬性值可以造成遠程任意代碼執行。
根據微軟官方MS15-33安全公告里顯示,這個漏洞覆蓋Office 2007 SP3,Office 2010 SP2(32位和64位),Office 2013 SP1(32位和64位),Office 2013RT SP1,Word for Mac 2011以及Office在SharePoint服務器上的Office 2010/2013和Office Web 2010/2013應用,除此之外,經過驗證Office 2010 SP1也受該漏洞的影響,但是微軟針對該漏洞在2010上的補丁KB2553428并未推出SP1版本,因此SP1版本的Office 2010到目前即使更新所有補丁仍然存在該漏洞。
CVE-2015-1641這個漏洞的觸發非常穩定,幾乎影響微軟目前所支持的所有office版本(最新推出的Office 2016除外),影響范圍十分廣泛。目前無論是在VirusTotal還是在野外抓到的樣本,利用這個漏洞的攻擊樣本已經開始逐漸增加。根據以上原因可以推斷,在今后很長的一段時間內都會存在該漏洞的攻擊,并且有替代CVE-2012-0158的趨勢。
使用阿里諦聽引擎掃描RTF文檔,解析出其中的一個word文檔的document.xml中有如下代碼,包含了4個smartTag標簽,每個smartTag中又有permStart標簽,而在permStart標簽中的則是帶有displacedByCustomXml屬性的moveFromRangeStart和moveFromRangeEnd標簽:
首先來說明一下幾個標簽及屬性的作用。smartTag標簽是用于word和excel中的智能標簽,針對人名、日期、時間、地址、電話號碼等進行智能識別并允許用戶執行特定操作的標簽。比如如果Steve Jobs被識別為人名,則smartTag標簽可以執行諸如打開通訊錄、添加到聯系人、預約會議等操作,給office用戶提供更多自定義的智能選擇。displacedByCustomXml在很多標簽中都可以使用,目的是當前標簽處需要被一個customXML中的內容代替,它的值是next表示被下一個customXML代替,prev則表示被上一個代替。
這個漏洞是一個類型混淆漏洞,本來帶有displacedByCustomXml的標簽會被上一個或下一個customXML代替,但是word沒有對傳入的customXML對象進行嚴格的校驗,導致可以傳入諸如smartTag對象,然而smartTag對象的處理流程和customXML并不相同,上述特殊處理的smartTag標簽中的element屬性值會被當作是一個地址,隨后經過簡單的計算得到另一個地址。最后處理流程會將moveFromRangeEnd的id值覆蓋到之前計算出來的地址中,導致任意內存寫入,漏洞代碼如下:
通過下面的補丁對比可以很容易看到打上最新補丁的word代碼增加了對customXML對象處理函數的校驗:
利用的分析環境為win7 64位+office2010 sp2 32位。
雖然這上面有4個smartTag標簽,但就目前分析來看,前兩個標簽是漏洞利用的關鍵。首在解析第一個smartTag標簽時會把其moveFromRangeEnd子標簽的id進行解析,然后寫到0x7c38bd74這個地址中去,這個地址是根據smartTag的element即0x7c38bd50計算出來的:
然后解析第二個smartTag標簽,esi指向的內存就是smartTag的結構體,esi+4的內容是element屬性值:
而eax的值為0x7C376FC3,剛好就是moveFromRangeEnd對象id "2084007875"的十六進制值:
然后覆蓋MSVCR71.dll中0x7c38a428,這是一個虛函數的指針,而0x7c38a428這個地址是通過當前smartTag的element屬性值即0x7c38bd68和第一個smartTag標簽中moveFromRangeStart的id共同計算出來的:
調試可以看到如下內存,ecx的內存如下,ecx+0xc就是上面解析第一個smartTag標簽時寫入的值,最終計算得到的被覆蓋的地址便是0x7c38a428:
而在覆蓋之前0x7c38a428處的指針指向kernel32! FlsGetValue:
最后調用memcpy函數進行覆蓋:
覆蓋之后的0x7c38a428指向的便是攻擊者想要執行的代碼位置:
總結一下利用流程如下:首先smartTag_1(第一個smartTag標簽)的element屬性值進行簡單計算得到一個地址addr1,然后將其moveFromRangeEnd_1子標簽的id寫入到addr1中備用;然后解析smartTag_2,根據他的element屬性值和前面計算出來的addr1共同計算出另一個地址addr2,并將其子標簽moveFromRangeEnd_2的id寫入到addr2,而addr2是一個虛函數表中的地址,這樣原本是這個虛函數的地址就被覆蓋成攻擊者想要執行的任意代碼的地址,漏洞利用成功。
word在office2010的環境下沒有打補丁的情況下執行的堆噴射后的地址為0x0900080C,如下:
看到這段內存想必都已經清楚了,這里就是RTF文檔釋放的activeX.bin文件的內容,而0x7c342404處的代碼是ret,因此這里會一直執行ret直到到達最終ROP的位置,ROP鏈如下:
毫無疑問ROP的作用還是調用VirtualProtect函數對當前這塊內存添加可執行權限:
獲得執行權限之后開始執行shellcode:
想要檢測這個漏洞的攻擊樣本必須要先從rtf文檔提取出docx然后獲取到document.xml,yara規則如下:
rule CVE_2015_1641
{
meta:
description="Word Type Confusion Vulnerability"
output="Nday & CVE-2015-1641"
strings:
$smart_tag=/<w:smartTag[\w\W]+?w:element=\"(&#x[a-zA-Z0-9]{4};){2}\">[\w\W]+?<w:permStart[\w\W]+?w:displacedByCustomXml=\"prev\"\/>[\w\W]+?<w:permEnd[\w\W]+?<\/w:smartTag>/
condition:
$smart_tag
}
上面的規則匹配其實就是一個正則匹配,從左到右流程如下:1.匹配到smartTag標簽,查看其element屬性是否為十六進制數值作為地址;2.在smartTag標簽中匹配到permStart標簽,在它的屬性或子標簽的屬性中存在displacedByCustomXml="prev"。滿足上述兩個條件則認為就是這個漏洞的攻擊樣本。依據上面的yara規則檢測該攻擊樣本的document.xml結果如下:
關于阿里基礎安全威脅情報中心
阿里基礎安全威脅情報中心是2015年6月新成立的部門,以沉淀阿里的安全數據、安全能力和建設阿里安全的威脅情報體系為使命,歡迎志同道合的小伙伴們加盟。