用的是泉哥的POC來調的這個漏洞
0x0 漏洞除錯
Microsoft Office Open XML檔案格式轉換器棧緩衝區溢位漏洞
Microsoft Office 是微軟釋出的非常流行的辦公軟體套件。
基於Mac平臺的Microsoft Office XP SP3,Office 2003 SP3,Office 2007
SP2,Office 2010,Office 2004以及2008版本,基於Mac 2011平臺的Office,以及基於MAC平臺的Open
XML檔案格式轉換器中存在基於棧的緩衝區溢位漏洞。遠端攻擊者可以藉助特製的RTF資料執行任意程式碼。該漏洞又名"RTF棧緩衝區溢位漏洞"。
載入POC後,程式中斷在如下所示位置
(8a0.b70): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000c8ac ebx=05000000 ecx=0000019b edx=00000000 esi=1051c24c edi=00130000
eip=30edf864 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
mso!Ordinal1488+0x29fd:
30edf864 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] es:0023:00130000=78746341 ds:0023:1051c24c=4c36744c
此時若是檢視棧回溯會發現得不到正確的結果,判斷應該是棧被覆蓋導致棧回溯被破壞得不到正確的結果,於是對mso!Ordinal1488+0x29fd:位置下斷。重新執行程式發現可以正常的得到回溯結果了。棧回溯結果如下
0:000> kp
ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00123dd0 30f0f3cb mso!Ordinal1488+0x29fd
00123e00 30f0f359 mso!Ordinal901+0x2a3c
0012404c 30d4d762 mso!Ordinal901+0x29ca
00124074 30d4d70b mso!Ordinal4925+0x53
00124078 30d4d47d mso!Ordinal5148+0x36
0012407c 06270b10 mso!Ordinal4783+0x12f
00124080 06270b48 0x6270b10
00124084 062709f8 0x6270b48
00124088 30dd112c 0x62709f8
0012408c 00000000 mso!Ordinal2940+0x1588c
可以看到本段函式是由mso!Ordinal901+0x2a3c(30f0f3cb)呼叫而來,對30f0f3cb函式進行檢視發現並不是呼叫到本函式的,而是呼叫了 sub_30F0F422。如下所示
0:000> ub 30f0f3cb
mso!Ordinal901+0x2a28:
30f0f3b7 23c1 and eax,ecx
30f0f3b9 50 push eax
30f0f3ba 8d47ff lea eax,[edi-1]
30f0f3bd 50 push eax
30f0f3be 8b4508 mov eax,dword ptr [ebp+8]
30f0f3c1 6a00 push 0
30f0f3c3 ff750c push dword ptr [ebp+0Ch]
30f0f3c6 e857000000 call mso!Ordinal901+0x2a93 (30f0f422)
跟進sub_30F0F422裡面也沒有發現有直接呼叫30edf864所在函式的語句。用ida載入MSO.dll檔案,發現30edf864所在的函式被IDA識別為資料,自行建立函式之後求交叉引用發現此地址被置於如下所示的資料表中,推測是某一個物件的虛表?
.text:30DA6114 dd offset sub_30EDF83E
總之發現了30f0f422對30edf864所在函式的呼叫關係。
分析30edf864所在的sub_30EDF83E函式可以看到,所執行的rep movsd指令的edi(複製的目的地址)為2號引數。複製的次數為 (*(引數1+8)&65535)/4 。複製的源地址為 *(引數1+8)&65535*引數3+*(引數1+16) 。看起來很奇怪是不是我也覺得很奇怪,但是覺得可能是某個物件的this指標。我們先對mso!Ordinal1488+0x29fd(30edf864)下斷,重新執行程式斷在這裡,這時可以看到ecx的值為0x322b如下所示。我們知道這個大小意味著相當的大(0x322b=13099,13099x4=52396),共52396個位元組。
0:000> r
eax=0000c8ac ebx=05000000 ecx=0000322b edx=00000000 esi=1051000c edi=00123dc0
eip=30edf864 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
mso!Ordinal1488+0x29fd:
30edf864 f3a5 rep movs dword ptr es:[edi],dword ptr [esi] es:0023:00123dc0=ffff0000 ds:0023:1051000c=41306141
無論如何棧也是承受不了這樣的大小的。那麼到底能承受多少呢?我們來看下。
1 .text:30F0F422 var_10 = dword ptr -10h
2
3 .text:30F0F44B lea ecx, [ebp+var_10]
4 .text:30F0F44E push ecx
5 .text:30F0F44F mov ebx, 5000000h
6 .text:30F0F454 push esi
7 .text:30F0F455 mov [ebp+var_C], ebx
8 .text:30F0F458 call dword ptr [eax+1Ch] //呼叫sub_30EDF83E
由上面可以知道,複製的目的地址就是var_10,一個sub_30F0F422中的4位元組的區域性變數。試圖往4個位元組中複製52396個位元組,這樣肯定是會溢位的了。我們進一步看一下棧的情況
0:000> dc edi
00123dc0 ffff00ff 05000000 00000000 00e4ffff ................
00123dd0 00123e00 30f0f3cb 00123f3c 00000000 .>.....0<?......
00123de0 ffffffff 00000000 01280b28 00124420 ........(.(. D..
00123df0 0012408c 00124e38 001240b0 00000000 .@..8N...@......
00123e00 00123fe4 30f0f359 00123f88 00123f3c .?..Y..0.?..<?..
00123e10 00000000 01280b28 0012408c 00124420 ....(.(..@.. D..
00123e20 00000000 ffffffff ffffffff ffffffff ................
00123e30 00000000 20000000 00000101 00000000 ....... ........
0:000> kp
ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00123dd0 30f0f3cb mso!Ordinal1488+0x29fd
00123e00 30f0f359 mso!Ordinal901+0x2a3c
0012404c 30d4d762 mso!Ordinal901+0x29ca
00124074 30d4d70b mso!Ordinal4925+0x53
00124078 30d4d47d mso!Ordinal5148+0x36
0012407c 01280b10 mso!Ordinal4783+0x12f
00124080 01280b48 0x1280b10
00124084 012809f8 0x1280b48
00124088 30dd112c 0x12809f8
0012408c 00000000 mso!Ordinal2940+0x1588c
可見最多達到16byte時會覆蓋ebp,然後是返回地址。
0x1 漏洞分析
我們在前面看了一下漏洞觸發的原理,但是漏洞為什麼會存在還並沒有搞清楚。我們回過頭來看一下漏洞描述可以知道這是對rtf檔案的解析不正確所導致漏洞。那麼我們來看下複製的東西是什麼
0:000> db esi
1109000c ba 1e 1d 88 05 d9 c7 d9-74 24 f4 5e 29 c9 b1 32 ........t$.^)..2
1109001c 83 ee fc 31 56 0e 03 48-13 6a f0 88 c3 e3 fb 70 ...1V..H.j.....p
1109002c 14 94 72 95 25 86 e1 de-14 16 61 b2 94 dd 27 26 ..r.%.....a...'&
1109003c 2e 93 ef 49 87 1e d6 64-18 af d6 2a da b1 aa 30 ...I...d...*...0
1109004c 0f 12 92 fb 42 53 d3 e1-ad 01 8c 6e 1f b6 b9 32 ....BS.....n...2
1109005c 9c b7 6d 39 9c cf 08 fd-69 7a 12 2d c1 f1 5c d5 ..m9....iz.-..\.
1109006c 69 5d 7d e4 be bd 41 af-cb 76 31 2e 1a 47 ba 01 i]}...A..v1..G..
1109007c 62 04 85 ae 6f 54 c1 08-90 23 39 6b 2d 34 fa 16 b...oT...#9k-4..
在poc檔案中搜尋一下,如下圖
咦,acc8這個數有點熟悉啊
0:008> g
ModLoad: 05da0000 05f41000 C:\Program Files\Microsoft Office\OFFICE11\GdiPlus.DLL
Breakpoint 0 hit
eax=0000c8ac ebx=05000000 ecx=0000c8ac edx=00000000 esi=1051000c edi=00123dc0
eip=30edf861 esp=00123d98 ebp=00123dd0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
mso!Ordinal1488+0x29fa:
30edf861 c1e902 shr ecx,2
注意看ecx,明顯是信任了rtf檔案的給出的大小而沒有進行自己的驗證,而那些.doc的樣本其實就是rtf檔案改了一下字尾名,其實還是按照rtf進行解析的。搞定!
ps:win7通用的jmp esp 7ffa4512