Talos Vulnerability Report

TALOS-2018-0553

ACD Systems Canvas Draw 4 Invert Map Out-of-Bounds Write Code Execution Vulnerability

July 19, 2018
CVE Number

CVE-2018-3871

Summary

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.

Tested Versions

ACDSystems Canvas Draw 4.0.0

Product URLs

https://www.pl32.com/

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-787: Out-of-bounds Write

Details

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 has been replaced by more sophisticated formats, it is still in use and fully supported inside of Canvas Draw.

The vulnerability arises in parsing the PCX image, specifically dealing with the column and row sizes of the image. Inside of the PCX header, values are set to determine the location of image data and the size of the image itself. By passing in incorrect values, the application will write out of bounds, attempting to access the image data. A look at the image header is shown below.

[TOP] 0        
[BOTTOM] 31
[LEFT] 225            [0]
[RIGHT] 31
[COLUMNS] -193
[ROWS] 32

The columns and rows are calculated by subtracting the bottom from the top, or subtracting the right from the left, respectively. As seen above, [0], the left value is far too large, causing a negative column value. This leads to an out-of-bounds write when the image map is accessed. The crash is shown below.

->  0x114e2290d <+71>: not    dword ptr [rcx]               [1]
    0x114e2290f <+73>: add    rcx, 0x4
    0x114e22913 <+77>: dec    ebx
    0x114e22915 <+79>: jne    0x114e2290d               ; <+71>

At location [1], RCX is user-controlled determined by the column sizes shown above. This creates an exploitable condition and could be used to gain code execution.

Crash Information

Crashed thread log = 
: Dispatch queue: com.apple.main-thread
0   com.acdsystem.canvastool.ImageIO    0x00000001129d290d invert_map(int, int, unsigned char*, int) + 71
1   com.acdsystem.canvastool.ImageIO    0x00000001129d33a5 MySetRasterData(void*, unsigned char*, long long, unsigned int) + 1280
2   ImageGear18                     0x00000001082c420d _PCX_read + 842
3   ImageGear18                     0x00000001082c3e9d PCX_read + 329
4   ImageGear18                     0x0000000108263dfd GPb_fltrm_READ_call_param + 178
5   ImageGear18                     0x0000000108263d45 GPb_fltrm_READ_call + 21
6   ImageGear18                     0x000000010823a923 iIG_load_FD_CB + 400
7   ImageGear18                     0x00000001083ac2db IG_load_FD_CB + 91
8   com.acdsystem.canvastool.ImageIO    0x0000000112a428a3 0x1129c0000 + 534691
9   com.acdsystem.canvastool.ImageIO    0x0000000112a40678 ImageGearAcquireProc(short, AcquireRecord*, int*, short*) + 791
10  com.acdsystem.canvastool.ImageIO    0x0000000112a40bf2 ImageIORunAcquireProc(_ImageIOAcquireState*) + 750
11  com.acdsystem.canvastool.ImageIO    0x0000000112a3e78a 0x1129c0000 + 518026
12  com.acdsystem.canvastool.ImageIO    0x0000000112a3fef4 DoImportFile(ImportFileMsg*) + 817
13  com.acdsystem.canvastool.ImageIO    0x00000001129f37c1 toolmain() + 917
14  com.acdsystem.canvastool.ImageIO    0x0000000112a1f90a stdtool(TToolCallBlock*) + 122
15  com.acdsystem.canvastool.ImageIO    0x0000000112a1f889 cvtool_main(TToolCallBlock*) + 9
16  com.acdsystems.Canvas-Draw4     0x00000001065af5b0 0x106476000 + 1283504
17  com.acdsystems.Canvas-Draw4     0x0000000107084b76 0x106476000 + 12643190
18  com.acdsystems.Canvas-Draw4     0x0000000107084438 0x106476000 + 12641336
19  com.acdsystems.Canvas-Draw4     0x00000001071b48a7 0x106476000 + 13887655
20  com.apple.AppKit                0x00007fffafee4bd3 -[NSApplication _doOpenFile:ok:tryTemp:] + 322
21  com.apple.AppKit                0x00007fffafaa3ba7 -[NSApplication finishLaunching] + 1624
22  com.apple.AppKit                0x00007fffafaa3148 -[NSApplication run] + 267
23  com.apple.AppKit                0x00007fffafa6de0e NSApplicationMain + 1237
24  libdyld.dylib                   0x00007fffc7734235 start + 1

log name is: ./crashlogs/1.crashlog.txt
---
exception=EXC_BAD_ACCESS:signal=11:is_exploitable=yes:instruction_disassembly=notl  (%rcx):instruction_address=0x00000001129d290d:access_type=unknown:access_address=0x0000000322700000:
Crash accessing invalid address.

Timeline

2018-04-03 - Vendor Disclosure
2018-07-19 - Public Release

Credit

Discovered by Tyler Bohan of Cisco Talos.