header-logo
Suggest Exploit
vendor:
N/A
by:
phoenhex
8,8
CVSS
HIGH
JavaScriptCore Spread Overflow
119
CWE
Product Name: N/A
Affected Version From: N/A
Affected Version To: N/A
Patch Exists: Yes
Related CWE: N/A
CPE: N/A
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: macOS
2017

Heap Feng-Shui to Exploit JavaScriptCore Spread Overflow

JavaScriptCore will allocate a JSFixedArray for every spread operand of the array literal (in slow_path_spread). As such, roughly 4 billion JSValues will have to be allocated, taking up 32 GiB in RAM. To exploit the bug, the author allocates 100 JSArrays of size 0x40000 and roots them, allocates 100 JSArrays of size 0x40000, where only every second one is rooted, allocates a larger JSArray and an ArrayBuffer of the same size, allocates 4 GiB of padding using JSArrays, and triggers the bug by concatenating JSArrays with a combined size of 232 + 0x40000 (containing the repeated byte 0x41). This increases the size of the victim array to the sprayed value (0x4141414141414141), so that it overlaps with the victim ArrayBuffer. This yields the fakeobj and addrof primitives which can then be used to write code to a JIT page and jump to it.

Mitigation:

Ensure that JavaScriptCore is up to date and patched.
Source

Exploit-DB raw data:

Sources:
https://phoenhex.re/2017-06-02/arrayspread
https://github.com/phoenhex/files/blob/master/exploits/spread-overflow

JavaScriptCore will allocate a JSFixedArray for every spread operand of the array literal (in slow_path_spread). As such, roughly 4 billion JSValues will have to be allocated, taking up 32 GiB in RAM. Luckily, this isn’t much of a problem due to the page compression performed by the macOS kernel. It will, however, take roughly a minute to trigger the bug.

What is left to do now is to perform some heap feng-shui to place something interesting on the heap that we will then overflow into. We use the following heap spray to exploit the bug:

- Allocate 100 JSArrays of size 0x40000 and root them (i.e. keep references). This will trigger GC multiple times and fill up holes in the heap.
- Allocate 100 JSArrays of size 0x40000, where only every second one is rooted. This triggers GC and leaves holes of size 0x40000 in the heap.
- Allocate a larger JSArray and an ArrayBuffer of the same size. These end up directly after the spray from step 2.
- Allocate 4 GiB of padding using JSArrays.
- Trigger the bug by concatenating JSArrays with a combined size of 232 + 0x40000 (containing the repeated byte 0x41).

The target buffer will be allocated in the sprayed region from step 2 and the victim buffers from step 3 will be overwritten. This increases the size of the victim array to the sprayed value (0x4141414141414141), so that it overlaps with the victim ArrayBuffer. The final steps immediately yield the fakeobj and addrof primitives described in section 1.2 of the JavaScriptCore phrack paper which can then be used to write code to a JIT page and jump to it.

In our exploit we perform step 5 in a separate web worker, so that we can launch a second stage shellcode immediately after the victim arrays are overwritten. This way we do not need to wait for the full overwrite to finish, and the heap is only left in a broken state for a very short time, so that garbage collection does not crash (which runs concurrently starting from Safari version 10.1). 


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/42125.zip