Following my previous post, I’m releasing ziVA: a fully chained iOS kernel exploit that (should) work on all the iOS devices running iOS 10.3.1 or earlier. The exploit itself consists of multiple vulnerabilities that were discovered all in the same module: AppleAVEDriver.
The exploit will be covered in depth in my HITBGSEC talk held on August 25th.
For those of you who are not interested in iOS research and would like to protect themselves against these vulnerabilities, we urge you to update your iOS device to the latest version. Without an advanced mobile security and mitigation solution on the device (such as Zimperium zIPS), there’s little chance a user would notice any malicious or abnormal activity.
The POC is released for educational purposes and evaluation by IT Administrators and Pentesters alike, and should not be used in any unintended way.
The CVEs explanations, as written by Apple, can be found here.
iOS vulnerabilities discovered and reported to Apple
AVEVideoEncoder
Available for: iPhone 5 and later, iPad 4th generation and later, and iPod touch 6th generation
Impact: An application may be able to gain kernel privileges
Description: Multiple memory corruption issues were addressed with improved memory handling.
- CVE-2017-6989: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
- CVE-2017-6994: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
- CVE-2017-6995: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
- CVE-2017-6996: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
- CVE-2017-6997: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
- CVE-2017-6998: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
- CVE-2017-6999: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
IOSurface
Available for: iPhone 5 and later, iPad 4th generation and later, and iPod touch 6th generation
Impact: An application may be able to gain kernel privileges
Description: A race condition was addressed through improved locking.
CVE-2017-6979: Adam Donenfeld (@doadam) of the Zimperium zLabs Team
I will provide an in depth analysis of the vulnerabilities and exploitation techniques at HITBGSEC. After the conference, I will publish the rest of the disclosures as well as my slides and whitepaper.
A brief description of one of the vulnerabilities, CVE-2017-6979:
The function IOSurfaceRoot::createSurface is responsible for the creation of the IOSurface object. It receives an OSDictionary, which it forwards to the function IOSurface::init.
IOSurface::init parses the properties and in case one of these are invalid (e.g, a width that exceeds 32 bits), returns 0, and the creation of the IOSurface is halted.
The IOSurfaceRoot object must hold a lock while calling IOSurface::init because IOSurface::init adds the IOSurface object to the IOSurfaceRoot’s list of surfaces.
Here’s the code that used to call IOSurface::init before Apple’s fix:
IORecursiveLockLock(provider->iosurface_array_lock);
if ( !surface )
{
IORecursiveLockUnlock(provider->iosurface_array_lock);
return 0;
}
init_ret_code = surface->init(surface, provider, task_owner, surface_data);
At this point, the surfaces’ list is unlocked,
and an invalid IOSurface object is in the list
*/
IORecursiveLockUnlock(provider->iosurface_array_lock);if ( !init_ret_code )
{
surface->release(surface);
return 0;
}
In case the IOSurface::init function fails, IORecursiveLockUnlock will be called.
A bogus IOSurface object will still be in the system and in the IOSurfaceRoot’s list of surfaces (thus accessible to everyone).
At this particular moment, an attacker can increase the refcount of the IOSurface (creating, for instance, an IOSurfaceSendRight object attached to the surface) and prevent the bogus IOSurface object from being destroyed.
This leads to the creation and existence of an IOSurface in the kernel which the attacker controls its properties (IOSurface->width = -1 for example).
Such an IOSurface object can be given to other mechanisms in the kernel which might rely on a valid width/height/one of the properties to work, thus causing heap overflows/other problems that might lead to an elevation of privileges by the attacker.
Our proposed solution to Apple was to call IOSurface::release while the lock provider->iosurface_array_lock is still held. Therefore moving the IORecursiveLockUnlock call just below IOSurface::release and putting it after the entire if statement would fix the problem because the IOSurfaceRoot’s list of surfaces will only be available once the bogus IOSurface is already cleaned up.
Further reverse engineering of the function reveals that Apple changed the code according to our suggestions:
IORecursiveLockLock(provider->iosurface_array_lock);
if ( !surface )
{
IORecursiveLockUnlock(provider->iosurface_array_lock);
return 0;
}
init_ret_code = surface->init(surface, provider, task_owner, surface_data);if ( !init_ret_code )
{
surface->release(surface);
Here our bad surface is freed *before* the kernel unlocks the surfaces’ list,
Hence our bad surface is not accessible at anytime in case IOSurface::init fails.
*/
return 0;
}
IORecursiveLockUnlock(provider->iosurface_array_lock);
The issues are severe and could lead to a full device compromise. The vulnerabilities ultimately lead to an attacker with initial code execution to fully control any iOS device on the market prior to version 10.3.2.
Fortunately, we responsibly disclosed these bugs to Apple and a proper fix was coordinated. iOS users that update their device to the latest iOS version should be protected.
We discovered more vulnerabilities, and the written exploit POC didn’t take advantage of CVE-2017-6979! The vulnerabilities used for the POC will be covered in depth. We plan to release the security advisories as we sent them to Apple right after my talk at HITBGSEC
Zimperium’s patented machine-learning technology, z9, detects the exploitation of this vulnerability. We recommend to strengthen iOS security using a solution like Zimperium zIPS. Powered by z9, zIPS offers protection against known and unknown threats targeting Apple iOS and Google Android devices. z9 has detected every discovered exploit over the last five years without requiring updates.
The exploit source code is available here.
Disclosure timeline:
24/01/2017 – First Bug discovered
20/03/2017 – Shared bugs with Apple
29/03/2017 – Apple confirmed the bugs
15/05/2017 – Apple distributed patches
I would like to thank Apple for their quick and professional response, Zuk Avraham (@ihackbanme) and Yaniv Karta (@shokoluv) that helped in the process.