Talos Vulnerability Report

TALOS-2023-1802

Accusoft ImageGear dcm_pixel_data_decode out-of-bounds write vulnerability

September 25, 2023
CVE Number

CVE-2023-32653

SUMMARY

An out-of-bounds write vulnerability exists in the dcm_pixel_data_decode functionality of Accusoft ImageGear 20.1. A specially crafted malformed file can lead to arbitrary code execution. A victim would need to open a malicious file 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.

Accusoft ImageGear 20.1

PRODUCT URLS

ImageGear - https://www.accusoft.com/products/imagegear-collection/

CVSSv3 SCORE

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

CWE

CWE-191 - Integer Underflow (Wrap or Wraparound)

DETAILS

The ImageGear library is a document-imaging developer toolkit that offers image conversion, creation, editing, annotation and more. It supports more than 100 formats such as DICOM, PDF, Microsoft Office and others.

Trying to load a malformed Dicom, we end up in the following situation:

eax=00004000 ebx=00000008 ecx=00000000 edx=00000000 esi=ffffcfdf edi=136b1000
eip=75059a65 esp=0019fa50 ebp=0019fad0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
igMED20d!CPb_MED_init+0x169c5:
75059a65 897cb58c        mov     dword ptr [ebp+esi*4-74h],edi ss:002b:001939d8=????????

The crash happens in LINE16 below in a function identified as dcm_pixel_data_decode:

LINE1  8b45ec             mov     eax, dword [ebp-0x14 {l_value}]
LINE2  68db100000         push    0x10db {var_88_3}
LINE3  0fb700             movzx   eax, word [eax]
LINE4  68a0c40775         push    data_7507c4a0 {var_8c_3}{"..\..\..\..\Common\Components\ME…"}
LINE5  57                 push    edi {var_90_3}
LINE6  be0f000000         mov     esi, 0xf
LINE7  6a00               push    0x0 {ptr_var34}
LINE8  2bf0               sub     esi, eax
LINE9  ff15c0130b75       call    dword [AF_memm_alloc]
LINE10 8bf8               mov     edi, eax
LINE11 8b45e4             mov     eax, dword [ebp-0x1c {l_buffer_size_1}]
LINE12 99                 cdq     
LINE13 2bc2               sub     eax, edx
LINE14 d1f8               sar     eax, 0x1
LINE15 33c9               xor     ecx, ecx  {0x0}
LINE16 897cb58c           mov     dword [ebp+esi*4-0x74 {obj_str_sz_0x40}], edi
LINE17 85c0               test    eax, eax
LINE18 7e0e               jle     0x75059a7b

The register esi is a very big value, as result of an integer underflow. We can see at LINE6, it was set to a constant 0xf and subtracted by the register eax LINE8.
There is no check on the value of register eax, causing the very large number. eax gets its value at LINE1, which is under our control into the malformed file.
At LINE16 we can influence the stack pointer ebp with esi, as that depends on the content of the file, which means we can choose where in the stack to write edi. The value pointed by the register edi is a result of AF_memm_alloc, which is some kind of wrapper of malloc.

By controlling the eax register an attacker can overwrite anywhere in the stack, possibly leading to code execution.

Crash Information

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

Unable to load image E:\ImageGearFuzzing\bin\igCore20d.dll, Win32 error 0n2

KEY_VALUES_STRING: 1

    Key  : AV.Fault
    Value: Write

    Key  : Analysis.CPU.mSec
    Value: 375

    Key  : Analysis.Elapsed.mSec
    Value: 2704

    Key  : Analysis.IO.Other.Mb
    Value: 0

    Key  : Analysis.IO.Read.Mb
    Value: 0

    Key  : Analysis.IO.Write.Mb
    Value: 0

    Key  : Analysis.Init.CPU.mSec
    Value: 4061

    Key  : Analysis.Init.Elapsed.mSec
    Value: 65613

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

    Key  : Failure.Bucket
    Value: INVALID_POINTER_WRITE_AVRF_c0000005_igMED20d.dll!Unknown

    Key  : Failure.Hash
    Value: {7bd32a5f-d13c-5070-0693-11be1df9b256}

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

    Key  : WER.Process.Version
    Value: 1.0.1.1


NTGLOBALFLAG:  2100000

APPLICATION_VERIFIER_FLAGS:  0

APPLICATION_VERIFIER_LOADED: 1

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 75059a65 (igMED20d!CPb_MED_init+0x000169c5)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 001939d8
Attempt to write to address 001939d8

FAULTING_THREAD:  00001a78

PROCESS_NAME:  Fuzzme.exe

WRITE_ADDRESS:  001939d8 

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:  001939d8

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
0019fad0 750592f0     0019fc3c 10694fa0 1000001e igMED20d!CPb_MED_init+0x169c5
0019fb04 750567e0     0019fc3c 10694fa0 1000001e igMED20d!CPb_MED_init+0x16250
0019fbb4 755a15b9     0019fc3c 10680fb8 00000001 igMED20d!CPb_MED_init+0x13740
0019fbec 755e08bc     00000000 10680fb8 0019fc3c igCore20d!IG_image_savelist_get+0xb29
0019fe68 755e0239     00000000 05c26fd0 00000001 igCore20d!IG_mpi_page_set+0x1479c
0019fe88 75575bc7     00000000 05c26fd0 00000001 igCore20d!IG_mpi_page_set+0x14119
0019fea8 00402399     05c26fd0 0019febc 75c6fb80 igCore20d!IG_load_file+0x47
0019fec0 004026c0     05c26fd0 05c28fe0 05b8cf50 Fuzzme!fuzzme+0x19
0019ff28 00408407     00000005 05b86f78 05b8cf50 Fuzzme!fuzzme+0x340
0019ff70 75c700c9     002d4000 75c700b0 0019ffdc Fuzzme!fuzzme+0x6087
0019ff80 77cc7b4e     002d4000 65bf4f61 00000000 KERNEL32!BaseThreadInitThunk+0x19
0019ffdc 77cc7b1e     ffffffff 77ce8c7f 00000000 ntdll!__RtlUserThreadStart+0x2f
0019ffec 00000000     0040848f 002d4000 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND:  ~0s ; .cxr ; kb

SYMBOL_NAME:  igMED20d+169c5

MODULE_NAME: igMED20d

IMAGE_NAME:  igMED20d.dll

FAILURE_BUCKET_ID:  INVALID_POINTER_WRITE_AVRF_c0000005_igMED20d.dll!Unknown

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 8

IMAGE_VERSION:  20.1.0.117

FAILURE_ID_HASH:  {7bd32a5f-d13c-5070-0693-11be1df9b256}

Followup:     MachineOwner
---------
VENDOR RESPONSE

Release notes from the vendor can be found here:

https://help.accusoft.com/ImageGear/v20.3/Windows/DLL/webframe.html#release-notes.html

https://help.accusoft.com/ImageGear/v20.3/Linux/webframe.html#release-notes.html

TIMELINE

2023-07-18 - Vendor Disclosure
2023-09-20 - Vendor Patch Release
2023-09-25 - Public Release

Credit

Discovered by Emmanuel Tacheau of Cisco Talos.