本文將對CVE-2016-0059進行深度分析,該漏洞是由于微軟超鏈接對象庫內存數據泄露造成的,成功利用該漏洞可以獲得一些信息從而對用戶系統造成進一步威脅。要利用該漏洞,攻擊者必須誘導用戶點擊一個email里的或者一個office文檔里的超鏈接。
起初是把該漏洞作為Microsoft Office Excel?堆溢出漏洞報告給微軟的 ,但是該漏洞實際上是由?Internet Explorer對象庫?hlink.dll (微軟超鏈接對象庫)?引起的,因此微軟把該漏洞定義為?Internet Explorer信息泄露漏洞。本文將仍然用Microsoft Office來證明和分析該漏洞。
受影響產品:
要重現該漏洞,我們可以用?Microsoft Office Excel 2007打開POC FG-VD-15-073_PoC.xls。然后我們可以到Excel.exe崩潰了,崩潰信息顯示如下:
#!bash
(3344.1804): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=1a06d0d0 ebx=00000002 ecx=18b22fea edx=00000001 esi=18b23000 edi=18b22fe8
eip=6cd40b40 esp=00b739b4 ebp=00b739c4 iopl=0 ? ? ? ? nv up ei ng nz na po nc
cs=0023 ?ss=002b ?ds=002b ?es=002b ?fs=0053 ?gs=002b ? ? ? ? ? ? efl=00010282
hlink!WzDupWzToWz+0x16:
6cd40b40 668b06 ? ? ? ? ?mov ? ? ax,word ptr [esi] ? ? ? ?ds:002b:18b23000=????
0:000> u
hlink!WzDupWzToWz+0x16:
6cd40b40 668b06 ? ? ? ? ?mov ? ? ax,word ptr [esi]
6cd40b43 03f3 ? ? ? ? ? ?add ? ? esi,ebx
6cd40b45 6685c0 ? ? ? ? ?test ? ?ax,ax
6cd40b48 75f6 ? ? ? ? ? ?jne ? ? hlink!WzDupWzToWz+0x16 (6cd40b40)
6cd40b4a 2bf1 ? ? ? ? ? ?sub ? ? esi,ecx
6cd40b4c d1fe ? ? ? ? ? ?sar ? ? esi,1
6cd40b4e 8d5e01 ? ? ? ? ?lea ? ? ebx,[esi+1]
6cd40b51 85d2 ? ? ? ? ? ?test ? ?edx,edx
0:000> !heap -p -a esi
? ? address 18b23000 found in
? ? _DPH_HEAP_ROOT @ 5601000
? ? in busy allocation ( ?DPH_HEAP_BLOCK: ? ? ? ? UserAddr ? ? ? ? UserSize - ? ? ? ? VirtAddr ? ? ? ? VirtSize)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1a173a5c: ? ? ? ? 18b22fe8 ? ? ? ? ? ? ? 16 - ? ? ? ? 18b22000 ? ? ? ? ? ? 2000
? ? 5e6d9abc verifier!AVrfDebugPageHeapAllocate+0x0000023c
? ? 77c97ab1 ntdll!RtlDebugAllocateHeap+0x0000003c
? ? 77c4ba4e ntdll!RtlpAllocateHeap+0x0004cfde
? ? 77bfdc26 ntdll!RtlpAllocateHeapInternal+0x00000146
? ? 77bfdab8 ntdll!RtlAllocateHeap+0x00000028
? ? 770f32e6 combase!CRetailMalloc_Alloc+0x00000016 [d:thcomcombaseclassmemapi.cxx @ 641]
? ? 6cd337fd hlink!CMalloc::Alloc+0x0000002d
? ? 6cd40c32 hlink!operator new+0x00000023
? ? 6cd3d50e hlink!HrReadLengthWzStm+0x00000034
? ? 6cd39b2c hlink!HLNK_PersistStm::Load+0x0000010c
*** ERROR: Symbol file could not be found. ?Defaulted to export symbols for C:Program Files (x86)Common FilesMicrosoft Sharedoffice12mso.dll -?
? ? 3280dc07 mso!Ordinal2575+0x00000320
? ? 3280dac1 mso!Ordinal2575+0x000001da
? ? 3280da7a mso!Ordinal2575+0x00000193
*** ERROR: Symbol file could not be found. ?Defaulted to export symbols for C:Program Files (x86)Microsoft OfficeOffice12oart.dll -?
? ? 3a99fb87 oart!Ordinal5476+0x00000709
0:000> dp 18b22fe8 ? ? ? ? ? ? ??
18b22fe8 ?00720041 00610072 00440079 006d0075
18b22ff8 ?00320070 d0d0d000 ???????? ????????
18b23008 ????????? ???????? ???????? ????????
18b23018 ????????? ???????? ???????? ????????
18b23028 ????????? ???????? ???????? ????????
18b23038 ????????? ???????? ???????? ????????
18b23048 ????????? ???????? ???????? ????????
18b23058 ????????? ???????? ???????? ????????
0:000> kb
?# ChildEBP RetAddr ?Args to Child ? ? ? ? ? ? ?
00 00b739c4 6cd3590d 00000000 00b73a88 00b73a1c hlink!WzDupWzToWz+0x16
01 00b739e0 6cd331cf 1a068f28 00000000 00b73a1c hlink!CExtensionService::Release+0x105d
02 00b73a28 3280da8e 1a068f28 00000000 00b73a88 hlink!HLNK::GetStringReference+0x5f
WARNING: Stack unwind information not available. Following frames may be wrong.
03 00b73a58 3a99fb87 08f74fd0 00000000 00b73a88 mso!Ordinal2575+0x1a7
04 00b73d70 77bf6d70 77cc74a8 19cd6ff0 00000000 oart!Ordinal5476+0x709
05 00b73d98 77c91c3a 000df3e0 00000060 14b90fa0 ntdll!RtlpPopEntrySListLockedAlt+0x20
06 00b73de8 32c8de4f 32195748 2fc48b8c 00000000 ntdll!RtlpStdLockRelease+0x14
07 00b73dec 32195748 2fc48b8c 00000000 00000000 mso!Ordinal1743+0x2f43
08 00b73df0 2fc48b8c 00000000 00000000 00000000 mso!MsoPvAllocCore+0x36
09 00b73df4 00000000 00000000 00000000 00b73c90 Excel!Ordinal40+0x108b8c
由于輸入字符串缺失結尾標志符,從而導致讀取字符串時讀取到了字符串以外的內存數據,最終導致了該漏洞的產生。這個漏洞發生在hlink!WzDupWzToWz()?函數里,當該函數進行字符串復制的時候產生了漏洞,成功利用該漏洞可導致信息泄露。
首先我們看一下這個特制的XLS文件,在偏移0x66C 和 0x140DC處分別不同,POC文件和正常文件在這兩處對比如圖:
圖1 正常文件和POC文件在偏移0x66c處對比
圖2 正常文件和POC文件在偏移0x140dc處對比
然后我們用工具Offvis來解析POC文件如圖:
圖3 POC文件0x66c處解析
圖4 POC文件0x140dc處解析
從圖3我們看到,0x66C處對應的是ModifyTime域,實際上它不會導致漏洞產生,這里我們忽略它。從圖4可以看到0x140dc處的 字節D0對應complexData域。并且complexData是fopt (OfficeArtRGFOPTE)結構的一部分,OfficeArtRGFOPTE結構被微軟定義為:
圖5 OfficeArtRGFOPTE結構
從上面的定義中,我們看不到complexData域包含特定的結構。
然后我們在windbg用如下方式設置斷點:
#!bash
bu hlink!HLNK::GetMonikerReference " .printf "GetMonikerReference:\n"; db poi(poi(esp+4)+0x4c);"
該斷點被斷幾次后你會看到如下調試信息:
從上面調試信息可以看到,堆緩沖區0x16c52fe8處包含了complexData域的一部分。它指向一個沒有結束標志符的寬字節字符串。
下面是hlink!HLNK::GetMonikerReference函數的部分代碼,它調用?hlink!WzDupWzToWz()?函數來處理這個寬字節字符串。
下圖是對函數hlink!WzDupWzToWz()的分析
圖6 hlink!WzDupWzToWz()函數分析
總的來說,該問題是由于讀取輸入字符串的時候,該字符串沒有結束標識符,從而讀取到了該字符串內存以外的數據造成的。這個過程是?hlink!WzDupWzToWz()?函數進行字符串復制操作的時候發生的。
庫文件hlink.dll時用來處理超鏈接對象的。我們可以通過如下方式創建一個超鏈接來構造POC文件:
圖7 在XLS 文件里創建超鏈接
我們把它保存為?test.xls,然后用?Offvis解析如下:
圖8 新構造的EXCEL文件解析
從上圖可以清楚第看到我們創建的超鏈接被存儲在了HLink?結構中,HLink結構被微軟定義如下:
Hyperlink結構定義如下:
根據上面的定義,我們可以通過與HLink結構進行對比,來推斷complexData域的數據結構。上面構造的test.xls里HLink結構如下:
由此推斷complexData域數據內部結構如下(譯者注:這里紅框中00 D0,可能應該是 00 00):
我們修改hyperlinkBitFields字段的值為?|08 00 00 00|
?,修改HyperlinkString字段的字符串結束符NULL 為?|00 D0|
?如圖:
保存后在WIN7 和WIN10里測試,可以觸發漏洞。下圖是在WIN10里的截圖:
如上圖所示,打開修改后的test.xls,可以看到hlink.dll并沒有被加載。然后點擊超鏈接"test",這時候hlink.dll被加載,并觸發了漏洞,如圖: