Abstract. Due to its popularity, iOS has attracted the attention of a large number of security researchers. Apple is constantly improving iOS security, develops and adapts new mitigations at a rapid pace. In terms of the effectiveness of mitigation measures, Apple increases the complexity of hacking iOS devices making it one of the hardest platforms to hack, however, it is not yet sufficient to block skilled individuals and well-funded groups from achieving remote code execution with elevated permissions, and persistence on the device.
This blog post is the first of multiple in a series of achieving elevated privileges on iOS.
This series of posts will go all the way until privileged access is obtained, the userspace exploit, as well as persistence on the device following a reboot. The full reports are currently available to iOS Threat Intelligence subscribers of ZecOps Mobile Threat Intelligence.
We will cover in detail how chaining a few bugs leads us to run code in the context of iOS kernel. Chaining such bugs with other exploits (e.g. the iOS MailDemon vulnerability, or other webkit based bugs) allow to gain full remote control over iOS devices.
This exploit was obtained as part of ZecOps Reverse Bounty, and donated to FreeTheSandbox initiative.
|Freethesandbox.org – Free The Sandbox restrictions from iOS & Android devices|
We would like to thank @08Tc3wBB for participating in ZecOps Reverse Bounty, and everyone else that helped in this project. We would also like to thank the Apple Security team for fixing these bugs and preventing further abuse of these bugs in up to date versions of iOS.
As we’re planning to release the additional blogs, we are already releasing a full Local Privilege Escalation chain that works on iOS 13.7 and earlier versions on both PAC and non-PAC devices.
We are making this release fully open-source for transparency. We believe that it is the best outcome to improve iOS research and platform security.
|You may access the source here: https://github.com/ZecOps/FreeTheSandbox_LPE_POC_13.7|
The Vulnerabilities – Part I
AppleAVE2 is a graphics IOKit driver that runs in kernel space and exists only on iOS and just like many other iOS-exclusive drivers, it’s not open-source and most of the symbols have been removed.
The driver cant be accessed from the default app sandbox environment, which reduces the chances of thorough analysis by Apple engineers or other researchers. The old implementation of this driver seems like a good attack surface and the following events demonstrate this well.
Back in 2017, 7 vulnerabilities were exposed in the same driver, by Adam Donenfeld of the Zimperium zLabs Team,
From the description of these vulnerabilities, some remain attractive even today, while powerful mitigations like PAC (for iPhones/iPads with A12 and above) and zone_require (iOS 13 and above) are present, arbitrary memory manipulation vulnerabilities such as CVE-2017-6997, CVE-2017-6999 play a far greater role than execution hijacking type, have great potential when used in chain with various information leakage vulnerabilities.
Despite the fact that these vulnerabilities have CVEs, which generally indicating that they have been fixed, Apple previously failed to fix bugs in one go and even bug regressions. With that in-mind, let’s commence our journey to hunt the next AVE vulnerability!
We will start off from the user-kernel data interaction interface:
AppleAVE2 exposes 9 (index 0-8) methods via rewriting IOUserClient::externalMethod:
Two exposed methods (index 0 and 1) allow to add or remove clientbuf(s), by the FIFO order.
The rest of the methods (index 3-8) are all eventually calling AppleAVE2Driver::SetSessionSettings through IOCommandGate to ensure thread-safe and avoid racing.
*1 Overlapping Segment Attack against dyld to achieve untethered jailbreak, first appearance in iOS 6 jailbreak tool — evasi0n, then similar approach shown on every public jailbreak, until after Pangu9, Apple seems finally eradicated the issue.
*2 Apple accidentally re-introduces previously fixed security flaw in a newer version.
We mainly use method at index 7 to encode a clientbuf, which basically means to load many IOSurfaces via IDs provided from userland, and use method at index 6 to trigger trigger the multiple security flaws located inside AppleAVE2Driver::SetSessionSettings.
The following chart entails a relationship map between salient objects:
clientbuf is memory buffer allocated via IOMalloc, with quite significant size (0x29B98 in iOS 13.2).
Every clientbuf objext thats is being added contains pointers to the front and back, forming a double-linked list, so that the AppleAVE2Driver’s instance stores only the first clientbuf pointer.
The clientbuf contains multiple MEMORY_INFO structures. When user-space provides IOSurface, an iosurfaceinfo_buf will be allocated and then used to fill these structures.
iosurfaceinfo_buf contains a pointer to AppleAVE, as well as variables related to mapping from user-space to kernel-space.
As part of the clientbuf structure, the content of these InitInfo_block(s) is copied from user-controlled memory through IOSurface, this happens when the user first time calls another exposed method(At index 7) after adding a new clientbuf.
m_DPB is related to arbitrary memory reading primitive which will be explained later in this post.
Brief Introduction to IOSurface
In case if you are not familiar with IOSurface, read the below:
According to Apple’s description IOSurface is used for sharing hardware-accelerated buffer data ( for framebuffers and textures) more efficiently across multiple processes.
Unlike AppleAVE, an IOSurface object can be easily created by any userland process (using IOSurfaceRootUserClient). When creating an IOSurface object you will get a 32 bit long Surface ID number for indexing purposes in the kernel so that the kernel will be able to map the userspace memory associated with the object into kernel space.
Now with these concepts in mind let’s talk about the AppleAVE vulnerabilities.
The First Vulnerability (iOS 12.0 – iOS 13.1.3)
The first AppleAVE vulnerability has given CVE-2019-8795 and together with other two vulnerabilities — A Kernel Info-Leak(CVE-2019-8794) that simply defeats KASLR, and a Sandbox-Escape(CVE-2019-8797) that’s necessary to access AppleAVE, created an exploit chain on iOS 12 that was able to jailbreak the device. That’s until the final release of iOS 13, which destroyed the Sandbox-Escape by applying sandbox rules to the vulnerable process and preventing it from accessing AppleAVE, So the sandbox escape was replaced with another sandbox escape vulnerability that was discussed before.
The first AppleAVE vulnerability was eventually fixed after the update of iOS 13.2.
Here is a quick description about it and for more detailed-write up you can look at a previous writeup.
When a user releases a clientbuf, it will go through every MEMORY_INFO that the clientbuf contains and will attempt to unmap and release related memory resources.
The security flaw is quite obvious if you compare to how Apple fixed it:
The unfixed version has defect code due to an out-of-bounds access that allows an attacker to hijack kernel code execution in regular and PAC-enabled devices. This flaw can also become an arbitrary memory release primitive via the operator delete. and back then, before Apple fixed zone_require flaw on iOS 13.6, that was enough to achieve jailbreak on the latest iOS device.
The POC released today is just an initial version that will allow others to take it further. The POC shares basic analytics data with ZecOps to find additional vulnerabilities and help further secure iOS – this option can be disabled in the source.
In the next posts we’ll cover:
- Additional vulnerabilities in the kernel
- Exploiting these vulnerabilities
- User-space vulnerabilities
- The ultimate persistence mechanism that is likely to never be patched