Ian Beer, Project Zero (Originally posted on Project Zero blog 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)

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:

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. 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