CVE-2018-3871
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 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.
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.
2018-04-03 - Vendor Disclosure
2018-07-19 - Public Release
Discovered by Tyler Bohan of Cisco Talos.