Talos Vulnerability Report

TALOS-2018-0561

Computerinsel Photoline PCX Decompress Code Execution Vulnerability

April 11, 2018
CVE Number

CVE-2018-3886

Summary

A memory corruption vulnerability exists in the PCX-parsing functionality of Computerinsel Photoline 20.53. 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

Computerinsel Photoline 20.53 for OS X

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

Photoline is an image processing tool used to modify and edit images, as well as other graphic-editing functions. 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 parsing 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 error comes in due to incorrectly calculating the size of the compressed data. The relevant code is shown below.

    do
    {
      packet_byte = *packet_ptr;                       [0]
      next_packet_byte = packet_ptr + 1;
      ...
        user_byte = packet_byte & 0x3F;                [1]
        count = 0LL;
        do
            pixels[count++] = *next_packet_byte;       [2]
        while ( count < user_byte );
        pixels += count;
        ++counter;
    ...
    }
    while ( counter < packet_count );                  [3]

At location [0], the compressed image data is read, and a binary operation is performed to calculate the counter for the inner loop [1]. The outer loop counter at location [3] has been passed into the function but has been calculated via controlled image data. This allows a specially crafted image to iterate through the loop more than desired. This creates an out-of-bounds write at location [2] and an exploitable condition arises. This vulnerability can be exploited to gain code execution.

Crash Information

Crashed thread log = 
: Dispatch queue: com.apple.main-thread
0   de.pl32.photoline               0x0000000107dc3f75 0x107392000 + 10690421
1   de.pl32.photoline               0x0000000107dc4396 0x107392000 + 10691478
2   de.pl32.photoline               0x00000001074d2481 0x107392000 + 1311873
3   de.pl32.photoline               0x00000001074d2302 0x107392000 + 1311490
4   de.pl32.photoline               0x00000001074d1ff4 0x107392000 + 1310708
5   de.pl32.photoline               0x0000000107907d42 0x107392000 + 5725506
6   de.pl32.photoline               0x0000000107544688 0x107392000 + 1779336
7   de.pl32.photoline               0x00000001075443db 0x107392000 + 1778651
8   de.pl32.photoline               0x00000001075a17c2 0x107392000 + 2160578
9   de.pl32.photoline               0x0000000107dbdc0a 0x107392000 + 10664970
10  de.pl32.photoline               0x0000000107dbdfb2 0x107392000 + 10665906
11  com.apple.AppKit                0x00007fffafccfdd7 -[NSDocument _initWithContentsOfURL:ofType:error:] + 172
12  com.apple.AppKit                0x00007fffafccfcbc -[NSDocument initWithContentsOfURL:ofType:error:] + 231
13  com.apple.AppKit                0x00007fffafdad2b0 -[NSDocumentController makeDocumentWithContentsOfURL:ofType:error:] + 644
14  com.apple.AppKit                0x00007fffb0000470 __97-[NSDocumentController makeDocumentWithContentsOfURL:alternateContents:ofType:completionHandler:]_block_invoke + 83
15  com.apple.AppKit                0x00007fffb0000412 -[NSDocumentController makeDocumentWithContentsOfURL:alternateContents:ofType:completionHandler:] + 176
16  com.apple.AppKit                0x00007fffafdac2e6 __80-[NSDocumentController openDocumentWithContentsOfURL:display:completionHandler:]_block_invoke + 613
17  com.apple.AppKit                0x00007fffaffff48b __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke_2.922 + 180
18  com.apple.AppKit                0x00007fffaffff3a7 __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke.921 + 138
19  com.apple.AppKit                0x00007fffaffff269 __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke_4 + 267
20  com.apple.CoreFoundation        0x00007fffb1fd717c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
21  com.apple.CoreFoundation        0x00007fffb1fb7f84 __CFRunLoopDoBlocks + 356
22  com.apple.CoreFoundation        0x00007fffb1fb7705 __CFRunLoopRun + 917
23  com.apple.CoreFoundation        0x00007fffb1fb7114 CFRunLoopRunSpecific + 420
24  com.apple.HIToolbox             0x00007fffb1517ebc RunCurrentEventLoopInMode + 240
25  com.apple.HIToolbox             0x00007fffb1517bf9 ReceiveNextEventCommon + 184
26  com.apple.HIToolbox             0x00007fffb1517b26 _BlockUntilNextEventMatchingListInModeWithFilter + 71
27  com.apple.AppKit                0x00007fffafaaea54 _DPSNextEvent + 1120
28  com.apple.AppKit                0x00007fffb022a7ee -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 2796
29  com.apple.AppKit                0x00007fffafaa33db -[NSApplication run] + 926
30  de.pl32.photoline               0x0000000107dbaa19 0x107392000 + 10652185
31  com.apple.AppKit                0x00007fffafa6de0e NSApplicationMain + 1237
32  de.pl32.photoline               0x0000000107393d14 0x107392000 + 7444

log name is: ./crashlogs/1.crashlog.txt
---
exception=EXC_BAD_ACCESS:signal=11:is_exploitable=yes:instruction_disassembly=movb  %al,(%r9,%rcx):instruction_address=0x0000000107dc3f75:access_type=write:access_address=0x00000001a17d6000:
Crash accessing invalid address.

Timeline

2018-04-09 - Vendor Disclosure
2018-04-11 - Public Release

Credit

Discovered by Tyler Bohan of Cisco Talos.