CVE-2021-31178
Information
graph.exe at offset 0x9FCDC contains a parsing loop of TLV records from the graph’s data stream.
When handling a record of type 0x007F (Little-Endian short), following a record type of 0x005D, the following logic occurs:
- The length field of the TLV record is 7 (mark it as “len”)
- There is an inner 4 byte length field at offset 0x04 into the record’s value
- The buffer’s max size is calculated according to “len - 8”, thus having an integer underflow
- The size check is therefore bypassed, and there is a huge read according to the malicious inner length field of 4 bytes.
Stack trace:
0:000> k
00 000000bf`b1b03488 00007ff7`745a725d VCRUNTIME140!memcpy_repmovs+0xe [d:\A01\_work\62\s\src\vctools\crt\vcruntime\src\string\amd64\memcpy.asm @ 114]
01 000000bf`b1b034a0 00007ff7`744a9a0d graph+0x23725d
02 000000bf`b1b034d0 00007ff7`744a9800 graph+0x139a0d
03 000000bf`b1b03540 00007ff7`7441040f graph+0x139800
04 000000bf`b1b035c0 00007ff7`74418ae4 graph+0xa040f
05 000000bf`b1b07b20 00007ff7`7437d730 graph+0xa8ae4
06 000000bf`b1b07d00 00007ff7`74371eb1 graph+0xd730
07 000000bf`b1b0abe0 00007ff7`7450aeea graph+0x1eb1
08 000000bf`b1b0b4b0 00007ffe`f0f5f3cf graph+0x19aeea
09 000000bf`b1b0b570 00007ffe`f0f490e6 OLEAUT32!DispCallFuncAmd64+0x7f
0a 000000bf`b1b0b5e0 00007ffe`f0f496e4 OLEAUT32!DispCallFunc+0x226
0b 000000bf`b1b0b730 00007ffe`f0f49fe1 OLEAUT32!CTypeInfo2::Invoke+0x554
0c 000000bf`b1b0bae0 00007ff7`7451661e OLEAUT32!CTypeInfo2::Invoke+0xe51
0d 000000bf`b1b0be90 00007ffe`f0fcbb04 graph+0x1a661e
0e 000000bf`b1b0e3e0 00007ffe`f0fcacb0 OLEAUT32!IDispatch_Invoke_Stub+0xd4
0f 000000bf`b1b0e470 00007ffe`f0201a3f OLEAUT32!IDispatch_RemoteInvoke_Thunk+0x60
10 000000bf`b1b0e4e0 00007ffe`f1168422 RPCRT4!NdrStubCall2+0x92f
11 000000bf`b1b0eb40 00007ffe`f0f42f60 combase!CStdStubBuffer_Invoke+0xa2 [onecore\com\combase\ndr\ndrole\stub.cxx @ 1524]
12 000000bf`b1b0eb80 00007ffe`f10f4313 OLEAUT32!CStubWrapper::Invoke+0x90
13 (Inline Function) --------`-------- combase!InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_c9f3956a20c9da92a64affc24fdd69ec>::operator()+0x18 [onecore\com\combase\dcomrem\channelb.cxx @ 1385]
14 000000bf`b1b0ebc0 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 000000bf`b1b0ec20 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 000000bf`b1b0ed70 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 000000bf`b1b0edb0 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 000000bf`b1b0f1b0 00007ffe`f111579c combase!ReentrantSTAInvokeInApartment+0x19d [onecore\com\combase\dcomrem\reentrantsta.cpp @ 112]
1e 000000bf`b1b0f230 00007ffe`f1116001 combase!AppInvoke+0x1ec [onecore\com\combase\dcomrem\channelb.cxx @ 1182]
1f 000000bf`b1b0f2c0 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 000000bf`b1b0f5f0 00007ffe`f15f5c1d combase!ThreadWndProc+0x3ad [onecore\com\combase\dcomrem\chancont.cxx @ 744]
23 000000bf`b1b0f720 00007ffe`f15f5612 USER32!UserCallWinProcCheckWow+0x2bd
24 000000bf`b1b0f8b0 00007ff7`7458f681 USER32!DispatchMessageWorker+0x1e2
25 000000bf`b1b0f930 00007ff7`743992d7 graph+0x21f681
26 000000bf`b1b0f960 00007ff7`74582dd6 graph+0x292d7
27 000000bf`b1b0fb50 00007ff7`746ef602 graph+0x212dd6
28 000000bf`b1b0fc50 00007ffe`f0327c24 graph+0x37f602
29 000000bf`b1b0fc90 00007ffe`f18cd721 KERNEL32!BaseThreadInitThunk+0x14
2a 000000bf`b1b0fcc0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
0:000> r
rax=000002aaf902bdc0 rbx=0000000000112233 rcx=000000000010583b
rdx=fffffe14b8ad7848 rsi=000000bfb1b10000 rdi=000002aaf90387b8
rip=00007ffed65612de rsp=000000bfb1b03488 rbp=00000000ffff9f00
r8=0000000000112233 r9=000002aaf913e000 r10=000000bfb1b03608
r11=000002aaf902bdc0 r12=000002aaf902bdc0 r13=0000000000002020
r14=000000bfb1b03600 r15=000002aace7f0018
iopl=0 nv up ei pl nz na pe nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
VCRUNTIME140!memcpy_repmovs+0xe:
00007ffe`d65612de f3a4 rep movs byte ptr [rdi],byte ptr [rsi]
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-31178
https://research.checkpoint.com/2021/fuzzing-the-office-ecosystem/