CVE-2018-3870
An exploitable out-of-bounds write exists in the PCX parsing functionality of Canvas Draw version 4.0.0. A specially crafted PCX image processed via the application can lead to an out-of-bounds write, overwriting arbitrary data. An attacker can deliver a PCX image to trigger this vulnerability and gain code execution.
ACDSystems Canvas Draw 4.0.0
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-787: Out-of-bounds Write
Canvas Draw 4 is a graphics editing tool used to create and edit images, as well as other graphic-related material. This product has a large user base, and is popular in its specific field. The vulnerable component is in the handling of PCX images. PCX was a popular image format with early computers, and although it has been replaced by more sophisticated formats, it is still in use and is fully supported inside of Canvas Draw.
The vulnerability arises in the parsing of the PCX image, specifically dealing with the compression of the image. The compression scheme is determined via the file header, and by choosing run length encoding as the compression, the program writes out of bounds using user-controlled data. The problem lies in the error-checking in the code. If there is an error present, the code path can be altered and allows user-controlled data to be accessed without validation. The initial crash is below.
* thread #1: tid = 0xb02b8d, 0x0000000101f8623b ImageGear18`IO_metad_item_get + 90, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
frame #0: 0x0000000101f8623b ImageGear18`IO_metad_item_get + 90
ImageGear18`IO_metad_item_get:
-> 0x101f8623b <+90>: jmp rax
0x101f8623d <+92>: add rsp, 0x8
0x101f86241 <+96>: pop rbx
0x101f86242 <+97>: pop r12
rax = 0x00a7a7a700a6a6a6
Looking further into the assembly, we can see where the RAX value has been set:
__text:0000000101F861FE mov r14, rdi [0]
...
__text:0000000101F86201 call _AF_error_check [1]
__text:0000000101F86206 test rax, rax
__text:0000000101F86209 jnz short loc_101F8623D
__text:0000000101F8620B mov rax, [r14+128h] [2]
At [1], there is a call to error check to see if the everything is OK and if this fails, returns a non-zero status: RAX is loaded with the value from R14 [2]. At the function prologue [0], RDI gets loaded into the R14 register. Checking the calling function, we can see the error:
__text:0000000101ED8BDE mov rdi, r13 [3]
__text:0000000101ED8BE1 mov esi, 1Fh
__text:0000000101ED8BE6 mov ecx, 1Fh
__text:0000000101ED8BEB mov r8d, 3
__text:0000000101ED8BF1 xor r9d, r9d
__text:0000000101ED8BF4 call _IO_metad_item_get [4]
The R13 value at location [3], is user-controlled and not verified to contain the expected structure. Therefore, when calling into the meta data function [4] an exploitable condition arises. The user data is accessed as if it was a struct
, and a function pointer is attempted to be called. This allows an attacker to leverage control and potentially gain code execution.
Crashed thread log =
: Dispatch queue: com.apple.main-thread
0 ImageGear18 0x000000010c0c523b IO_metad_item_get + 90
1 ImageGear18 0x000000010c017063 PCX_header_read + 175
2 ??? 0x003737370b363636 0 + 15541833269917238
log name is: ./crashlogs/1.crashlog.txt
---
exception=EXC_BAD_ACCESS:signal=11:is_exploitable=yes:instruction_disassembly=jmp *%eax:instruction_address=0x000000010c0c523b:access_type=exec:access_address=0x0000000000000000:
The exception code indicates that the access address was invalid in the 64-bit ABI (it was > 0x0000800000000000).
2018-04-03 - Vendor Disclosure
2018-07-19 - Public Release
Discovered by Tyler Bohan of Cisco Talos.