office CVE-2015-1641雜談
之前看CVE-2017-11826的時候發現該漏洞和早年的CVE-2015-1641不僅在漏洞類型上相似,甚至部分漏洞代碼也一致,遂將之前的分析有回顧了一下,留個記錄。
具體觸發漏洞的字段如下所示,為<w:p>標簽下的四個smartTag,該標簽用於word和excel中的智能標簽,針對任命,日期,時間,地址,等進行智能識別並允許用戶執行特征操作的標簽,其中displacedByCustomxml字段在多個標簽中被使用,其目的在於標記當前標簽被一個cumtomxml標簽替代,替代的方式基於displacedByCustomxml字段的參數,prev表示上一個,next表示下一個,該漏洞的本質在於wwlib中相關的標簽解析函數在處理customxml標簽是沒有進行校驗,導致customxml可被混淆為smartTag標簽,從而導致代碼執行。
由於手中的是標準的利用樣本,無法觸發函數的崩潰,因此需要對該樣本進行改造,這裏的思路在於將除了漏洞觸發以外的ole objdata代碼刪除,從而導致利用代碼執行出錯崩潰(一般樣本有三或四個ole對象,區別在於是否具備繞過alsr的ole,找到對應的漏洞出發ole對象,其他的全部刪除即可)。
此時再運行調試器斷下。
Heapspra內存如下所示:
09c9080c即為對應的漏洞利用後跳轉的shellcode地址。
Poc斷下的地址處對應的代碼如下所示,由於trigger處,ecx中指向的地址為非法地址導致調試器崩潰斷下,此處知道對應的漏洞觸發函數,即可設置斷點,並運行正常的樣本。
斷點如下:bp wwlib+0x00009d30,如下圖所示此時紅框中函數的參數如下所示
Eax:7c38bd50(SmartTag element 值)
Esi:標簽層級
Src:smartTag下的w:id值
如下圖所示
進入fun_cpy1_Vul_17_11826_Vul_1641,之後執行函數fun_CalcspectalTagobject(詳見11826分析),該函數通過這兩個參數(兩個參數分別為taglist base address及index,由此可知此處的element被作為taglist base address來計算對應的標簽對象地址)會返回一個具體的標簽對象地址,之後通過函數fun_cpy_Vul_17_11826_Memcpy_1641將參數src中的內容拷貝到該地址中(可以看到起邏輯和11826中十分相似)。
如下圖所示進入對應的fun_CalcspectalTagobject函數前。
具體的計算代碼如下所示(對象地址+對象頭長度+對象長度*index),如下所示
taglist base + head len + index * objectsize
0x7c38bd50 + 0x18 + 3 * 4 = 0x7c38bd74。
如下所示生成地址0x7c38bd74
進入拷貝函數。
拷貝前
拷貝後,寫入的值為ffffe696。
之後處理第二個tag,同樣的公式,此時
taglist base + head len + index * objectsize
0x7c38bd68 + ffffe696 +6*7 = 0x7c38a428,此時可以看到head len的值即為上次寫入的ffffe696,用於輔助第二個標簽生成對應的地址(此時第一次寫入的位置為第二次tag對象的headlen域),以此控制生成對應的寫入地址。
進入之後的拷貝函數。
如下所示0x7c38a428這個地址原本保存了kernel32!FlsGetValueStub的地址
此時寫入的地址為7c376fc3,該地址代碼如下所示:
之後的第三,第四個標簽和之前一致,用於將9c90808寫入到0x7c38a430中。
下斷點到前面的劫持地址7c376fc3,重新運行,漏洞觸發,布置好兩處寫入地址後,之後的程序會調用之前修改的0x7c38a428函數指針,即kernel32!FlsGetValueStub的函數調用,而該地址已經被修改為7c376fc3。
運行到7c376fc3,通過簡單的操作設置好esp棧值後,通過ret返回。
通過回溯可知實際上對該函數指針的調用處如下所示,其傳入的參數ecx為之前修改過的指向9c90800的7c38a430。
9c90808通過計算得出9c9080c,並布置於esp上,最後ret返回進入該heapspray布置的shellcode處執行。
進入shellcode。
此時再來回顧之前的觸發漏洞poc,如下所示的4個smartag兩兩配合,用於完成兩次內存寫入,每次內存寫入依賴兩個smarttag,第一個用於初始化真實寫入的地址,第二次通過第一次初始寫入的地址,生成最後的寫入地址。前兩個smarttag用於完成對函數指針的篡改劫持,後兩個smarttag用於準備篡改後的函數參數,之後wwlib往後運行到劫持函數時導致代碼執行。
具體的篡改流程如下所示:
回溯trigger函數,其父函數調用如下所示,可以看到*(v9+4)即為指向element的指針,SRC為對應的寫入id,v9的值來自於v27+0x44的位置。
往上回溯,可以看到v27來自於v25,而v25的值為fun_GettagObject,很熟悉吧,在之前CVE-2017-11826的文章中我們提到該函數用於返回具體的tag標簽的對象。
通過分析發現進入解析smartag解析流程時,對應的xml返回的結構如下所示,其中Tagobeject[3]標簽為此時返回的標簽,對應Tagobeject[3]+44的位置即為之後導致漏洞的所謂smarttag結構,(Tagobeject[3]+44)+4位置指向smarttag中對應的element。
如下圖所示可知每個對象對應的xml中的標簽,對於正常的子costomxml標簽而言,其taglist應該位於(Tagobeject[3]+44)+4中的位置,由於wwlib對costomxml及smarttag的校驗不嚴,構造非法的smarttag標簽被costomxml的代碼邏輯處理,最為致命的在於,此時的處理中smarttag標簽的element被識別為taglist的baseaddress,導致在標簽解析時fun_CalcspectalTagobject函數計算出的對象地址為攻擊者所控制(通過兩個smarttag標簽可實現指定地址的寫入),而costomxml的處理邏輯中fun_CalcspectalTagobject計算的地址後續會進行內存寫入,此時寫入的值正好也是攻擊者可控的smarttag中的id字段,此時攻擊者具備完整的內存任意地址寫的能力,從而導致代碼執行
補丁代碼中,在進入Tagobeject[3]+44的處理前,會對Tagobeject[3]+48處的函數指針進行校驗,以防止不合法的標簽混入。
相關斷點
bp wwlib+0x00009d30 ".if(ecx = 7c38bd50 | ecx = 7c38bd68| ecx = 7c38bd60| ecx = 7c38bd80){.printf\"woca1\\n\"}.else{gc}" four memory copy
bp wwlib+0x00e1211c get parent tag object of smarttag
相關參考
http://www.freebuf.com/vuls/81868.html
https://paper.seebug.org/351/
office CVE-2015-1641雜談