Talos Vulnerability Report

TALOS-2019-0921

Accusoft ImageGear GEM Raster Code Execution Vulnerability

December 2, 2019
CVE Number

CVE-2019-5132

Summary

An exploitable out-of-bounds write vulnerability exists in the igcore19d.dll GEM Raster parser of the Accusoft ImageGear 19.3.0 library. A specially crafted GEM file can cause an out-of-bounds write, resulting in a remote code execution. An attacker needs to provide a malformed file to the victim to trigger the vulnerability.

Tested Versions

Accusoft ImageGear 19.3.0

Product URLs

https://www.accusoft.com/products/imagegear/overview/

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-787: Out-of-bounds Write

Details

The ImageGear library is a document imaging developer toolkit providing all kinds of functionality related to image conversion, creation, editing, annotation, etc. It supports more than 100 formats, including many image formats, DICOM, PDF, Microsoft Office and others. There is a vulnerability in the GEM raster image parser. A specially crafted GEM file can lead to an out-of-bounds write resulting in remote code execution.

File format documentation can be find here : http://www.fileformat.info/format/gemraster/spec/20e311cc16f844fda91beb539d62c46c/view.htm

If we try to load a malformed GEM file via the IG_load_file function we end up in the following situation:

0:000> g
(4478.3d88): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: 195929:0
eax=27ad0ff5 ebx=000003d2 ecx=0000006d edx=000000a3 esi=27ad0f88 edi=207bd000
eip=63b3df22 esp=003df1a4 ebp=003df1bc iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
MSVCR110!memcpy+0x2a:
63b3df22 f3a4            rep movs byte ptr es:[edi],byte ptr [esi]

The edi register points to the page with the PAGE_GUARD flag causing an access violation. Looking at the place where the exception appears in a form of pseudo-code it looks as follows:

Line 1 	int __cdecl sub_63D1A350(int a1, int a2, int a3, struct_a4 *a4, int a5)
Line 2 	{
Line 3 		(...)
Line 4 		counter = v20;
Line 5 		size_1 = a4->size;
Line 6 		do
Line 7 		{
Line 8 			memcpy(&dst_buffer + offset, src_buffer, size_1);
Line 9 			size_1 = a4->size;
Line 10			offset += size_1;
Line 11			--counter;
Line 12		}
Line 13		while ( counter );

As we can see in the above code, the memory copy operation takes place inside a while loop controlled by the counter variable.

Further analysis revealed that:

The dst_buffer buffer size depends on line width in pixels located at offset : 0xC with value 0x2020 [WORD] and the following formula : ` hex((( 1 * 0x2020 + 31) >> 3) & 0xFFFFFFFC)`

The src_buffer points to data starting at offset 0x14.

While size_1 represents the pattern length in bytes at offset 0x6. Current value : 0xA3.

The counter value also comes from the file at offset 0x12. Current value : 0x47.

As we can see an attacker controls all presented variables just by proper file content manipulation. Increasing loop count via counter variable an attacker can cause an out-of-bounds write leading to memory corruption which can result in remote code execution.

Crash Information

0:000> g
(4478.3d88): Access violation - code c0000005 (first/second chance not available)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
Time Travel Position: 195929:0
eax=27ad0ff5 ebx=000003d2 ecx=0000006d edx=000000a3 esi=27ad0f88 edi=207bd000
eip=63b3df22 esp=003df1a4 ebp=003df1bc iopl=0         nv up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000287
MSVCR110!memcpy+0x2a:
63b3df22 f3a4            rep movs byte ptr es:[edi],byte ptr [esi]
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


KEY_VALUES_STRING: 1

	Key  : AV.Fault
	Value: Write

	Key  : Analysis.CPU.Sec
	Value: 8

	Key  : Analysis.DebugAnalysisProvider.CPP
	Value: Create: 8007007e on ICELENOVO

	Key  : Analysis.DebugData
	Value: CreateObject

	Key  : Analysis.DebugModel
	Value: CreateObject

	Key  : Analysis.Elapsed.Sec
	Value: 32

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

	Key  : Analysis.System
	Value: CreateObject

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


APPLICATION_VERIFIER_LOADED: 1

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 63b3df22 (MSVCR110!memcpy+0x0000002a)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 207bd000
Attempt to write to address 207bd000

FAULTING_THREAD:  00003d88

PROCESS_NAME:  FuzzmeHeap.exe

WRITE_ADDRESS:  207bd000 

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:  207bd000

STACK_TEXT:  
003df1a8 63c20216 207bcfca 27ad0f52 000000a3 MSVCR110!memcpy+0x2a
WARNING: Stack unwind information not available. Following frames may be wrong.
003df1bc 63d1a5e3 207bcfca 27ad0f52 000000a3 igCore19d+0x10216
003df230 63d1acd4 003df744 1000001b 18e4eff8 igCore19d!IG_mpi_page_set+0x9ea83
003df270 63d1a2fd 003df744 1000001b 18e4eff8 igCore19d!IG_mpi_page_set+0x9f174
003df6bc 63c50ff9 003df744 18e4eff8 00000001 igCore19d!IG_mpi_page_set+0x9e79d
003df6f4 63c90437 00000000 18e4eff8 003df744 igCore19d!IG_image_savelist_get+0xb29
003df970 63c8fd99 00000000 18e12fc0 00000001 igCore19d!IG_mpi_page_set+0x148d7
003df990 63c26767 00000000 18e12fc0 00000001 igCore19d!IG_mpi_page_set+0x14239
003df9b0 007110af 18e12fc0 003df9c8 19a4cfb4 igCore19d!IG_load_file+0x47
003df9d0 00711252 18e12fc0 003dfa08 00000021 FuzzmeHeap!fuzzme+0x2f
003dfa30 00711d55 00000003 19a4cf70 160e7f50 FuzzmeHeap!fuzzme+0x1d2
003dfa78 756a6359 004f0000 756a6340 003dfae4 FuzzmeHeap!fuzzme+0xcd5
003dfa88 77dc7b74 004f0000 91d75531 00000000 KERNEL32!BaseThreadInitThunk+0x19
003dfae4 77dc7b44 ffffffff 77de8f15 00000000 ntdll!__RtlUserThreadStart+0x2f
003dfaf4 00000000 00711dcb 004f0000 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND:  ~0s ; .cxr ; kb

SYMBOL_NAME:  MSVCR110!memcpy+2a

MODULE_NAME: MSVCR110

IMAGE_NAME:  MSVCR110.dll

FAILURE_BUCKET_ID:  INVALID_POINTER_WRITE_AVRF_c0000005_MSVCR110.dll!memcpy

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 8

FAILURE_ID_HASH:  {80e9803c-2e1f-2683-6c9b-fae163af54bc}

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



0:000> lmv a rip
Browse full module list
start             end                 module name
00007fff`b8870000 00007fff`b8c83000   igCore19d   (export symbols)       igCore19d.dll
	Loaded symbol image file: igCore19d.dll
	Mapped memory image file: d:\projects\ImageGear\Build\Bin\x64\igCore19d.dll
	Image path: d:\projects\ImageGear\Build\Bin\x64\igCore19d.dll
	Image name: igCore19d.dll
	Browse all global symbols  functions  data
	Timestamp:        Tue Dec 11 16:32:31 2018 (5C101EDF)
	CheckSum:         0041928B
	ImageSize:        00413000
	File version:     19.3.0.0
	Product version:  19.3.0.0
	File flags:       0 (Mask 3F)
	File OS:          4 Unknown Win32
	File type:        2.0 Dll
	File date:        00000000.00000000
	Translations:     0409.04b0
	Information from resource tables:
		CompanyName:      Accusoft Corporation
		ProductName:      Accusoft ImageGear
		InternalName:     igcore19d.dll
		OriginalFilename: igcore19d.dll
		ProductVersion:   19.3.0.0
		FileVersion:      19.3.0.0
		FileDescription:  Accusoft ImageGear CORE DLL 
		LegalCopyright:   Copyright© 1996-2018 Accusoft Corporation. All rights reserved.
		LegalTrademarks:  ImageGearÆ and AccusoftÆ are registered trademarks of Accusoft Corporation

Timeline

2019-10-23 - Vendor Disclosure
2019-11-27 - Vendor Patched
2019-12-02 - Public Release

Credit

Discovered by Marcin Noga of Cisco Talos.