作者:binjo
CVE-2017-11826是360捕獲的一個在野0day,當時的announcement信息較少,隨著研究人員在VirusTotal之類平臺發現真實樣本后,陸續有分析文章面世,然而對于漏洞本身似乎并沒有文章進行深入分析。遂成此文,記錄及分享之。 筆者的分析平臺基于Windows 7 + Office 2010。筆者假設讀者已經閱讀過其它分析文章,對該漏洞樣本有個大致了解。
Crash現場
真實樣本中內嵌了兩個docx,一個負責spray heap,一個負責觸發漏洞,為了方便調試,我們可以利用oletools工具,先dump出來再單獨加載、調試。dump的文件包含OLE頭部,使用二進制編輯軟件如010Editor去除。 打開該docx文件后,Office崩潰場景如下:
(97c.438): Access violation - code c0000005 (!!! second chance !!!)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Microsoft Office\Office14\wwlib.dll -
eax=088888ec ebx=00000000 ecx=03d50f00 edx=00000004 esi=012b42b0 edi=0128c1dc
eip=5b38962a esp=002f3134 ebp=002f319c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
wwlib!DllGetClassObject+0xf2e3a:
5b38962a 8b08 mov ecx,dword ptr [eax] ds:0023:088888ec=????????
引用寄存器eax時產生異常,查看該語句上下文,可以發現0x088888ec從某個對象+44h處取得,而設置其值就在上面不遠處。
5b38960b 8b06 mov eax,dword ptr [esi]
5b38960d 8b10 mov edx,dword ptr [eax]
5b38960f 4a dec edx
5b389610 4a dec edx
5b389611 8bce mov ecx,esi
5b389613 e8ee70d4ff call wwlib!DllMain+0x3b15 (5b0d0706) // 關鍵call
5b389618 8b4044 mov eax,dword ptr [eax+44h]
5b38961b 8b4044 mov eax,dword ptr [eax+44h]
5b38961e 8b4f44 mov ecx,dword ptr [edi+44h]
5b389621 894144 mov dword ptr [ecx+44h],eax // [[edi+44h]+44h] = [[eax+44h]+44h]
5b389624 8b4744 mov eax,dword ptr [edi+44h]
5b389627 8b4044 mov eax,dword ptr [eax+44h] // eax = [[edi+44h]+44h]
5b38962a 8b08 mov ecx,dword ptr [eax] ds:0023:088888ec=????????
5b38962c 50 push eax
5b38962d ff5104 call dword ptr [ecx+4] // 飛向光明之巔!
5b389613(wwlib!DllGetClassObject+0xf2e23)處的call wwlib!DllMain+0x3b15就是關鍵,其取得的某個對象+44h處應該是個指針,指針指向的對象+44h處便是0x088888ec了。
倒攆猴
為了驗證,我們先attach windbg到winword.exe,對其設斷,然后再打開觸發文件。
(8fc.aa4): Break instruction exception - code 80000003 (first chance)
eax=7ffaf000 ebx=00000000 ecx=00000000 edx=7725ec4b esi=00000000 edi=00000000
eip=771f3c8c esp=01a9fe30 ebp=01a9fe5c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!DbgBreakPoint:
771f3c8c cc int 3
0:012> bp wwlib!DllGetClassObject+0xf2e23
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Microsoft Office\Office14\wwlib.dll -
0:012> g
Breakpoint 0 hit
eax=039f7800 ebx=00000000 ecx=012b4450 edx=00000004 esi=012b4450 edi=039f79dc
eip=5b389613 esp=00120c40 ebp=00120ca8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
wwlib!DllGetClassObject+0xf2e23:
5b389613 e8ee70d4ff call wwlib!DllMain+0x3b15 (5b0d0706)
這時單步進入,慢慢調戲,哦不,調試之。當然看官也可同時在IDA中查看。
.text:318D0706 xxx_retrieve_obj_ptr proc near ; CODE XREF: sub_318CFA51+2A9↑p
.text:318D0706 ; sub_318D0659+1E↑p ...
.text:318D0706 mov ecx, [ecx]
.text:318D0708 mov eax, [ecx]
.text:318D070A cmp edx, eax
.text:318D070C jb short loc_318D0710
.text:318D070E mov edx, eax
.text:318D0710
.text:318D0710 loc_318D0710: ; CODE XREF: xxx_retrieve_obj_ptr+6↑j
.text:318D0710 mov eax, [ecx+8]
.text:318D0713 imul eax, edx
.text:318D0716 add eax, [ecx+0Ch]
.text:318D0719 add eax, ecx
.text:318D071B retn
.text:318D071B xxx_retrieve_obj_ptr endp
它邏輯很簡單,edx是某個index值,ecx經過兩次defer后指向一個結構體,返回的是edx對應index值對應的結構體(某個對象)指針。查看內存,可以推斷當前存在6個對象,在內存中的大小為0x5c。
0:000> dd poi(ecx) l10/4
039f7800 00000006 00000019 0000005c 00000010
0:000> dd poi(ecx)+10+5c*0 l5c/4
039f7810 0000007d 00000096 0000002e 00000027
039f7820 00000000 00000000 00000000 00000000
039f7830 ffff0000 ffffffff 0000ffff 00000000
039f7840 ffff0000 0000ffff 00000000 00000000
039f7850 00000000 00000000 00000000 00000000
039f7860 00000000 00000000 00000000
0:000> dd poi(ecx)+10+5c*1 l5c/4
039f786c 00000132 00000030 0000002e 00000027
039f787c 00000000 00000000 00000000 00000000
039f788c ffff0000 ffffffff 0000ffff 00000000
039f789c ffff0000 0000ffff 00000000 00000000
039f78ac 00000000 00000000 00000000 00000000
039f78bc 00000000 00000000 00000000
0:000> dd poi(ecx)+10+5c*2 l5c/4
039f78c8 000001c7 000001ca 0000002e 00000027
039f78d8 00000000 00000000 00000000 00000000
039f78e8 ffff0000 ffffffff 0000ffff 00000000
039f78f8 ffff0000 0000ffff 00000000 00000000
039f7908 00000000 00000000 00000000 00000000
039f7918 00000000 00000000 00000000
0:000> dd poi(ecx)+10+5c*3 l5c/4
039f7924 0000ffff 0000ffff 0000001a 0000001a
039f7934 00000001 00000000 00000000 00000000
039f7944 ffff0000 ffffffff 0000ffff 00000000
039f7954 ffff0000 0000ffff 00000000 00000000
039f7964 00000000 015006e0 5b694a29 00000000
039f7974 00000000 00000000 00000000
0:000> dd poi(ecx)+10+5c*4 l5c/4
039f7980 0000020a 000000e0 0000002e 00000027
039f7990 00000000 00000000 00000000 00000000
039f79a0 ffff0000 ffffffff 0000ffff 00000000
039f79b0 ffff0000 0000ffff 00000000 00000000
039f79c0 00000000 0148d300 5b2acb04 00000000
039f79d0 00000000 00000000 00000000
0:000> dd poi(ecx)+10+5c*5 l5c/4
039f79dc 0000ffff 0000ffff 0000001a 0000001a
039f79ec 00000000 00000000 00000000 00000000
039f79fc ffff0000 ffffffff 0000ffff 00000000
039f7a0c ffff0000 0000ffff 00000000 00000000
039f7a1c 00000000 01500640 5b694a29 00000000
039f7a2c 00000000 00000000 00000000
由前面斷下時寄存器edx可知,程序在取得index=4對應的對象后,產生了崩潰,讓我們看看這是個什么神仙。
0:000> dd poi(ecx)+10+5c*4 l5c/4
039f7980 0000020a 000000e0 0000002e 00000027
039f7990 00000000 00000000 00000000 00000000
039f79a0 ffff0000 ffffffff 0000ffff 00000000
039f79b0 ffff0000 0000ffff 00000000 00000000
039f79c0 00000000 0148d300 5b2acb04 00000000
039f79d0 00000000 00000000 00000000
0:000> dc 0148d300
0148d300 0000045f 00000000 00000000 00000000 _...............
0148d310 00000000 00000000 00000000 00000000 ................
0148d320 00000000 00000000 0069004c 0063006e ........L.i.n.c.
0148d330 00720065 00680043 00720061 00680043 e.r.C.h.a.r.C.h.
0148d340 00720061 088888ec 006f0066 0074006e a.r.....f.o.n.t.
0148d350 0062ff1a 00740061 006e0061 00000067 ..b.a.t.a.n.g...
0148d360 00000000 00000000 00000000 00000000 ................
0148d370 00000000 00000000 00000000 00000000 ................
這時我們發現那個0x088888ec在這對象的+44h處了,對照docx中的樣式,我們可以推斷這是那個font對象。
<w:body >
<w:shapeDefaults >
<o:OLEObject >
<w:font w:name="LincerCharChar裬?font:batang"><o:idmap/>
</o:OLEObject>
</w:shapeDefaults>
</w:body>
不知道客官是否好奇那個結構體數組中其它對象是什么呢,我們再來一探究竟。
0:000> dd poi(ecx)+10+5c*3 l5c/4
039f7924 0000ffff 0000ffff 0000001a 0000001a
039f7934 00000001 00000000 00000000 00000000
039f7944 ffff0000 ffffffff 0000ffff 00000000
039f7954 ffff0000 0000ffff 00000000 00000000
039f7964 00000000 015006e0 5b694a29 00000000
039f7974 00000000 00000000 00000000
0:000> dc 015006e0
015006e0 00000001 00000001 0148cf18 00000009 ..........H.....
015006f0 00000000 00000000 00000000 00000000 ................
01500700 00000000 000004b0 00000000 00000000 ................
01500710 0005003c 00000000 00000000 00000000 <...............
01500720 00000003 01500b40 00000000 614c223d ....@.P.....="La
01500730 5957c414 00000000 595ffd5c 54484b4c ..WY....\._YLKHT
01500740 75734d43 69727453 614d676e 00000070 CMsuStringMap...
01500750 00000001 01202e98 592c484d 592c4db0 ...... .MH,Y.M,Y
0:000> du 0148cf18 l9
0148cf18 "OLEObject"
0:000> dd poi(ecx)+10+5c*5 l5c/4
039f79dc 0000ffff 0000ffff 0000001a 0000001a
039f79ec 00000000 00000000 00000000 00000000
039f79fc ffff0000 ffffffff 0000ffff 00000000
039f7a0c ffff0000 0000ffff 00000000 00000000
039f7a1c 00000000 01500640 5b694a29 00000000
039f7a2c 00000000 00000000 00000000
0:000> dc 01500640
01500640 00000001 00000001 01f86ee0 00000005 .........n......
01500650 00000000 00000000 00000000 00000000 ................
01500660 00000000 000004b0 00000000 00000000 ................
01500670 0005003c 00000000 00000000 00000000 <...............
01500680 00000003 00000000 00000000 2f226179 ............ya"/
01500690 00016b48 55b77748 0001fbd0 55b778c8 Hk..Hw.U.....x.U
015006a0 0000000e 74202261 00000000 00000000 ....a" t........
015006b0 00000000 00000000 00000001 594f9e4c ............L.OY
0:000> du 01f86ee0 l5
01f86ee0 "idmap"
原來它們分別對應OLEObject和idmap,和xml相呼應。至此,我想客官可以大膽猜上一猜了,Office在解析那段xml時,解析器維護了一段內存來保存解析狀態,當處理<o:idmap>時,存在type confusion漏洞,取得了前置font對象內容,且可以被利用來控制寄存器eax,從而控制程序流程。如果<w:font>這個tag正確閉合,可以驗證該font對象內容不會存在于那段內存中。
補丁
知道漏洞關鍵點后,尋找補丁也就順理成章,不難找到具體位置了。取得對象指針后,再比較了+48h處的指針,如果不對應則跳轉了。
.text:31B8960B 8B 01 mov eax, [ecx]
.text:31B8960D 8B 10 mov edx, [eax]
.text:31B8960F 4A dec edx
.text:31B89610 4A dec edx
.text:31B89611 E8 E8 70 D4 FF call xxx_retrieve_obj_ptr
.text:31B89616 81 78 48 4A 4A E9+ cmp dword ptr [eax+48h], offset sub_31E94A4A ; patch for CVE-2017-11826
.text:31B8961D 75 1D jnz short loc_31B8963C
.text:31B8961F 8B 40 44 mov eax, [eax+44h]
.text:31B89622 8B 40 44 mov eax, [eax+44h]
.text:31B89625 8B 4F 44 mov ecx, [edi+44h]
.text:31B89628 89 41 44 mov [ecx+44h], eax
.text:31B8962B 8B 47 44 mov eax, [edi+44h]
.text:31B8962E 8B 40 44 mov eax, [eax+44h]
.text:31B89631 8B 08 mov ecx, [eax]
.text:31B89633 50 push eax
.text:31B89634 FF 51 04 call dword ptr [ecx+4]
禪(xian)定(zhe)時刻
正常打開利用文件,咣當崩潰了,這是為啥呢?
(a70.544): Access violation - code c0000005 (!!! second chance !!!)
eax=768a0000 ebx=088883ec ecx=00000000 edx=77206c74 esi=768a0000 edi=08888f70
eip=08889000 esp=08888f70 ebp=08888f70 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
08889000 e893ffffff call 08888f98
許久沒寫文章,疏漏在所難免,歡迎到微博聯系指正。@binjo_
歡迎轉發分享,或者打賞一杯咖啡錢。 :)

參考
- http://360coresec.blogspot.com/2017/10/new-office-0day-cve-2017-11826.html
- http://www.freebuf.com/vuls/150607.html
- https://securingtomorrow.mcafee.com/mcafee-labs/analyzing-microsoft-office-zero-day-exploit-cve-2017-11826-memory-corruption-vulnerability/
- https://github.com/decalage2/oletools
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/435/