d3k4z / google-security-research

Automatically exported from code.google.com/p/google-security-research
1 stars 0 forks source link

Microsoft Office 2007: object vtable memory corruption #379

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The following crash was observed in MS Office 2007 running under Windows 2003 
x86. Microsoft Office File Validation Add-In is disabled for testing and 
reproduction. This sample did not reproduce in Office 2010 on Windows 7 x86. 
There may be difficulties triggering this crash multiple times if Office 
attempts to repair the document. You can rename the crashing file to a unique 
name with each open to prevent this.

The attached minimized PoC that produces the crash is a 1 bit change from the 
original file. OffViz identifies this offset (0xEF4) as the least significant 
byte in: 
stPapxFKPs[2].PAPXKFP[0].PAPXINFKP[2].ggpprlInPapx.grpprl[8].PRL[5].sprm.operand

Attached files:

Fuzzed and minimized PoC: 3471051319_crash.doc
Fuzzed non-minimized PoC: 3471051319_fuzzed.doc
Original non-mutated file: 3471051319_orig.doc

Observed crash:

eax=00000011 ebx=012c0550 ecx=03321a20 edx=33513a02 esi=012c0540 edi=03320410
eip=326a9754 esp=0012b414 ebp=0012b428 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
mso!Ordinal4328+0x153:
326a9754 ff5024          call    dword ptr [eax+24h]  ds:0023:00000035=????????
0:000> k
ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
0012b428 3280c0f8 mso!Ordinal4328+0x153
0012b440 327ad143 mso!Ordinal7740+0x1a1
0012b478 326dc30b mso!Ordinal7069+0x74
0012b488 326dbbc5 mso!Ordinal3891+0x605
0012b498 326dbeb4 mso!Ordinal3805+0x56b

326a9749 8b0e            mov     ecx,dword ptr [esi]
326a974b ff7508          push    dword ptr [ebp+8]
326a974e 83e1fe          and     ecx,0FFFFFFFEh
326a9751 8b01            mov     eax,dword ptr [ecx]
326a9753 57              push    edi
326a9754 ff5024          call    dword ptr [eax+24h]  ds:0023:00000035=????????

ecx is set to 03321a20 which contains the value 00000011.

Restarting and setting a write memory access breakpoint with "ba w 1 03321a20" 
shows that the first usage of this heap address is a call to memset(). The 
stack trace shows this call coming from mso.dll similar to the crashing call 
stack. It is likely that this is where our object is initialized. The next 
breakpoint hit shows a constant value being set at instruction 32695985. The 
call stack here also shows this value being set with calls from mso.dll as well.

Breakpoint 0 hit
eax=032a2a20 ebx=00000000 ecx=0012beb0 edx=00000000 esi=032a2a20 edi=00000020
eip=3269598b esp=0012bea0 ebp=0012beb4 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212

3269597e 83c40c          add     esp,0Ch
32695981 56              push    esi
32695982 8d4dfc          lea     ecx,[ebp-4]
=> 32695985 c706344fa732    mov     dword ptr [esi],offset 
mso!Ordinal2940+0xbfde0 (32a74f34)
3269598b 895e04          mov     dword ptr [esi+4],ebx ds:0023:032a2a24=00000000

The constant value (32a74f34) appears to be a vtable pointer because it 
contains pointers to the following function start addresses:

32a74f34 3276f9c9 mso!Ordinal7518
32a74f38 32695b54 mso!Ordinal8791+0x635
32a74f3c 32695d6e mso!Ordinal8791+0x84f
32a74f40 3263cca7 mso!Ordinal5455
32a74f44 3271522a mso!Ordinal6935+0x7b
32a74f48 327f8efb mso!Ordinal8490+0x121
32a74f4c 3339109a mso!Ordinal4570+0x158
32a74f50 3269618b mso!Ordinal7282+0x78
32a74f54 327ad69d mso!Ordinal1715+0x23f
32a74f58 326a989d mso!Ordinal4328+0x29c
32a74f5c 32697acc mso!Ordinal6617+0x225
32a74f60 32725a7c mso!Ordinal5274+0x35
32a74f64 32699abd mso!Ordinal8336+0x785
32a74f68 3284dcad mso!Ordinal9267+0x5f
32a74f6c 3271b4a6 mso!Ordinal329+0xee9
32a74f70 3280ce05 mso!Ordinal8127+0x72
32a74f74 32697209 mso!Ordinal8136+0x68
32a74f78 327089da mso!Ordinal2426+0xb8e
32a74f7c 00000000

The next access to this memory address is on a memcpy() from wwlib.dll. The 
vtable pointer is gone at this point. Continuing, we see our watch access 
address being set with a mov [eax], ecx also from wwlib.dll. The value being 
written in this write look to be flag values at this point. Continuing once 
more we see:

Breakpoint 0 hit
eax=032a2a20 ebx=00000000 ecx=00000011 edx=00000001 esi=00000000 edi=00000100
eip=31249f2a esp=001284f0 ebp=001284f4 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206

31249f13 3b560c          cmp     edx,dword ptr [esi+0Ch]
31249f16 8d44961c        lea     eax,[esi+edx*4+1Ch]
31249f1a 0f83c2900400    jae     wwlib!FMain+0x4ea2b (31292fe2)
31249f20 33f6            xor     esi,esi
31249f22 8b4d08          mov     ecx,dword ptr [ebp+8]
31249f25 2bce            sub     ecx,esi
31249f27 5f              pop     edi
=> 31249f28 8908            mov     dword ptr [eax],ecx
31249f2a 5e              pop     esi

0:000> k
ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
001284f4 320c436f wwlib!FMain+0x5973
00128558 320c5c36 wwlib!DllGetClassObject+0xf70f
00128fe0 320c3d45 wwlib!DllGetClassObject+0x10fd6
0012937c 312ff5c6 wwlib!DllGetClassObject+0xf0e5

0:000> dd 32a2a20
032a2a20  00000011 00000001 0000000e 0000000e
032a2a30  00000000 000000ad 00000000 000000cd
032a2a40  00000030 00300000 00000000 00024000

This 00000011 value is the value used in the call [eax+24h] that we saw in the 
original crash. Indeed, if we continue one last time we end up back at the 
original crashing instruction. The analysis here shows that an object with a 
corrupted vtable is being called. The call was intended to go to the function 
at 326a989d (mso!Ordinal4328+0x29c). This is suggestive of a UAF or memory 
corruption vulnerability.

DLL version information is:

wwlib.dll: 12.0.6720.5000
mso.dll: 12.0.6718.5000

This bug is subject to a 90 day disclosure deadline. If 90 days elapse without 
a broadly available patch, then the bug report will automatically become 
visible to the public.

Original issue reported on code.google.com by scvi...@google.com on 13 May 2015 at 4:08

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 13 May 2015 at 4:09

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 13 May 2015 at 5:45

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 17 Jul 2015 at 7:13

GoogleCodeExporter commented 9 years ago

Original comment by scvi...@google.com on 21 Jul 2015 at 4:00