In the Pwn2own 2017 game, Apple macOS Sierra and Safari 10 become is attack up one of the goals. In this competition process, although there are multi-branched clan successfully/semi-successfully completed on macOS + Safari target compromised, however 360 security team use exploits the minimum number, and is also the only one by a kernel vulnerability to achieve sandbox escape and provide the right and complete control of the macOS operating system kernel of the clan. In this article techniques to share, we will describe our use of the macOS kernel vulnerability principle and find details.
In the Pwn2own 2017, in order to completely break the macOS Sierra + Safari objectives, a thorough control of theoperating systemthe kernel, the 360 security team uses two security vulnerabilities: a Safari remote code execution vulnerability, CVE-2017-2544 and a macOS kernel elevation of privilege vulnerability, CVE-2017-2545) in. CVE-2017-2545 is present in macOS IOGraphics components of the security vulnerability.
From the Internet-based source history view, this vulnerability as early as 1992, transplanted from Joe Pasqua of the code, and therefore this vulnerability is already in the Appleoperating systemin the presence of more than 25 years, almost effects Mac all version, while it is again possible to ignore the sandbox restrictions, directly from the sandbox into the kernel vulnerability.
In our 3 on game winning vulnerability responsibly reported to Apple after the Apple has been in the 5 on 15, release of macOS Sierra 10.12.5 fixes the vulnerability.
Looking for a browser can access the kernel driver
And Windows systems, the Safari browser sandbox restricted sandbox within the process can access the kernel driver, in order to reduce the kernel attack the face of the sandbox escaping attack impact, thus we performed the first step of the study is to find the in the browser sandbox can access the kernel driver interface.
In macOS, the system according to the following two sandbox rules file defines the Safari browser of the permission range.
/System/ Library/Sandbox/Profiles/system. sb
/System/Library/Frameworks/WebKit. framework/Versions/A/Resources/com. apple. WebProcess. sb
We are further concerned that the Safari browser can access the kernel driver type. In the system. sb file, we find such a rule:
(allow iokit-open (iokit-registry-entry-class “IOFramebufferSharedUserClient”))
This rule description The Safari browser can open IOFramebufferSharedUserClient this the drive interface. IOFramebufferSharedUserClient is IOGraphic kernel components to the user mode provides the interface. IOGraphic is a macOS on the core Foundation of driving, responsible for graphics and image processing tasks, 10.12.4 version on the corresponding IOGraphic the source package at: https://opensource.apple.com/source/IOGraphics/IOGraphics-514.10/ the. Since IOGraphic-related code is open source, then in the next step, we are on the IOGraphic conducted a code audit.
Attack surface
IOFramebufferSharedUserClient inherits from IOUserClient it. The user state can be by matching the name“IOFramebuff”IOService, then calling IOServiceOpen function obtained IOFramebufferSharedUserClient object of the port.
In the acquisition of an IOUserClient object port after we
Through the user mode API IOConnectCallMethod can trigger the kernel execution of this object ::externalMethod interface;
Through the user mode API IOConnectMapMemory can trigger the kernel execution of this object ::clientMemoryForType interface;
Through the user mode API IOConnectSetNotificationPort can trigger the kernel execution of this object ::registerNotificationPort interface.
In fact IOFramebufferSharedUserClient provides the user mode interface is very small, where the function IOFramebufferSharedUserClient::getNotificationSemaphore caught our attention. In the IOKit. framework, in fact, have a non-exported function io_connect_get_notification_semaphore, through this API, we can trigger the kernel to perform the corresponding IOUserClient object ::getNotificationSemaphore interface.
Vulnerability: getNotificationSemaphore UAF
We refer to IOFramebufferSharedUserClient::getNotificationSemaphore interface code
! [](/Article/UploadPic/2017-5/201752811827195. jpg? www. myhack58. com)
Thus, IOFramebufferSharedUserClient::getNotificationSemaphore directly invoked is it the owner that is IOFramebuffer instance getNotificationSemaphore interface.
! [](/Article/UploadPic/2017-5/201752811827577. jpg? www. myhack58. com)
Through above code we can see vblSemaphore is a global object members. vblSemaphore the initial value is 0. This function for the first time after the execution, the kernel calls the semaphore_create, create a semaphore, which gives vblSemaphore it. This latter function is performed again when it will be returned directly vblSemaphore it.
The problem is that the user mode call io_connect_get_notification_semaphore obtain a signal amount, can destroy the signal amount. In this case, the kernel vblSemaphore still pointing to an already destroyed to release the semaphore object.
When the user mode to continue the call io_connect_get_notification_semaphore get vblSemaphore and use the signal amount, it will trigger the UAF released after use.
Summary
IOUserClient Framework provides a large number of interfaces to the user state program. Due to historical reasons, IOFramebufferSharedUserClient still retains a rare interface. Although the user state of the IOKit. framework does not export the appropriate API, this interface can still call, we can put the kernel in the IOFramebuffer::getNotificationSemaphore of UAF problems, into the kernel address information leak and arbitrary code execution, the browser sandbox escape and elevation of privileges.