Talos Vulnerability Report

TALOS-2023-1742

Accusoft ImageGear tif_processing_dng_channel_count stack-based buffer overflow vulnerability

September 25, 2023
CVE Number

CVE-2023-28393

SUMMARY

A stack-based buffer overflow vulnerability exists in the tif_processing_dng_channel_count functionality of Accusoft ImageGear 20.1. A specially crafted malformed file can lead to memory corruption. An attacker can provide 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

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

CWE

CWE-121 - Stack-based Buffer Overflow

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.

A specially crafted TIFF file can lead to a stack-based buffer overflow in tif_processing_dng_channel_count, due to a missing bounds check.

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

(c74.ec0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000010 ebx=0ec9efe0 ecx=000003c8 edx=0ec9e000 esi=0ec9efe0 edi=001a0000
eip=6f579a03 esp=0019faf4 ebp=0019fb34 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
igCore20d!IG_mpi_page_set+0x2d8e3:
6f579a03 f3ab            rep stos dword ptr es:[edi]

As we can see below the stack is overwritten with some constant value 0x10:

0:000> kb
 # ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0019fb34 00000000 00000010 00000010 00000010 igCore20d!IG_mpi_page_set+0x2d8e3

The crash is happening in the function tif_processing_dng_channel_count with the following pseudo code at LINE36:

LINE1   dword tif_processing_dng_channel_count
LINE2                   (HIGEAR higear,int param_2,int param_3,int *param_4,int param_5)
LINE3   {
LINE4     int max_loop;
LINE5     double *pdVar1;
LINE6     int iVar2;
LINE7     uint uVar3;
LINE8     dword dVar4;
LINE9     int iVar5;
LINE10    int iVar6;
LINE11    short *psVar7;
LINE12    void **ppvVar8;
LINE13    int iVar9;
LINE14    int iVar10;
LINE15    AT_INT *p_loc_at_int;
LINE16    double dVar11;
LINE17    double dVar13;
LINE18    int local_28;
LINE19    int local_24;
LINE20    int local_20;
LINE21    void **local_1c;
LINE22    AT_INT _local_at_int [2];
LINE23    double local_10;
LINE24    uint local_8;
LINE25    undefined auVar12 [16];
LINE26    
LINE27    local_8 = DAT_10319e74 ^ (uint)&stack0xfffffffc;
LINE28    max_loop = get_channel_count(higear);
LINE29    local_1c = (void **)0x0;
LINE30    _local_at_int[0] = 0;
LINE31    _local_at_int[1] = 0;
LINE32    local_10 = 0.0;
LINE33    if (0 < max_loop) {
LINE34      p_loc_at_int = _local_at_int;
LINE35      for (iVar5 = max_loop; iVar5 != 0; iVar5 = iVar5 + -1) {
LINE36        *p_loc_at_int = 0x10;
LINE37        p_loc_at_int = p_loc_at_int + 1;
LINE38      }
LINE39    }
LINE40    iIG_image_channel_depths_change(higear,_local_at_int,1);
    [...]
LINE148 }

This is a for loop with a bound size controlled by the variable max_loop LINE35. The pointer p_loc_at_int is pointing to a stack variable _local_at_int, which is a table of two integers.
The max_loop is returned by the function get_channel_count LINE28, which is a wrapper, and returns a value directly read and controlled from the file. This can happen under specific circumstances with some malformed tags BitsPerSample, the max_loop corresponds to the SamplesPerPixel value. The presence of some other tags like DNGVersion and SubIFDs is a prerequisite to make this happen.
As the loop is arbitrarily controlled and has no bounds checks, the command at LINE36 would write out-of-bounds on the stack, leading to memory corruption.

Crash Information

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

*** WARNING: Unable to verify checksum for Fuzzme.exe

KEY_VALUES_STRING: 1

    Key  : AV.Fault
    Value: Write

    Key  : Analysis.CPU.Sec
    Value: 1

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

    Key  : Analysis.DebugData
    Value: CreateObject

    Key  : Analysis.DebugModel
    Value: CreateObject

    Key  : Analysis.Elapsed.Sec
    Value: 1

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

    Key  : Analysis.System
    Value: CreateObject

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

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


NTGLOBALFLAG:  2100000

PROCESS_BAM_CURRENT_THROTTLED: 0

PROCESS_BAM_PREVIOUS_THROTTLED: 0

APPLICATION_VERIFIER_FLAGS:  0

APPLICATION_VERIFIER_LOADED: 1

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 6f579a03 (igCore20d!IG_mpi_page_set+0x0002d8e3)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 001a0000
Attempt to write to address 001a0000

FAULTING_THREAD:  00000ec0

PROCESS_NAME:  Fuzzme.exe

WRITE_ADDRESS:  001a0000 

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:  001a0000

STACK_TEXT:  
0019fb34 00000000 00000010 00000010 00000010 igCore20d!IG_mpi_page_set+0x2d8e3


STACK_COMMAND:  ~0s ; .cxr ; kb

SYMBOL_NAME:  igCore20d!IG_mpi_page_set+2d8e3

MODULE_NAME: igCore20d

IMAGE_NAME:  igCore20d.dll

FAILURE_BUCKET_ID:  INVALID_POINTER_WRITE_AVRF_c0000005_igCore20d.dll!IG_mpi_page_set

OS_VERSION:  10.0.19041.1

BUILDLAB_STR:  vb_release

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 10

FAILURE_ID_HASH:  {fe8f80f8-683f-d41f-7c33-712a409d5fb5}

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-04-20 - Vendor Disclosure
2023-09-20 - Vendor Patch Release
2023-09-25 - Public Release

Credit

Discovered by Emmanuel Tacheau of Cisco Talos.