CVE-2019-5132
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.
Accusoft ImageGear 19.3.0
https://www.accusoft.com/products/imagegear/overview/
9.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE-787: Out-of-bounds Write
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.
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
2019-10-23 - Vendor Disclosure
2019-11-27 - Vendor Patched
2019-12-02 - Public Release
Discovered by Marcin Noga of Cisco Talos.