CVE-2021-31179
Information
graph.exe at offset 0x9FCDC contains a parsing loop of TLV records from the graph’s data stream.
- Graph.exe initializes an object with a pointer to an additional object at offset 0x22
- When handling the record type 0x005D, std::numpunct::_Init is being invoked, which causes the lower 2 bytes of the said pointer to be set to 0x0006
- After that, when handling the record type 0x000A, the code uses the now-modified pointer (stored at offset 0x22) in order to extract a value, which in turn will be used for Read / Write operations on the Heap
Due to the nature of this vulnerability, we have observed multiple different crashes, depending on the heap value / state pointed to by the modified pointer:
- Use-After-Free
- Heap Corruption (verifier)
- Etc.
Stack trace:
0:000> k
00 00000035`9e8f7810 00007ff6`3de6a56e graph+0x15c49d
01 00000035`9e8f7850 00007ff6`3de6a4a8 graph+0x1ba56e
02 00000035`9e8f7890 00007ff6`3de7fcd9 graph+0x1ba4a8
03 00000035`9e8f78d0 00007ff6`3de0c198 graph+0x1cfcd9
04 00000035`9e8f7910 00007ff6`3de0c8db graph+0x15c198
05 00000035`9e8f7a80 00007ff6`3dcbd9a1 graph+0x15c8db
06 00000035`9e8f7ae0 00007ff6`3dcb1eb1 graph+0xd9a1
07 00000035`9e8fa9c0 00007ff6`3de4aeea graph+0x1eb1
08 00000035`9e8fb290 00007ffe`f0f5f3cf graph+0x19aeea
09 00000035`9e8fb350 00007ffe`f0f490e6 OLEAUT32!DispCallFuncAmd64+0x7f
0a 00000035`9e8fb3c0 00007ffe`f0f496e4 OLEAUT32!DispCallFunc+0x226
0b 00000035`9e8fb510 00007ffe`f0f49fe1 OLEAUT32!CTypeInfo2::Invoke+0x554
0c 00000035`9e8fb8c0 00007ff6`3de5661e OLEAUT32!CTypeInfo2::Invoke+0xe51
0d 00000035`9e8fbc70 00007ffe`f0fcbb04 graph+0x1a661e
0e 00000035`9e8fe1c0 00007ffe`f0fcacb0 OLEAUT32!IDispatch_Invoke_Stub+0xd4
0f 00000035`9e8fe250 00007ffe`f0201a3f OLEAUT32!IDispatch_RemoteInvoke_Thunk+0x60
10 00000035`9e8fe2c0 00007ffe`f1168422 RPCRT4!NdrStubCall2+0x92f
11 00000035`9e8fe920 00007ffe`f0f42f60 combase!CStdStubBuffer_Invoke+0xa2 [onecore\com\combase\ndr\ndrole\stub.cxx @ 1524]
12 00000035`9e8fe960 00007ffe`f10f4313 OLEAUT32!CStubWrapper::Invoke+0x90
13 (Inline Function) --------`-------- combase!InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_c9f3956a20c9da92a64affc24fdd69ec>::operator()+0x18 [onecore\com\combase\dcomrem\channelb.cxx @ 1385]
14 00000035`9e8fe9a0 00007ffe`f10f4103 combase!ObjectMethodExceptionHandlingAction<<lambda_c9f3956a20c9da92a64affc24fdd69ec> >+0x43 [onecore\com\combase\dcomrem\excepn.hxx @ 87]
15 (Inline Function) --------`-------- combase!InvokeStubWithExceptionPolicyAndTracing+0xa8 [onecore\com\combase\dcomrem\channelb.cxx @ 1383]
16 00000035`9e8fea00 00007ffe`f116b036 combase!DefaultStubInvoke+0x1c3 [onecore\com\combase\dcomrem\channelb.cxx @ 1452]
17 (Inline Function) --------`-------- combase!SyncStubCall::Invoke+0x22 [onecore\com\combase\dcomrem\channelb.cxx @ 1509]
18 00000035`9e8feb50 00007ffe`f10f82da combase!SyncServerCall::StubInvoke+0x26 [onecore\com\combase\dcomrem\servercall.hpp @ 826]
19 (Inline Function) --------`-------- combase!StubInvoke+0x259 [onecore\com\combase\dcomrem\channelb.cxx @ 1734]
1a 00000035`9e8feb90 00007ffe`f10f550d combase!ServerCall::ContextInvoke+0x42a [onecore\com\combase\dcomrem\ctxchnl.cxx @ 1418]
1b (Inline Function) --------`-------- combase!CServerChannel::ContextInvoke+0x79 [onecore\com\combase\dcomrem\ctxchnl.cxx @ 1327]
1c (Inline Function) --------`-------- combase!DefaultInvokeInApartment+0x92 [onecore\com\combase\dcomrem\callctrl.cxx @ 3352]
1d 00000035`9e8fef90 00007ffe`f111579c combase!ReentrantSTAInvokeInApartment+0x19d [onecore\com\combase\dcomrem\reentrantsta.cpp @ 112]
1e 00000035`9e8ff010 00007ffe`f1116001 combase!AppInvoke+0x1ec [onecore\com\combase\dcomrem\channelb.cxx @ 1182]
1f 00000035`9e8ff0a0 00007ffe`f1137c6d combase!ComInvokeWithLockAndIPID+0x681 [onecore\com\combase\dcomrem\channelb.cxx @ 2290]
20 (Inline Function) --------`-------- combase!ComInvoke+0x1ab [onecore\com\combase\dcomrem\channelb.cxx @ 1803]
21 (Inline Function) --------`-------- combase!ThreadDispatch+0x20a [onecore\com\combase\dcomrem\chancont.cxx @ 416]
22 00000035`9e8ff3d0 00007ffe`f15f5c1d combase!ThreadWndProc+0x3ad [onecore\com\combase\dcomrem\chancont.cxx @ 744]
23 00000035`9e8ff500 00007ffe`f15f5612 USER32!UserCallWinProcCheckWow+0x2bd
24 00000035`9e8ff690 00007ff6`3decf681 USER32!DispatchMessageWorker+0x1e2
25 00000035`9e8ff710 00007ff6`3dcd92d7 graph+0x21f681
26 00000035`9e8ff740 00007ff6`3dec2dd6 graph+0x292d7
27 00000035`9e8ff930 00007ff6`3e02f602 graph+0x212dd6
28 00000035`9e8ffa30 00007ffe`f0327c24 graph+0x37f602
29 00000035`9e8ffa70 00007ffe`f18cd721 KERNEL32!BaseThreadInitThunk+0x14
2a 00000035`9e8ffaa0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
0:000> r
rax=000001e9de6a0006 rbx=0000000000000001 rcx=000001e9e0dc9fc0
rdx=000000359e8f7aa0 rsi=0000000000000000 rdi=000001e9de6a0008
rip=00007ff63de0c49d rsp=000000359e8f7810 rbp=0000000000000000
r8=0000000000000000 r9=0000000000000000 r10=000000359e8f7aa0
r11=0100000000440000 r12=0000000000000000 r13=0000000000000001
r14=000000359e8f7aa0 r15=000000359e8fb2e0
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
graph+0x15c49d:
00007ff6`3de0c49d 0fb707 movzx eax,word ptr [rdi] ds:000001e9`de6a0008=????
Steps to reproduce:
Steps to reproduce - Outlook:
1. open WinDBG for the following process: C:\Program Files\Microsoft Office\root\Office16\graph.exe /automation -Embedding
2. open crash.eml using outlook
3. double-click the image inside the eml file
4. observe the crash in WinDBG
** Please note that if you have Microsoft Office installed, excelcnv.exe may cause your outlook to hang, so we recommend changing its name for testing purposes.
Steps to reproduce - Graph:
1. open WinDBG for the following process: C:\Program Files\Microsoft Office\root\Office16\graph.exe /automation -Embedding
2. run the attached vbscript file - test.vbs with crash.bin as an argument (use the full path)
3. observe the crash in WinDBG
Attachments:
crash
crash.eml
test.vbs
References:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-31179
https://research.checkpoint.com/2021/fuzzing-the-office-ecosystem/