Monday, 22 January 2007

Apple UserNotificationCenter Privilege Escalation Vulnerability

Vendor:: Apple
Application:: Mac OS X
Disclosed:: 22-01-07
Description:: UserNotificationCenter retains wheel privileges on execution time, and still has a UID associated with the current user. Because of this, it> will attempt to run any InputManager provided by the user. Code within the input manager will run under wheel privileges. In combination with diskutil and a wheel-writable setuid binary, this allows unprivileged users to gain root privileges.
Exploit::
$ ruby bug-files/MOAB-22-01-2007.rb 0
++ Welcome to Pwndertino...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4513 100 4513 0 0 4165 0 0:00:01 0:00:01 --:--:-- 12642
r00tim/
r00tim/Info
r00tim/r00tim.bundle/
r00tim/r00tim.bundle/Contents/
r00tim/r00tim.bundle/Contents/Info.plist
r00tim/r00tim.bundle/Contents/MacOS/
r00tim/r00tim.bundle/Contents/MacOS/r00tim
r00tim/r00tim.bundle/Contents/Resources/
r00tim/r00tim.bundle/Contents/Resources/English.lproj/
r00tim/r00tim.bundle/Contents/Resources/English.lproj/InfoPlist.strings
$ /Applications/System\ Preferences.app/Contents/Resources/installAssistant
sh-2.05b# id
uid=0(root) gid=0(wheel) groups=0(wheel), 81(appserveradm), 79(appserverusr), 80(admin)
A CFUserNotification object presents a simple dialog on the screen and optionally receives feedback from the user. The contents of the dialog can include a header, a message, an icon, text fields, a pop-up button, radio buttons or checkboxes, and up to three ordinary buttons. Use CFUserNotification in processes that do not otherwise have user interfaces, but may need occasional interaction with the user.
The API involved in the handling of these dialogs, CFUserNotificationSendRequest(), works by sending a Mach message to a port named "com.apple.UNCUserNotification".
---- UserNotification-17.1/Libunc/UNCUserNotification.c
#define NOTIFICATION_PORT_NAME "com.apple.UNCUserNotification"
#define NOTIFICATION_PORT_NAME_OLD "UNCUserNotification"
---- UserNotification-17.1/Libunc/UNCUserNotification.c
Basically, this vulnerability makes every "denial of service issue" leading to a so-called 'crash' usable for escalating privileges. Elevating to root from wheel is as simple as replacing the installAssistant binary with a setuid(0) shell wrapper and running diskutil to "repair" the permissions, setting the setuid bit back. diskutil requires the user to have admin group privileges, but due to the fact that it's being executed in the context of the InputManager (which, again, runs with wheel privileges) the issue can be successfully exploited by fully unprivileged users.
Actually, /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow is responsible
for operating the com.apple.UNCUserNotification port. For example, making a call to CFUserNotificationDisplayAlert() will lead to a call of CFUserNotificationSendRequest() which then interacts with the Mach port. Upon connection, UserNotificationCenter.app application is launched to handle the notification requests. In essence, the notification center application is launched on demand, at any time by any process.
Although, the application retains wheel privileges on execution time, and still has a UID associated with the current user. Because of this, UserNotificationCenter.app will attempt to run any InputManager that the user has placed into ~/Library/InputManagers. The code that is run within the input manager will do so under wheel privileges. In combination with diskutil and a wheel-writable setuid binary, this allows unprivileged users to gain root privileges.
MORE...
Prevention:: Limit user access to ~/Library/InputManagers/. Prevent use of diskutil (modification of permissions of the installAssistant binary isn't enough as the tool will set the permissions back).
Links::
PoC:: MOAB-22-01-2007.rb
MOAB-22-01-2007

No comments: