Talos Vulnerability Report

TALOS-2016-0216

ImageMagick Convert Tiff Adobe Deflate Code Execution Vulnerability

December 3, 2016

Report ID

CVE-2016-8707

Summary

An exploitable out of bounds write exists in the handling of compressed TIFF images in ImageMagicks’s convert utility. A crafted TIFF document can lead to an out of bounds write which in particular circumstances could be leveraged into remote code execution.. The vulnerability can be triggered through any user controlled TIFF that is handled by this functionality.

Tested Versions

ImageMagick 7.0.3-1

Product URLs

http://www.imagemagick.org

CVSSv3 Score

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

Details

This vulnerability is present in the convert utility bundled with ImageMagick. Thus utility is used by many web applications to parse and convert images and other formats inter changeably. It is a very popular piece of software for this use. The vulnerability arises when attempting to deflate an Adobe Deflate compressed Tiff image.

The vulnerability arises in the way that ImageMagick handles compressed data inside of an image. The size necessary to hold the decompressed data is calculated and then passed in to LibTiff but it is not large enough to hold the decompressed stream.

The buffer is calculated here:

pixels=(unsigned char *) GetQuantumPixels(quantum_info);

and then passed in here as op:

static int
ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
{

Finally this buffer is used as the next available buffer in a stream which has more data than is available and the out of bounds write occurs.

  sp->stream.next_out = op;

  ...

  int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);

This is a controlled out of bounds write that under proper circumstances could be exploited into full remote code execution.

Crash Information

Crashed thread log =
: Dispatch queue: com.apple.main-thread
frame #0: 0x00007fff9563d9c2 libz.1.dylib`inflate + 2549
frame #1: 0x0000000100fec96a libtiff.5.dylib`ZIPDecode(tif=0x0000000103bf9bb0, op=<unavailable>,
occ=<unavailable>,s=<unavailable>) + 186 at tif_zip.c:185
frame #2: 0x0000000100fe89d5 libtiff.5.dylib`TIFFReadScanline(tif=0x0000000103bf9bb0, buf=0x0000000105114ef0, row=0,
sample=0) + 693 at tif_read.c:299
frame #3: 0x0000000100979499 libMagickCore-7.Q16HDRI.0.dylib`ReadTIFFImage [inlined] TIFFReadPixels(bits_per_sample=0) +
27993
at tiff.c:873
frame #4: 0x000000010097948b libMagickCore-7.Q16HDRI.0.dylib`ReadTIFFImage(image_info=0x0000000101cb8de0,
exception=0x0000000101b4bfc0) + 27979 at tiff.c:1708
frame #5: 0x00000001000f69e8 libMagickCore-7.Q16HDRI.0.dylib`ReadImage(image_info=0x0000000101c61de0,
exception=0x0000000101b4bfc0) + 3720 at constitute.c:554
frame #6: 0x00000001000f9557 libMagickCore-7.Q16HDRI.0.dylib`ReadImages(image_info=0x0000000101bd4de0,
filename="crash1.tif", exception=0x0000000101b4bfc0) + 1447

---
exception=EXC_BAD_ACCESS:signal=11:is_exploitable=yes:instruction_disassembly=.byte 0xc5 #bad
opcode:instruction_address=0x00007fff8b1b303b:access_type=unknown:access_address=0x000000010985b000:
Crash accessing invalid address.  Consider running it again with libgmalloc(3) to see if the log changes.

Credit

Discovered by Tyler Bohan of Cisco Talos

Timeline

2016-10-10 - Vendor Disclosure
2016-12-03 - Public Release