Sploitus

Exploit for Integer Overflow or Wraparound in Apple Icloud

githubexploit · 2020-01-02

Exploit Code

README100 lines
## https://sploitus.com/exploit?id=1703F542-B444-5411-8FA9-855252161826
# Exploiting CVE-2019-8601

This is an exploit for a WebKit vulnerability that was originally discovered by [Fluoroacetate](https://www.twitter.com/fluoroacetate) during the pwn2own competition in Vancouver. While I did not discover this bug, I wrote this exploit to practice my exploit development skills. The original writeup for this exploit is [here](https://www.zerodayinitiative.com/blog/2019/11/25/diving-deep-into-a-pwn2own-winning-webkit-bug) from Zero Day Initiative . While this write up is very good and it was instrumental in helping me understand the vulnerability, it is from the point of view of someone verifying the vulnerability. I found that some key details are missing when trying to engineer this exploit from scratch and I hope to fill in some of the gaps that the ZDI write up missed and gain practical skills on how to engineer a complicated exploit from scratch.

## Steps to Exploitation 

These steps serve as an outline to get arbitrary code execution within JavaScriptCore (JSC), the JavaScript engine for WebKit

- [ ] Identify the vulnerability
- [ ] Trigger the vulnerability and crash with ASAN enabled
- [ ] Get leakAddr and fakeObj primitives
- [ ] Corrupt array butterfly in order to achieve read and write primitives
- [ ] Use read and write primitives to achieve arbitrary code execution within JSC

## Identifying the Vulnerability

The vulnerability that will be exploited is an integer overflow that occurs in the code produced by the DFG just in time (JIT) compiler for WebKit. This specifically occurs in the `compileNewArrayWithSpread` function. This function will be called when code using [JavaScript spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) to create a new array is JITed by DFG.

![compileNewArrayWithSpread](./img/compileNewArrayWithSpread.png)



Inside the JITed code, first it will compute the size of the array. It does this by adding the length of each argument passed to the array constructor. As it computes the size for each addition it checks for an overflow of the size. After this it will call the `compileAllocateNewArray` function passing the length that was computed in this function.

![compileAllocateNewArrayWithSize](./img/compileAllocateNewArrayWithSize.png)

The `compileAllocateNewArray` will then pass the length that was computed before to `emitAllocateButterfly`.

![emitAllocateButterfly](./img/emitAllocateButterfly.png)

The `emitAllocateButterfly` will then left shift the size 3 bits which is equivalent to multiplying it by 8. However, there is no check for an overflow and thus a number such as 0x20000001 can overflow to 0x8

This c program illustrates this vulnerability:

 ![overflow-example2](./img/overflow-example2.png)

![overflow-example](./img/test.png)

We can use this vulnerability to trick the JavaScript engine into thinking we've allocated an array with size 0x20000001 but actually only have allocated enough space for 1 JSValue (8 bytes). This will result in an out-of-bounds (OOB) read and write (R/W) primitive that can then be leveraged to achieve arbitrary R/W and eventually remote code execution (RCE).

- [x] Identify the vulnerability

  ## Triggering the Vulnerability with ASAN

In order to confirm that we have an OOB read we will try to trigger this vulnerability on an [address sanitizer](https://en.wikipedia.org/wiki/AddressSanitizer) (ASAN) build of JSC.

To do this from the WebKit directory we can run the commands:

```bash
Tools/Scripts/set-webkit-configuration --asan
Tools/Scripts/build-jsc --jsc--only --debug
```

This will build a debug build of JSC with ASAN enabled allow us to verify whether of not we have successfully triggered the vulnerability.

Here is the first iteration of exploit.js

```javascript
function jitMe(array){
  return [...array]
}

let dummy = [1.1]
for(let i = 0; i  {
  let x = new Array(0x10)
})

jitMe(a, b)
```

Gives us an ASAN error!![asan](./img/asan.png)

- [x] Trigger the vulnerability and crash with ASAN enabled

### Heap Spraying to Get Overlapping Allocations

Now that we can reliably trigger the vulnerability, we would like to use our OOB R/W primitive to further corrupt memory and get a type confusion primitive. The first step is to recompile JSC with ASAN disabled. After doing this we rerun exploit.js and get the following crash

![sucess!](./img/sucess!.png)



We can see that we are corrupting this to point to 0x3ff299999999999a when we use python struct module to convert the float value 1.1 to bytes we get the just what we'd expect: 0x3ff299999999999a ![struct](./img/struct.png)

Now that we can see that we have achieved memory corruption we need to do some heap massaging to turn this into a type confusion. The idea will be to spray a number of ArrayWithDoubles and ArrayWithContiguous and corrupt the length of the butterfly so we can achieve out of bounds access with these arrays and get a type confusion. Hopefully, allocating enough arrays will prevent the out of bounds from corrupting any important values.

```
function jitMe(array, reInitAllocator){                                                                                            
  for(let i = 0; i  {
  for(let i = 0; i  {
  for(let i = 0; i  {
  for(let i = 0; i  {
  for(let i = 0; i 

### Conclusion

This hopefully this shows how you can take a JSC n-day and develop an exploit for it. I benefited by having the Zeroday Initiative writeup. While I did use this while writing the exploit, I tried only to take the main ideas and do the implementation by myself without looking at the write up. 

This exploit is only a proof of concept and is not as robust as it could be. Although I have not experienced any failed attempts, there is always work that could be done to improve it. Since I did this as a learning experience I did not bother to make the exploit as robust as it could possible be.