# CVE-2019-7286: iOS use-after-free in cfprefsd
*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:** Exploit targeted iOS 12-12.1

**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:** use-after-free (UaF)

**Vulnerability details:**

cfprefds hosts the com.apple.cfprefsd.daemon XPC service. This service offers a number of operations, including a "multi-message" operation which allows bundling multiple individual operations into one larger message. The vulnerability is in the implementation of this multi-message handling.

The code allocates an array on the stack and fills it with raw pointers to each of the sub-messages inside the multi-message. It then invokes each message handler, passing a custom reply_handler [block](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html) which rather than sending the reply, instead overwrites the raw sub-message pointer in the stack buffer with a retained reply message pointer.

The code fails to take into account the fact that not all message handlers invoke the reply_handler block, as not all messages send replies. This can leave some slots in the stack buffer containing raw pointers, and some containing retained pointers. xpc_release will be called on each of the entries, dropping an extra reference on the raw pointers which was never obtained leading to a UaF.

**Patch analysis:** N/A

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

A manual audit of the service should have found this bug; the dual use of the stack buffer is a sufficiently weird primitive that I think it would have stood out. A generic XPC fuzzer might be able to find it, but I don't think it's necessarily trivially fuzzable because you'd need well-formed XPC objects with the right dictionaries.

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

This vulnerability was discovered and reported at the same time as [CVE-2019-7287](CVE-2019-7287.md). Google's 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. This vulnerability, CVE-2019-7286, is the sandbox escape that is paired with CVE-2019-7287, the kernel vulnerability.

## The Exploit

**Is the exploit method known?** Yes

**Exploit method:** 

This vulnerability is a sandbox escape. It runs as shellcode loaded in a sandboxed WebContent renderer process and gets ROP execution in cfprefsd, a more privileged process. They exploit the UaF using an XPC heap spray to fill the target heap with a fake objective C object with a fake selector cache. When a method is invoked on this object, it will trigger a ROP payload. The ROP stack opens an IOKit userclient mach port and sends it back to the renderer, allowing the shellcode to interact with the kernel driver and exploit a kernel bug ([CVE-2019-7287](CVE-2019-7287.md)).

## The Next Steps

### Variant analysis

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

Manual XPC object lifetime management is tricky and there are a few APIs which can be unsafe. Looking for places where xpc_retain/xpc_release are called could be a good start, but they're probably quite common.

**Found variants:**

### Structural improvements


### 0-day detection methods

A memory sanitizer tool would detect 0-days like this.

## Other References 

* March 2019: ["Analysis and Reproduction of iOS/OSX Vunerability: CVE-2019-7286"](https://blog.zecops.com/vulnerabilities/analysis-and-reproduction-of-cve-2019-7286/) and ["CVE-2019-7286 Part II: Gaining PC Control"](https://blog.zecops.com/vulnerabilities/exploit-of-cve-2019-7286/) by Zecops Research Team
* 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)
