Talos Vulnerability Report

TALOS-2023-1734

Microsoft Office Excel WebCharts out-of-bounds write vulnerability

June 13, 2023
CVE Number

CVE-2023-33133

SUMMARY

An access violation vulnerability exists in the WebCharts functionality of Microsoft Office Excel 2019 Plus version 2302 build 16130.20332. A specially crafted malformed file can lead to a heap buffer overflow. An attacker can use arbitrary code execution to trigger this vulnerability.

CONFIRMED VULNERABLE VERSIONS

The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.

Microsoft Office Excel 2019 Plus version 2302 build 16130.20332

PRODUCT URLS

Office - https://products.office.com

CVSSv3 SCORE

7.8 - CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-787 - Out-of-bounds Write

DETAILS

Microsoft Office is a suite of tools used for productivity in both a corporate environment as well as by end-users. It offers a range of tools that can be used for various purposes. Such as Excel for spreadsheets, Word for document editing, Outlook for email, PowerPoint for presentations, etc.

Running Excel with our testcase and PageHeap turned on, we can observe the following crash information in windbg :

(1668.25c8): Access violation - code c0000005 (!!! second chance !!!)
eax=00000000 ebx=6d636fd0 ecx=0000009c edx=001d3204 esi=65dbcb50 edi=65dd3560
eip=668c398c esp=001ce588 ebp=001ce5c8 iopl=0         nv up ei pl nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210203
VCRUNTIME140!memset+0x3c:
668c398c f3aa            rep stos byte ptr es:[edi]

0:000> kb
ChildEBP RetAddr  Args to Child              
00 001ce584 008a6439 65dd3560 00000000 0000009c VCRUNTIME140!memset+0x3c [D:\a\_work\1\s\src\vctools\crt\vcruntime\src\string\i386\memset.asm @ 86] 
01 001ce598 00891920 001cebec 00000000 663dc998 Excel!HrInitHtmlWebChart+0x3b1
02 001ce5a8 008a629b 001cebec 663dc998 07f17fd8 Excel!FCommitChartXmlLegendEntry+0x369
03 001ce5c8 020d7c20 000003df 001ce648 663dc998 Excel!HrCommitHtmlChartXml+0x4f7
04 001ce69c 00ba8cd8 00000000 001ce708 5a36a279 Excel!FProcessXmlItem+0x918
05 001ce6a8 5a36a279 02f03eec 001ceb98 663dc998 Excel!OHIU::FProcessXmlItem+0x10
06 001ce708 5a44c21d 013dc998 0000009a 663dc998 mso!FDispatchXmlItem+0x191
07 001ce74c 5a62300b 00002b08 0000009a ffffffff mso!FFlushXmlStack+0xd7
08 001ce770 5a2528db 663dc998 00000001 25329cb2 mso!`Microsoft::AugLoop::LocalWorkflows::TextPrediction::SimpleJsonReader::TryGetInt<unsigned int>'::`2'::`dynamic atexit destructor for 'regexDecimal''+0xe5ac3
09 001ce940 5a251431 25329c9a 001ceb98 07f17fd8 mso!TkLexHtml+0x11ab
0a 001ce968 5a251233 66300d14 00000000 07f17fd8 mso!HI::FDoImportCopyContent+0x1eb
0b 001ce97c 00ba019e 663dc918 07f17fd8 00000000 mso!HI::FDoImport+0x19
0c 001ceaa8 0186cd04 00000100 47d14fa8 00000003 Excel!HrLoadSheetHtml+0x425
0d 001d940c 020d9a40 00000000 00000000 00000000 Excel!HrBookLoadHtmlSinglePly+0x4c2
0e 001d9450 007620a6 001e8ae8 47d14fa8 00000002 Excel!HrLoadBookHtml+0xe4
0f 001e8f1c 007476d6 00000000 00000000 00000002 Excel!HrFileLoadEx+0x6af6
10 001e8fa8 01a891fb 00000000 00000000 00000002 Excel!FFileLoadWithCoauth+0x72
11 001e8ffc 01662a8e 00000000 02823042 001e9024 Excel!FFileLoadWithCoauth+0x45
12 001e90f8 016627f3 00000001 00001008 00000001 Excel!_HrLoadInternal+0x193
13 001e91a0 0056ebeb 00000001 00001008 00000001 Excel!_HrLoad+0xd1
14 001edef8 0056d344 0000000f 4784bfb0 00000825 Excel!FStartupFilename+0x1970
15 001edf9c 02415174 0000000f 4784bfb0 00000825 Excel!FLoadCmdLine+0x99
16 001eeb14 005c18d3 00000825 00000000 00000001 Excel!MergeInstance::ExecuteMergeInstance+0xdd
17 001eebc0 005b606c 07f17fd8 07f17fd8 00000000 Excel!DelayedMergeInstance::FProcessRequest+0x110
18 001ef0e8 005b44b6 07f17fd8 02ecbcf8 00000001 Excel!FDoIdleHardRejectUi+0x1c74
19 001ef168 005b083e 62ee2f65 02ecbed0 00000000 Excel!FDoIdle+0x9d
1a 001ef568 005455f4 00000000 0000000a 00365000 Excel!MainLoop+0x1335
1b 001ef79c 005311c3 00530000 00000000 07f35faa Excel!WinMain+0x6fe
1c 001ef7e8 761cfa29 00365000 761cfa10 001ef854 Excel!_imp_load__RmGetList+0x1c7
1d 001ef7f8 772b7a4e 00365000 f8853620 00000000 KERNEL32!BaseThreadInitThunk+0x19
1e 001ef854 772b7a1e ffffffff 772d890b 00000000 ntdll!__RtlUserThreadStart+0x2f
1f 001ef864 00000000 00531079 00365000 00000000 ntdll!_RtlUserThreadStart+0x1b

It seems that there is an attempt to “memset the data” out of the bounds of some array. Going one stack frame up and using pseudo-code, the situation looks as follows:

Line 1 	int __thiscall sub_7762EE(struct_xmlElement *rootXML)
Line 2 	{
Line 3 	  int index; // eax
Line 4 
Line 5 	  index = rootXML->someIndex;
Line 6 	  if ( index >= 0 )
Line 7 	  {
Line 8 		  memset(&rootXML->webCharts[156 * index], 0, 156u);
Line 9 		--rootXML->someIndex;
Line 10	  }
Line 11	  return index;
Line 12	}

It seems that the root cause of the out-of-bounds write is related to the index value (in our case, equal to 0x4d) used in line 8, which is not compared in any way with the actual size of the webCharts array. Let us check allocated space for rootXML (the webCharts array is an inline array) on the heap:

0:000> .frame /c 1
01 001ce598 00891920 Excel!HrInitHtmlWebChart+0x3b1
eax=00000000 ebx=6d636fd0 ecx=0000009c edx=001d3204 esi=65dbcb50 edi=65dd3560
eip=008a6439 esp=001ce58c ebp=001ce5c8 iopl=0         nv up ei pl nz na po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210203
Excel!HrInitHtmlWebChart+0x3b1:
008a6439 83c40c          add     esp,0Ch
0:000> !heap -p -a 65dbcb50 
    address 65dbcb50 found in
    _DPH_HEAP_ROOT @ 7ee1000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                5f6924e0:         65dbcb50            144b0 -         65dbc000            16000
    667ba8b0 verifier!AVrfDebugPageHeapAllocate+0x00000240
    7732ef3e ntdll!RtlDebugAllocateHeap+0x00000039
    77297080 ntdll!RtlpAllocateHeap+0x000000f0
    77296ddc ntdll!RtlpAllocateHeapInternal+0x0000104c
    77295d7e ntdll!RtlAllocateHeap+0x0000003e
    62edbd80 mso20win32client!Mso::Memory::AllocateEx+0x00000025
    005464dd Excel!FHpAllocCore+0x0000002c
    020f818b Excel!HrInitCHISD2+0x00000039
    020f885f Excel!HrInitHtmlWebChart+0x000000a0
    00a6b17b Excel!FInitSheetXml+0x00000724
    0186f433 Excel!HrInitBookXml+0x00000275
    020d7d51 Excel!FProcessXmlItem+0x00000a4c
    00ba8cd8 Excel!OHIU::FProcessXmlItem+0x00000010
    5a36a279 mso!FDispatchXmlItem+0x00000191
    5a254de2 mso!FProcessCloseXmlTag+0x000001c8
    5a251f18 mso!TkLexHtml+0x000007e8
    5a251431 mso!HI::FDoImportCopyContent+0x000001eb
    5a251233 mso!HI::FDoImport+0x00000019
    00ba019e Excel!HrLoadSheetHtml+0x00000425
    0186cd04 Excel!HrBookLoadHtmlSinglePly+0x000004c2
    020d9a40 Excel!HrLoadBookHtml+0x000000e4
    007620a6 Excel!HrFileLoadEx+0x00006af6
    007476d6 Excel!FFileLoadWithCoauth+0x00000072
    01a891fb Excel!FFileLoadWithCoauth+0x00000045
    01662a8e Excel!_HrLoadInternal+0x00000193
    016627f3 Excel!_HrLoad+0x000000d1
    0056ebeb Excel!FStartupFilename+0x00001970
    0056d344 Excel!FLoadCmdLine+0x00000099
    02415174 Excel!MergeInstance::ExecuteMergeInstance+0x000000dd
    005c18d3 Excel!DelayedMergeInstance::FProcessRequest+0x00000110
    005b606c Excel!FDoIdleHardRejectUi+0x00001c74
    005b44b6 Excel!FDoIdle+0x0000009d

Looking at heap values, the address of the webCharts array element should not be larger than > ( 65dbcb50 + 144b0 ) = 0x65dd1000. However, looking at the edi value at the moment of the crash 65dd3560, we can clearly see that indeed the index points to addresses far away from the end of array. Investigation of code where the allocation for xmlRoot took place tells us even more about the core of the problem here:

Line 1 	int __fastcall HrInitCHISD2(PBYTE a1, _DWORD *a2)
Line 2 	{
Line 3
Line 4	  rootXML = a1 + 17944;
Line 5	  if ( FHpAllocCore((Mso::Memory *)0x144B0, rootXML, (void **)1) )
            (...)

The allocation is made for a FIXED size memory 0x144B0. This means that the webCharts array always has slots for a max of 14 elements. We can calculate it from this code:

.text:007762EE ; int __thiscall sub_7762EE(struct_xmlElement *rootXML)
.text:007762EE sub_7762EE      proc near               ; CODE XREF: sub_758E58:loc_759063↑p
.text:007762EE                                         ; sub_759B30:loc_759CF1↑p ...
.text:007762EE                 push    esi
.text:007762EF                 mov     esi, ecx
.text:007762F1                 mov     eax, [esi+1413Ch]
.text:007762F7                 test    eax, eax
.text:007762F9                 js      short loc_77631E
.text:007762FB                 imul    eax, 9Ch
.text:00776301                 push    9Ch             ; Size
.text:00776306                 push    0               ; Val
.text:00776308                 add     eax, 13B24h
.text:0077630D                 add     eax, esi
.text:0077630F                 push    eax             ; void *
.text:00776310                 call    _memset


esi                                      = 0x65dbcb50
webCharts element size    = 9Ch 
xmlRoot end 		       = 0x65dd1000
webCharts beg = 0x65dbcb50 + 0x13B24= 0x65dd0674
webCharts potential space = 0x65dd1000 - 0x65dd0674 = 0x98c
webCharts max elements   = 0x98c / 0x9C = 0xf 

Our testcase contains 0x4d ( 77 ) embedded WebCharts elements, which significantly exceeds the acceptable amount. An attacker controlling the amount of WebChart elements might control the index for the webCharts table, and in that way achieve a precise out-of-bounds write primitive. With a proper heap grooming, this might lead to arbitrary write and finally to arbitrary code execution.

Crash Information

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


KEY_VALUES_STRING: 1

    Key  : AV.Fault
    Value: Write

    Key  : Analysis.CPU.Sec
    Value: 5

    Key  : Analysis.DebugAnalysisProvider.CPP
    Value: Create: 8007007e on DESKTOP-Q1N26JM

    Key  : Analysis.DebugData
    Value: CreateObject

    Key  : Analysis.DebugModel
    Value: CreateObject

    Key  : Analysis.Elapsed.Sec
    Value: 129

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 472

    Key  : Analysis.System
    Value: CreateObject

    Key  : Timeline.OS.Boot.DeltaSec
    Value: 148240

    Key  : Timeline.Process.Start.DeltaSec
    Value: 15093


NTGLOBALFLAG:  2000000

PROCESS_BAM_CURRENT_THROTTLED: 0

PROCESS_BAM_PREVIOUS_THROTTLED: 0

APPLICATION_VERIFIER_FLAGS:  0

APPLICATION_VERIFIER_LOADED: 1

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 668c398c (VCRUNTIME140!memset+0x0000003c)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 65dd3560
Attempt to write to address 65dd3560

FAULTING_THREAD:  000025c8

PROCESS_NAME:  Excel.exe

WRITE_ADDRESS:  65dd3560 

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  00000001

EXCEPTION_PARAMETER2:  65dd3560

STACK_TEXT:  
001ce584 008a6439 65dd3560 00000000 0000009c VCRUNTIME140!memset+0x3c
001ce598 00891920 001cebec 00000000 663dc998 Excel!HrInitHtmlWebChart+0x3b1
001ce5a8 008a629b 001cebec 663dc998 07f17fd8 Excel!FCommitChartXmlLegendEntry+0x369
001ce5c8 020d7c20 000003df 001ce648 663dc998 Excel!HrCommitHtmlChartXml+0x4f7
001ce69c 00ba8cd8 00000000 001ce708 5a36a279 Excel!FProcessXmlItem+0x918
001ce6a8 5a36a279 02f03eec 001ceb98 663dc998 Excel!OHIU::FProcessXmlItem+0x10
001ce708 5a44c21d 013dc998 0000009a 663dc998 mso!FDispatchXmlItem+0x191
001ce74c 5a62300b 00002b08 0000009a ffffffff mso!FFlushXmlStack+0xd7
001ce770 5a2528db 663dc998 00000001 25329cb2 mso!`Microsoft::AugLoop::LocalWorkflows::TextPrediction::SimpleJsonReader::TryGetInt<unsigned int>'::`2'::`dynamic atexit destructor for 'regexDecimal''+0xe5ac3
001ce940 5a251431 25329c9a 001ceb98 07f17fd8 mso!TkLexHtml+0x11ab
001ce968 5a251233 66300d14 00000000 07f17fd8 mso!HI::FDoImportCopyContent+0x1eb
001ce97c 00ba019e 663dc918 07f17fd8 00000000 mso!HI::FDoImport+0x19
001ceaa8 0186cd04 00000100 47d14fa8 00000003 Excel!HrLoadSheetHtml+0x425
001d940c 020d9a40 00000000 00000000 00000000 Excel!HrBookLoadHtmlSinglePly+0x4c2
001d9450 007620a6 001e8ae8 47d14fa8 00000002 Excel!HrLoadBookHtml+0xe4
001e8f1c 007476d6 00000000 00000000 00000002 Excel!HrFileLoadEx+0x6af6
001e8fa8 01a891fb 00000000 00000000 00000002 Excel!FFileLoadWithCoauth+0x72
001e8ffc 01662a8e 00000000 02823042 001e9024 Excel!FFileLoadWithCoauth+0x45
001e90f8 016627f3 00000001 00001008 00000001 Excel!_HrLoadInternal+0x193
001e91a0 0056ebeb 00000001 00001008 00000001 Excel!_HrLoad+0xd1
001edef8 0056d344 0000000f 4784bfb0 00000825 Excel!FStartupFilename+0x1970
001edf9c 02415174 0000000f 4784bfb0 00000825 Excel!FLoadCmdLine+0x99
001eeb14 005c18d3 00000825 00000000 00000001 Excel!MergeInstance::ExecuteMergeInstance+0xdd
001eebc0 005b606c 07f17fd8 07f17fd8 00000000 Excel!DelayedMergeInstance::FProcessRequest+0x110
001ef0e8 005b44b6 07f17fd8 02ecbcf8 00000001 Excel!FDoIdleHardRejectUi+0x1c74
001ef168 005b083e 62ee2f65 02ecbed0 00000000 Excel!FDoIdle+0x9d
001ef568 005455f4 00000000 0000000a 00365000 Excel!MainLoop+0x1335
001ef79c 005311c3 00530000 00000000 07f35faa Excel!WinMain+0x6fe
001ef7e8 761cfa29 00365000 761cfa10 001ef854 Excel!_imp_load__RmGetList+0x1c7
001ef7f8 772b7a4e 00365000 f8853620 00000000 KERNEL32!BaseThreadInitThunk+0x19
001ef854 772b7a1e ffffffff 772d890b 00000000 ntdll!__RtlUserThreadStart+0x2f
001ef864 00000000 00531079 00365000 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND:  ~0s ; .cxr ; kb

FAULTING_SOURCE_LINE:  D:\a\_work\1\s\src\vctools\crt\vcruntime\src\string\i386\memset.asm

FAULTING_SOURCE_FILE:  D:\a\_work\1\s\src\vctools\crt\vcruntime\src\string\i386\memset.asm

FAULTING_SOURCE_LINE_NUMBER:  86

SYMBOL_NAME:  VCRUNTIME140!memset+3c

MODULE_NAME: VCRUNTIME140

IMAGE_NAME:  VCRUNTIME140.dll

FAILURE_BUCKET_ID:  INVALID_POINTER_WRITE_AVRF_c0000005_VCRUNTIME140.dll!memset

OS_VERSION:  10.0.19041.1

BUILDLAB_STR:  vb_release

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 10

FAILURE_ID_HASH:  {026bf0da-38f7-e264-68be-a7a8bf3d1cc0}

Followup:     MachineOwner
---------


0:000> lmvm excel
Browse full module list
start    end        module name
00530000 0362d000   Excel      (pdb symbols)          c:\tools\x86\sym\excel.pdb\9DB19F7CA6E749AD89E8B3563E50ADD92\excel.pdb
    Loaded symbol image file: c:\Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE
    Image path: Excel.exe
    Image name: Excel.exe
    Browse all global symbols  functions  data
    Timestamp:        Thu Mar 16 20:01:23 2023 (6413D803)
    CheckSum:         030F8B98
    ImageSize:        030FD000
    File version:     16.0.16130.20332
    Product version:  16.0.16130.20332
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        1.0 App
    File date:        00000000.00000000
    Translations:     0000.04e4
    Information from resource tables:
        CompanyName:      Microsoft Corporation
        ProductName:      Microsoft Office
        InternalName:     Excel
        OriginalFilename: Excel.exe
        ProductVersion:   16.0.16130.20332
        FileVersion:      16.0.16130.20332
        FileDescription:  Microsoft Excel
TIMELINE

2023-03-29 - Vendor Disclosure
2023-06-13 - Vendor Patch Release
2023-06-13 - Public Release

Credit

Discovered by Marcin 'Icewall' Noga of Cisco Talos.