CVE-2018-3842
An exploitable use of an uninitialized pointer vulnerability exists in the JavaScript engine in Foxit PDF Reader version 9.0.1.1049. A specially crafted PDF document can lead to a dereference of an uninitialized pointer which, if under attacker control, can result in arbitrary code execution. An attacker needs to trick the user to open a malicious file to trigger this vulnerability. If the browser plugin extension is enabled, visiting a malicious site can also trigger the vulnerability.
Foxit Software Foxit PDF Reader 9.0.1.1049
https://www.foxitsoftware.com/products/pdf-reader/
8.8 - CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CWE-457: Use of Uninitialized Variable
Foxit PDF Reader is one of the most popular PDF document readers and has a widespread user base. It aims to have feature parity with Adobe’s Acrobat Reader. As a complete and feature-rich PDF reader, it supports JavaScript for interactive documents and dynamic forms. JavaScript support posses an additional attack surface. Additionally, Foxit PDF Reader supports XFA or XML Forms Architecture which is a new way of making interactive PDF forms.
When processing a specially crafted PDF document that contains XFA forms, executing the following JavaScript code leads to a dereference of an uninitialized pointer:
this.global.setPersistent();
This results in the following crash:
eax=000027f6 ebx=c0c0c0c0 ecx=c0c0c0c0 edx=0020eba8 esi=0020eb34 edi=0020eba8
eip=0151be10 esp=0020eac8 ebp=0020eaec iopl=0 nv up ei ng nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210286
FoxitReader!CertFreeCertificateChain+0x16fa30:
0151be10 8b4104 mov eax,dword ptr [ecx+4] ds:0023:c0c0c0c4=????????
Note that 0xc0c0c0c0
is a PageHeap magic value for allocated but uninitialized memory.
Tracking back to see where this pointer in ecx
comes from reveals the following:
0:000> bp FoxitReader!CertFreeCertificateChain+0x10d5a0
0:000> g
eax=12fdcff0 ebx=00000000 ecx=1323ef68 edx=0022e520 esi=13c3efb8 edi=123c2ff8
eip=018f9980 esp=0022e474 ebp=0022e4a0 iopl=0 nv up ei ng nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200282
FoxitReader!CertFreeCertificateChain+0x10d5a0:
018f9980 e8db09f0ff call FoxitReader!CertFreeCertificateChain+0xdf80 (017fa360)
0:000> u 017fa360
FoxitReader!CertFreeCertificateChain+0xdf80:
017fa360 8b416c mov eax,dword ptr [ecx+6Ch]
017fa363 c3 ret
0:000> dd ecx+6c
1323efd4 c0c0c0c0 00000000 00000001 106a8ff8
1323efe4 00000000 00000000 00000000 00000000
1323eff4 c0c0c0c0 00000000 00000000 ????????
1323f004 ???????? ???????? ???????? ????????
1323f014 ???????? ???????? ???????? ????????
1323f024 ???????? ???????? ???????? ????????
1323f034 ???????? ???????? ???????? ????????
1323f044 ???????? ???????? ???????? ????????
In the above output, we can see that at FoxitReader!CertFreeCertificateChain+0x10d5a0
a call is being made to a simple dereferencing function, which grabs a pointer from ecx+0x6c
and puts it into eax
. As we can see from the memory output, this pointer is uninitialized. The object pointed to by ecx
is actually allocated:
0:000> !heap -p -a ecx
address 1323ef68 found in
_DPH_HEAP_ROOT @ 7431000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
130f298c: 1323ef68 98 - 1323e000 2000
? FoxitReader!CertFreeCertificateChain+186dd2c
57a08e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77276206 ntdll!RtlDebugAllocateHeap+0x00000030
7723a127 ntdll!RtlpAllocateHeap+0x000000c4
77205950 ntdll!RtlAllocateHeap+0x0000023a
02b8ee12 FoxitReader!CertFreeCertificateChain+0x013a2a32
029d96ea FoxitReader!CertFreeCertificateChain+0x011ed30a
017ec6dc FoxitReader!CertFreeCertificateChain+0x000002fc
017f0142 FoxitReader!CertFreeCertificateChain+0x00003d62
01226aef FoxitReader+0x00136aef
01309bce FoxitReader+0x00219bce
012d8083 FoxitReader+0x001e8083
012e3697 FoxitReader+0x001f3697
012cb074 FoxitReader+0x001db074
012cfa5c FoxitReader+0x001dfa5c
02cee5af FoxitReader!CertFreeCertificateChain+0x015021cf
02b889ca FoxitReader!CertFreeCertificateChain+0x0139c5ea
75dcef8c kernel32!BaseThreadInitThunk+0x0000000e
7721367a ntdll!__RtlUserThreadStart+0x00000070
7721364d ntdll!_RtlUserThreadStart+0x0000001b
Further on, the pointer from eax
ends up in ebx
and ends up being used as this
pointer in a thiscall
function call:
.text:00C09996 lea eax, [ebp+arg_4]
.text:00C09999 push 27F6h
.text:00C0999E push eax
.text:00C0999F mov ecx, ebx
.text:00C099A1 call sub_C095C0
Finally, the crash will happen when the uninitialized this
value is used to dereference a vtable in the function sub_C095C0
:
.text:00C095F3 mov eax, [ebp+arg_4] .text:00C095F6 push eax .text:00C095F7 call sub_C6BE10 .text:00C095FC push esi .text:00C095FD mov edi, eax .text:00C095FF call sub_C094E0 .text:00C09604 add esp, 8 .text:00C09607 jmp short loc_
The crash actually occurs in the sub_C6BE10 call, comprised of just two instructions, that perform an object table dereference:
.text:00C6BE10 sub_C6BE10 proc near
.text:00C6BE10 mov eax, [ecx+4]
.text:00C6BE13 mov eax, [eax+3Ch]
.text:00C6BE16 retn
.text:00C6BE16 sub_C6BE10 endp
.text:00C6BE16
The target of double dereference above ends up in eax
. If we follow this value through registers, it ends up being saved in edi
, which is later dereferenced again into eax
and is used as the destination of an indirect call:
.text:00C09560 mov eax, [edi]
.text:00C09562 push esi
.text:00C09563 lea edx, [ebp+var_18]
.text:00C09566 push edx
.text:00C09567 mov byte ptr [ebp+var_4], 1
.text:00C0956B mov eax, [eax+11Ch]
.text:00C09571 mov ecx, edi
.text:00C09573 call eax
Following this, we can conclude that if, with careful memory layout manipulation, an attacker can control the contents of memory that gets used uninitialized it will eventually lead to control of the contents of eax
at the above call instruction leading to arbitrary code execution.
(edc.14c4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=000027f6 ebx=c0c0c0c0 ecx=c0c0c0c0 edx=0022e520 esi=0022e4ac edi=0022e520
eip=0195be10 esp=0022e440 ebp=0022e464 iopl=0 nv up ei ng nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00210286
FoxitReader!CertFreeCertificateChain+0x16fa30:
0195be10 8b4104 mov eax,dword ptr [ecx+4] ds:0023:c0c0c0c4=????????
0:000> k
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0022e464 018f99a6 FoxitReader!CertFreeCertificateChain+0x16fa30
01 0022e4a0 018f9bf9 FoxitReader!CertFreeCertificateChain+0x10d5c6
02 0022e4fc 014391c8 FoxitReader!CertFreeCertificateChain+0x10d819
03 0022e544 02836e8e FoxitReader+0x3491c8
04 0022e578 0282ec76 FoxitReader!CertFreeCertificateChain+0x104aaae
05 0022e5e0 02831023 FoxitReader!CertFreeCertificateChain+0x1042896
06 0022e5f0 1770a0d6 FoxitReader!CertFreeCertificateChain+0x1044c43
07 0022e610 1774db1a 0x1770a0d6
08 0022e630 17738e95 0x1774db1a
09 0022e64c 17722aca 0x17738e95
0a 0022e688 027270c9 0x17722aca
0b 0022e6d0 02727c0b FoxitReader!CertFreeCertificateChain+0xf3ace9
0c 0022e708 02683f61 FoxitReader!CertFreeCertificateChain+0xf3b82b
0d 0022e760 0143b0a2 FoxitReader!CertFreeCertificateChain+0xe97b81
0e 0022e7ec 0143a6f6 FoxitReader+0x34b0a2
0f 0022e7fc 0195c202 FoxitReader+0x34a6f6
10 0022e860 0195c462 FoxitReader!CertFreeCertificateChain+0x16fe22
11 0022e874 016af278 FoxitReader!CertFreeCertificateChain+0x170082
12 0022e8a4 016b2166 FoxitReader+0x5bf278
13 0022e8dc 016b2e4f FoxitReader+0x5c2166
14 0022e934 011c2a3a FoxitReader+0x5c2e4f
15 0022e96c 01324ae0 FoxitReader+0xd2a3a
16 0022f580 029e8172 FoxitReader+0x234ae0
17 0022f638 029e24f9 FoxitReader!CertFreeCertificateChain+0x11fbd92
18 0022f658 029e63fc FoxitReader!CertFreeCertificateChain+0x11f6119
19 0022f6cc 029e648b FoxitReader!CertFreeCertificateChain+0x11fa01c
1a 0022f6ec 756ac4b7 FoxitReader!CertFreeCertificateChain+0x11fa0ab
1b 0022f718 756ac5b7 USER32!InternalCallWinProc+0x23
1c 0022f790 756acbe9 USER32!UserCallWinProcCheckWow+0x14b
1d 0022f7f0 756acc40 USER32!DispatchMessageWorker+0x357
1e 0022f800 029e0596 USER32!DispatchMessageW+0xf
1f 0022f830 02cee5d0 FoxitReader!CertFreeCertificateChain+0x11f41b6
20 0022f844 02b889ca FoxitReader!CertFreeCertificateChain+0x15021f0
21 0022f8d4 75dcef8c FoxitReader!CertFreeCertificateChain+0x139c5ea
22 0022f8e0 7721367a kernel32!BaseThreadInitThunk+0xe
23 0022f920 7721364d ntdll!__RtlUserThreadStart+0x70
24 0022f938 00000000 ntdll!_RtlUserThreadStart+0x1b
2018-02-12 - Vendor Disclosure
2018-02-14 - Discussion with vendor on issues
2018-04-01 - Vendor pushed release to mid April
2018-04-19 - Vendor patch released
2018-04-19 - Public disclosure
Discovered by Aleksandar Nikolic of Cisco Talos.