Talos Vulnerability Report

TALOS-2019-0795

Aspose Aspose.Cells for C++ Number Code Execution Vulnerability

August 20, 2019
CVE Number

CVE-2019-5033

Summary

An exploitable out-of-bounds read vulnerability exists in the Number record parser of Aspose Aspose.Cells 19.1.0 library. A specially crafted XLS file can cause an out-of-bounds read, resulting in remote code execution. An attacker needs to provide a malformed file to the victim to trigger the vulnerability.

Tested Versions

Aspose Aspose.Cells for C++ 19.1.0

Product URLs

https://products.aspose.com/cells

CVSSv3 Score

9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

CWE

CWE-125: Out-of-bounds Read

Details

This vulnerability is present in the Aspose.Cells for C++ which is used for all kinds of operations related with XLS(X) files. Aspose.Cells library is used by many companies, banks, government organizations as a part of different software products responsible for data processing/conversion. There is a vulnerability in the function responsible for handling the Number record. A specially crafted XLS file can lead to an out-of-bounds read and remote code execution. Let's investigate this vulnerability. After we attempt to e.g convert the malicious XLS using the Aspose.Cells library to PDF we see the following state:

(4fd0.6b44): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for d:\projects\apose\cells\bin\Aspose.Cells.dll
eax=108a43e0 ebx=00000000 ecx=11525e54 edx=11525e54 esi=0ce48db0 edi=0cb300d0
eip=a364f445 esp=004ff3bc ebp=004ff418 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
a364f445 ??              ???

0:000> !address @eip


Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...
Address a364f445 could not be mapped in any of the available regions    

As we can see we landed at an address location which is not mapped at all, which can indicate that some function pointer or a return address has been corrupted. Because of that, the execution got redirected to that unmapped address. Moving back to the previous stack frame, we can see that our hypothesis is right.

1012fc87 8b4620       mov     eax, dword ptr [esi+20h]
1012fc8a 0fb755ec     movzx   edx, word ptr [ebp-14h]
1012fc8e 51           push    ecx
1012fc8f c645fc02     mov     byte ptr [ebp-4], 2
1012fc93 8b1490       mov     edx, dword ptr [eax+edx*4]
1012fc96 8bc4         mov     eax, esp
1012fc98 83c20c       add     edx, 0Ch
1012fc9b 8955d8       mov     dword ptr [ebp-28h], edx
1012fc9e 8908         mov     dword ptr [eax], ecx
1012fca0 85c9         test    ecx, ecx
1012fca2 7408         je      Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+0xed5c (1012fcac)
1012fca4 8b01         mov     eax, dword ptr [ecx]
1012fca6 ff5004       call    dword ptr [eax+4]
1012fca9 8b55d8       mov     edx, dword ptr [ebp-28h]
1012fcac 8b02         mov     eax, dword ptr [edx]
1012fcae 8bca         mov     ecx, edx
1012fcb0 ff5030       call    dword ptr [eax+30h]

0:000> kb
 # ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 004ff3b8 1012fcb3 0ca27ac0 18db51d7 0ca830c0 0xa364f445
01 004ff418 10125c2a 18db5107 0cb300d0 09ac8ac0 Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+0xed63
02 004ff4c8 107406ac 09ac8ac0 18db503b 0ce0c280 Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+0x4cda
03 004ff5f4 1073e49b 004ff620 0ce23d40 00000000 Aspose_Cells!Aspose::Cells::Drawing::Oval::`vbase destructor'+0x7f5c
04 004ff684 1102a478 18db520f 0a0412e0 0cb301b0 Aspose_Cells!Aspose::Cells::Drawing::Oval::`vbase destructor'+0x5d4b
05 004ff7c0 1102bc73 0c9e64c0 18db5dff 0c9e64c0 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x10658
06 004ff830 11039d61 0c9e64c0 18db5db3 09ba3740 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x11e53
07 004ff87c 1104829c 0cd94540 18db5c93 09ba3740 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x1ff41
08 004ff95c 11026448 0cd943f0 18db5c6f 0cd943f0 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x2e47c
09 004ff9a0 10e7b886 0cd943f0 18db5ee7 0a030700 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0xc628
0a 004ffb28 10e5f4e4 0a0306a0 09f71720 18db5eab Aspose_Cells!Aspose::Cells::Rendering::WorkbookRender::operator=+0xa3b6
0b 004ffb64 103b90a8 0a0306a0 18db5e6f 0a710f18 Aspose_Cells!Aspose::Cells::Workbook::Workbook+0x144
0c 004ffba0 001713ac 004ffc40 0a0306a0 00000000 Aspose_Cells!Aspose::Cells::Factory::CreateIWorkbook+0xe8
0d 004ffc58 00171e7d 00000003 0a710f18 0594cf48 Demo!main+0x25c [d:\downloads\aspose.total_for_c++\aspose.cells_for_c++_19.1.0\demo\main.cpp @ 29] 
0e (Inline) -------- -------- -------- -------- Demo!invoke_main+0x1c [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78] 
0f 004ffca0 77130179 003f3000 77130160 004ffd0c Demo!__scrt_common_main_seh+0xfa [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 
10 004ffcb0 7749662d 003f3000 4309b8b7 00000000 KERNEL32!BaseThreadInitThunk+0x19
11 004ffd0c 774965fd ffffffff 774b5186 00000000 ntdll!__RtlUserThreadStart+0x2f
12 004ffd1c 00000000 00171f05 003f3000 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> dx Debugger.Sessions[0].Processes[20432].Threads[27460].Stack.Frames[1].SwitchTo();dv /t /v
Debugger.Sessions[0].Processes[20432].Threads[27460].Stack.Frames[1].SwitchTo()
Unable to enumerate locals, Win32 error 0n318
Private symbols (symbols.pri) are required for locals.
Type ".hh dbgerr005" for details.
0:000> r
eax=108a43e0 ebx=00000000 ecx=11525e54 edx=11525e54 esi=0ce48db0 edi=0cb300d0
eip=a364f445 esp=004ff3bc ebp=004ff418 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
a364f445 ??              ???
0:000> dd eax+30 L1
108a4410  a364f445  

The eax register at address 1012fcb0 does not seem to point to a valid vftable. Tracking back the origin of the value of eax, we can see that it comes from an array 1012fc93. At address 1012fc93, the eax register points to a base address of this array and the edx register is an index. Both registers are initialized in the stub of code presented below.

1012fc87 8b4620       mov     eax, dword ptr [esi+20h]
1012fc8a 0fb755ec     movzx   edx, word ptr [ebp-14h]

Checking the edx value we get:

0:000> dw ebp-14h L1
004ff404  0022

Investigating a memory allocation for this array showed that the space allocated for it is the same: 0xC bytes, where each element in the array is 4 bytes.
This implies that the array only contains 3 elements, or at least that it's able to hold that amount of elements. By using an index of 0x22 we would read an element out of bounds, which is later used as a pointer to an object.
Applying this data to a file, a malformed index is located at an offset 0x1ACD1 being a part of Number record. An allocation made for 3 elements, results from the fact that there is three Number records inside SIIndex record at offset 0x1ACA1 with the size of 6 bytes.
Summarizing the analysis, we saw that the malformed array index value read directly from the file and used later without any sanitization can lead to the out of bounds read, that consequently can lead to remote code execution.

Crash Information

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


KEY_VALUES_STRING: 1

    Key  : AV.Fault
    Value: Execute

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

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


PROCESSES_ANALYSIS: 1

SERVICE_ANALYSIS: 1

STACKHASH_ANALYSIS: 1

TIMELINE_ANALYSIS: 1

Timeline: !analyze.Start
    Name: <blank>
    Time: 2019-03-22T10:58:37.132Z
    Diff: 132 mSec

Timeline: Dump.Current
    Name: <blank>
    Time: 2019-03-22T10:58:37.0Z
    Diff: 0 mSec

Timeline: Process.Start
    Name: <blank>
    Time: 2019-03-22T09:38:00.0Z
    Diff: 4837000 mSec

Timeline: OS.Boot
    Name: <blank>
    Time: 2019-03-11T07:04:09.0Z
    Diff: 964468000 mSec


DUMP_CLASS: 2

DUMP_QUALIFIER: 0

FAULTING_IP: 
+0
a364f445 ??              ???

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: a364f445
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000008
   Parameter[1]: a364f445
Attempt to execute non-executable address a364f445

FAULTING_THREAD:  00006b44

DEFAULT_BUCKET_ID:  SOFTWARE_NX_FAULT_AVRF

PROCESS_NAME:  Demo.exe

FOLLOWUP_IP: 
Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+ed63
1012fcb3 e9a6faffff      jmp     Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+0xe80e (1012f75e)

EXECUTE_ADDRESS: ffffffffa364f445

FAILED_INSTRUCTION_ADDRESS: 
+0
a364f445 ??              ???

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

EXCEPTION_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:  00000008

EXCEPTION_PARAMETER2:  a364f445

WATSON_BKT_PROCSTAMP:  5c927c6d

WATSON_BKT_MODULE:  unknown

WATSON_BKT_MODVER:  0.0.0.0

WATSON_BKT_MODOFFSET:  a364f445

WATSON_BKT_MODSTAMP:  bbbbbbb4

BUILD_VERSION_STRING:  17763.1.x86fre.rs5_release.180914-1434

MODLIST_WITH_TSCHKSUM_HASH:  3d2fd8ca83bc9cec8635ce2477174f7867854cb3

MODLIST_SHA1_HASH:  d398b29224a602bd9007248c5a929437c9653d17

NTGLOBALFLAG:  2100000

APPLICATION_VERIFIER_FLAGS:  0

PRODUCT_TYPE:  1

SUITE_MASK:  272

DUMP_TYPE:  fe

APPLICATION_VERIFIER_LOADED: 1

ANALYSIS_SESSION_HOST:  DESKTOP-E4N8506

ANALYSIS_SESSION_TIME:  03-22-2019 11:58:37.0132

ANALYSIS_VERSION: 10.0.18317.1001 x86fre

IP_ON_HEAP:  a364f445
The fault address in not in any loaded module, please check your build's rebase
log at <releasedir>\bin\build_logs\timebuild\ntrebase.log for module which may
contain the address if it were loaded.

IP_IN_RESERVED_BLOCK: ffffffffa364f445

THREAD_ATTRIBUTES: 
OS_LOCALE:  ENU

BUGCHECK_STR:  APPLICATION_FAULT_SOFTWARE_NX_FAULT_INVALID_POINTER_INVALID_POINTER_EXECUTE_AVRF

PRIMARY_PROBLEM_CLASS:  APPLICATION_FAULT

PROBLEM_CLASSES: 

    ID:     [0n313]
    Type:   [@ACCESS_VIOLATION]
    Class:  Addendum
    Scope:  BUCKET_ID
    Name:   Omit
    Data:   Omit
    PID:    [Unspecified]
    TID:    [0x6b44]
    Frame:  [0] : unknown!unknown

    ID:     [0n287]
    Type:   [INVALID_POINTER_EXECUTE]
    Class:  Primary
    Scope:  BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [Unspecified]
    TID:    [0x6b44]
    Frame:  [0] : unknown!unknown

    ID:     [0n295]
    Type:   [SOFTWARE_NX_FAULT]
    Class:  Primary
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [0x4fd0]
    TID:    [0x6b44]
    Frame:  [0] : unknown!unknown

    ID:     [0n293]
    Type:   [INVALID_POINTER]
    Class:  Primary
    Scope:  BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [0x4fd0]
    TID:    [0x6b44]
    Frame:  [0] : unknown!unknown

    ID:     [0n98]
    Type:   [AVRF]
    Class:  Addendum
    Scope:  DEFAULT_BUCKET_ID (Failure Bucket ID prefix)
            BUCKET_ID
    Name:   Add
    Data:   Omit
    PID:    [0x4fd0]
    TID:    [0x6b44]
    Frame:  [0] : unknown!unknown

LAST_CONTROL_TRANSFER:  from 1012fcb3 to a364f445

STACK_TEXT:  
WARNING: Frame IP not in any known module. Following frames may be wrong.
004ff3b8 1012fcb3 0ca27ac0 18db51d7 0ca830c0 0xa364f445
004ff418 10125c2a 18db5107 0cb300d0 09ac8ac0 Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+0xed63
004ff4c8 107406ac 09ac8ac0 18db503b 0ce0c280 Aspose_Cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+0x4cda
004ff5f4 1073e49b 004ff620 0ce23d40 00000000 Aspose_Cells!Aspose::Cells::Drawing::Oval::`vbase destructor'+0x7f5c
004ff684 1102a478 18db520f 0a0412e0 0cb301b0 Aspose_Cells!Aspose::Cells::Drawing::Oval::`vbase destructor'+0x5d4b
004ff7c0 1102bc73 0c9e64c0 18db5dff 0c9e64c0 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x10658
004ff830 11039d61 0c9e64c0 18db5db3 09ba3740 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x11e53
004ff87c 1104829c 0cd94540 18db5c93 09ba3740 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x1ff41
004ff95c 11026448 0cd943f0 18db5c6f 0cd943f0 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0x2e47c
004ff9a0 10e7b886 0cd943f0 18db5ee7 0a030700 Aspose_Cells!Aspose::Cells::Charts::Chart::GetCustomTable+0xc628
004ffb28 10e5f4e4 0a0306a0 09f71720 18db5eab Aspose_Cells!Aspose::Cells::Rendering::WorkbookRender::operator=+0xa3b6
004ffb64 103b90a8 0a0306a0 18db5e6f 0a710f18 Aspose_Cells!Aspose::Cells::Workbook::Workbook+0x144
004ffba0 001713ac 004ffc40 0a0306a0 00000000 Aspose_Cells!Aspose::Cells::Factory::CreateIWorkbook+0xe8
004ffc58 00171e7d 00000003 0a710f18 0594cf48 Demo!main+0x25c
004ffca0 77130179 003f3000 77130160 004ffd0c Demo!__scrt_common_main_seh+0xfa
004ffcb0 7749662d 003f3000 4309b8b7 00000000 KERNEL32!BaseThreadInitThunk+0x19
004ffd0c 774965fd ffffffff 774b5186 00000000 ntdll!__RtlUserThreadStart+0x2f
004ffd1c 00000000 00171f05 003f3000 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND:  ~0s ; .cxr ; kb

THREAD_SHA1_HASH_MOD_FUNC:  7c529cfc16ee16c77f35da19a90a17f8c6a4687f

THREAD_SHA1_HASH_MOD_FUNC_OFFSET:  710f375485e27738c1f9a3e265fb948f2164f070

THREAD_SHA1_HASH_MOD:  98b13f9225cec7f177621593927e3a391e21bac6

FAULT_INSTR_CODE:  fffaa6e9

SYMBOL_STACK_INDEX:  1

SYMBOL_NAME:  aspose_cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+ed63

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: Aspose_Cells

IMAGE_NAME:  Aspose.Cells.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  5c47fc12

FAILURE_BUCKET_ID:  SOFTWARE_NX_FAULT_AVRF_c0000005_Aspose.Cells.dll!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=

BUCKET_ID:  APPLICATION_FAULT_SOFTWARE_NX_FAULT_INVALID_POINTER_INVALID_POINTER_EXECUTE_AVRF_BAD_IP_aspose_cells!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=+ed63

FAILURE_EXCEPTION_CODE:  c0000005

FAILURE_IMAGE_NAME:  Aspose.Cells.dll

BUCKET_ID_IMAGE_STR:  Aspose.Cells.dll

FAILURE_MODULE_NAME:  Aspose_Cells

BUCKET_ID_MODULE_STR:  Aspose_Cells

FAILURE_FUNCTION_NAME:  Aspose::Cells::Drawing::MsoFillFormatHelper::operator=

BUCKET_ID_FUNCTION_STR:  Aspose::Cells::Drawing::MsoFillFormatHelper::operator=

BUCKET_ID_OFFSET:  ed63

BUCKET_ID_MODTIMEDATESTAMP:  5c47fc12

BUCKET_ID_MODCHECKSUM:  0

BUCKET_ID_MODVER_STR:  0.0.0.0

BUCKET_ID_PREFIX_STR:  APPLICATION_FAULT_SOFTWARE_NX_FAULT_INVALID_POINTER_INVALID_POINTER_EXECUTE_AVRF_BAD_IP_

FAILURE_PROBLEM_CLASS:  APPLICATION_FAULT

FAILURE_SYMBOL_NAME:  Aspose.Cells.dll!Aspose::Cells::Drawing::MsoFillFormatHelper::operator=

TARGET_TIME:  2019-03-22T10:58:51.000Z

OSBUILD:  17763

OSSERVICEPACK:  292

SERVICEPACK_NUMBER: 0

OS_REVISION: 0

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 10

OSEDITION:  Windows 10 WinNt SingleUserTS

USER_LCID:  0

OSBUILD_TIMESTAMP:  unknown_date

BUILDDATESTAMP_STR:  180914-1434

BUILDLAB_STR:  rs5_release

BUILDOSVER_STR:  10.0.17763.1.x86fre.rs5_release.180914-1434

ANALYSIS_SESSION_ELAPSED_TIME:  38b0

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:  um:software_nx_fault_avrf_c0000005_aspose.cells.dll!aspose::cells::drawing::msofillformathelper::operator=

FAILURE_ID_HASH:  {5252460a-1a1c-530e-969f-7a9bd2ccf4b7}

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

0:000> lmvDm Aspose.Cells.dll
Browse full module list
start    end        module name
0:000> lmvDm Aspose*
Browse full module list
start    end        module name
0fbb0000 11c03000   Aspose_Cells C (export symbols)       d:\projects\apose\cells\bin\Aspose.Cells.dll
    Loaded symbol image file: d:\projects\apose\cells\bin\Aspose.Cells.dll
    Image path: d:\projects\apose\cells\bin\Aspose.Cells.dll
    Image name: Aspose.Cells.dll
    Browse all global symbols  functions  data
    Timestamp:        Wed Jan 23 06:30:58 2019 (5C47FC12)
    CheckSum:         00000000
    ImageSize:        02053000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

Timeline

2019-04-17 - Vendor Disclosure
2019-08-20 - Public Disclosure
2019-08-24 - Vendor acknowledged & advised issues under review
2019-08-30 - Vendor patched

Credit

Discovered by Marcin 'Icewall' Noga of Cisco Talos.