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 0x085A (Little-Endian short) the following logic occurs:

  1. The TLV record is copied to a stack buffer of 0x2020 at max, according to the TLV’s length.
  2. An additional length field (“element_count”) is parsed from the value at offset 0x06 (Little-Endian short).
  3. A heap buffer will be allocated to accommodate enough bytes for the wanted elements: 0x70 * element_count.
  4. A reverse-copy loop will copy DWORDS from the data buffer (on the stack) to the heap buffer, according to element_count.

Problem is, “element_count” isn’t checked to be smaller than the capacity of the stack buffer, causing an Out-of-Bound Read from the stack to the heap.

Stack trace:

0:000> k
00 graph+0xa22ab
01 graph+0xa8ae4
02 graph+0xd730
03 graph+0x20c9f
04 graph+0x1608b3
05 RPCRT4!Invoke+0x73
06 RPCRT4!NdrStubCall2+0x713
07 RPCRT4!NdrStubCall3+0xe3
08 combase!CStdStubBuffer_Invoke+0x5f [onecore\com\combase\ndr\ndrole\stub.cxx @ 1524] 
09 combase!InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_c9f3956a20c9da92a64affc24fdd69ec>::operator()+0x18 [onecore\com\combase\dcomrem\channelb.cxx @ 1385] 
0a combase!ObjectMethodExceptionHandlingAction<<lambda_c9f3956a20c9da92a64affc24fdd69ec> >+0x43 [onecore\com\combase\dcomrem\excepn.hxx @ 87] 
0b combase!InvokeStubWithExceptionPolicyAndTracing+0xa8 [onecore\com\combase\dcomrem\channelb.cxx @ 1383] 
0c combase!DefaultStubInvoke+0x1c3 [onecore\com\combase\dcomrem\channelb.cxx @ 1452] 
0d combase!SyncStubCall::Invoke+0x22 [onecore\com\combase\dcomrem\channelb.cxx @ 1509] 
0e combase!SyncServerCall::StubInvoke+0x26 [onecore\com\combase\dcomrem\servercall.hpp @ 826] 
0f combase!StubInvoke+0x259 [onecore\com\combase\dcomrem\channelb.cxx @ 1734] 
10 combase!ServerCall::ContextInvoke+0x42a [onecore\com\combase\dcomrem\ctxchnl.cxx @ 1418] 
11 combase!CServerChannel::ContextInvoke+0x79 [onecore\com\combase\dcomrem\ctxchnl.cxx @ 1327] 
12 combase!DefaultInvokeInApartment+0x92 [onecore\com\combase\dcomrem\callctrl.cxx @ 3352] 
13 combase!ReentrantSTAInvokeInApartment+0x19d [onecore\com\combase\dcomrem\reentrantsta.cpp @ 112] 
14 combase!AppInvoke+0x1ec [onecore\com\combase\dcomrem\channelb.cxx @ 1182] 
15 combase!ComInvokeWithLockAndIPID+0x681 [onecore\com\combase\dcomrem\channelb.cxx @ 2290] 
16 combase!ComInvoke+0x1ab [onecore\com\combase\dcomrem\channelb.cxx @ 1803] 
17 combase!ThreadDispatch+0x20a [onecore\com\combase\dcomrem\chancont.cxx @ 416] 
18 combase!ThreadWndProc+0x3ad [onecore\com\combase\dcomrem\chancont.cxx @ 744] 
19 USER32!UserCallWinProcCheckWow+0x2bd
1a USER32!DispatchMessageWorker+0x1e2
1b graph+0x21f681
1c graph+0x292d7
1d graph+0x212dd6
1e graph+0x37f602
1f KERNEL32!BaseThreadInitThunk+0x14
20 ntdll!RtlUserThreadStart+0x21

0:000> r
rax=000000000000000a rbx=00000000ffffffff rcx=000000000000b191
rdx=00000266693d6f20 rsi=0000000000000001 rdi=00000000ffffffff
rip=00007ff69d6b22ab rsp=000000ad0e8f6a00 rbp=000000ad0e8f8a60
 r8=000000ad0e92308e  r9=0000000000000000 r10=0000000000000000
r11=0000026668efc020 r12=0000000000000000 r13=0000000000000004
r14=000000ad0e8f6a40 r15=000000000000ffff
iopl=0         nv up ei pl nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
graph+0xa22ab:
00007ff6`9d6b22ab 410fb740fe      movzx   eax,word ptr [r8-2] ds:000000ad`0e92308c=????

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 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-31174
https://research.checkpoint.com/2021/fuzzing-the-office-ecosystem/