作者: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_

歡迎轉發分享,或者打賞一杯咖啡錢。 :)

參考

  1. http://360coresec.blogspot.com/2017/10/new-office-0day-cve-2017-11826.html
  2. http://www.freebuf.com/vuls/150607.html
  3. https://securingtomorrow.mcafee.com/mcafee-labs/analyzing-microsoft-office-zero-day-exploit-cve-2017-11826-memory-corruption-vulnerability/
  4. https://github.com/decalage2/oletools

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/435/