# CVE-2019-7287: iOS Buffer Overflow in ProvInfoIOKitUserClient
*Ian Beer, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2020-07-27)*

## The Basics

**Disclosure or Patch Date:** 7 February 2019

**Product:** Apple iOS

**Advisory:** https://support.apple.com/en-us/HT209520 

**Affected Versions:** iOS 10-12.1.3 

**First Patched Version:** iOS 12.1.4

**Issue/Bug Report:** N/A

**Patch CL:** N/A

**Bug-Introducing CL:** N/A 

**Reporter(s):** Clement Lecigne of Google's Threat Analysis Group (TAG), Ian Beer & Samuel Groß of Google Project Zero, & an anonymous researcher (according to [Apple's release notes](https://support.apple.com/en-us/HT209520)) 

## The Code

**Proof-of-concept:** N/A

**Exploit sample:** N/A

**Did you have access to the exploit sample when doing the analysis?** Yes

## The Vulnerability

**Bug class:** Heap buffer overflow

**Vulnerability details:** 

A heap buffer overflow in an external method of an IOKit user client. In the driver pseudocode below the attacker controls the contents of the buffer pointed to by `struct_in`:

```c
ProvInfoIOKitUserClient::ucEncryptSUInfo(char* struct_in,
                                         char* struct_out){
  memmove(&struct_out[4],
          &struct_in[4],
          *(uint32_t*)&struct_in[0x7d4]);
```

The vulnerability is that the size argument to `memmove` is completely attacker controlled and not checked. This leads to kernel heap corruption.

**Patch analysis:** N/A

**Thoughts on how this vuln might have been found _(fuzzing, code auditing, variant analysis, etc.)_:**

A manual audit or fuzzing of the driver should have found this vulnerability. For the fuzzer, it would need to correctly guess the input and output structure sizes, which have to be exact, and would also need to be running outside the app sandbox.

**(Historical/present/future) context of bug:** 

This vulnerability was discovered and reported at the same time as [CVE-2019-7286](CVE-2019-7286.md). Google TAG discovered a cache of iOS exploit chains being used in the wild. CVE-2019-7286 and CVE-2019-7287 were the only two vulnerabilities that were still 0-days at the time of discovery. Because this vulnerability, CVE-2019-7287, is a kernel vulnerability in a driver not reachable from the WebContent renderer sandbox, it was paired with CVE-2019-7286 in order to get the send right to the user client mach part needed to exploit CVE-20196-7287.

## The Exploit

**Is the exploit method known?** Yes

**Exploit method:** 

The exploit discovered by TAG used the heap corruption to build an arbitrary kernel memory read and write primitive which they used to defeat codesigning and launch an unsandboxed and unsigned userspace implant binary from /tmp.

## The Next Steps

### Variant analysis

**Areas/approach for variant analysis (and why):** 

Analysis of all IOKit external method entrypoints looking for places where attacker-controlled values 
are trusted.

**Found variants:** None

### Structural improvements

The size of the output buffer is statically known, it should be possible to use `memcpy_chk` here.

### 0-day detection methods

A memory sanitizer tool would have detected this exploitation attempt.

## Other References 
* February 2019: [Analysis of CVE-2019-7287](https://www.antid0te.com/blog/19-02-23-ios-kernel-cve-2019-7287-memory-corruption-vulnerability.html) by Stefan Esser
* August 2019: Detailed, technical blog post series about these iOS exploit chains ["A very deep dive into iOS exploit chains found in the wild"](https://googleprojectzero.blogspot.com/2019/08/a-very-deep-dive-into-ios-exploit.html)
