Privilege Escalation in Install.framework
The private Install.framework has a few helper executables in /System/Library/PrivateFrameworks/Install.framework/Resources, one of which is suid root. Taking a look at it, it can be seen that it's vending an objective-c Distributed Object. The main function immediately temporarily drops privs doing seteuid(getuid()); setegid(getgid()); then reads line from stdin. It passes this to NSConnection rootProxyForConnectionWithRegisteredName to lookup that name in the DO namespace and create a proxy to connect to it via. It then allocates an IFInstallRunner which in its init method vends itself using a name made up of its pid, time() and random(). It then calls the setRunnerConnectionName method on the proxy to tell it the IFInstallRunner's DO name so that whoever ran the runner can connect to the IFInstallRunner. The IFRunnerMessaging protocol tells us the methods and prototypes of the remote methods we can invoke on the IFInstallRunner. Most of the methods begin with a call to processKey which will set the euid back to root if the process can provide a valid admin authorization reference from authd. Otherwise the euid will remain equal to the uid and the methods (like movePath, touchPath etc) will only run with the privs of the user. The methods then mostly end with a call to restoreUIDs which will drop back to euid==uid if we did temporarily regain root privs (with the auth ref). Not all methods we can invoke are like that though. IFInstallRunner setExternalAuthorizationRef calls seteuid(0);setegid(0); to regain root privs without requiring any auth. It then calls AuthorizationCreateFromExternalForm passing the bytes of an NSData we give it. This means that if we can craft an auth ref that authd will accept, we can gain root privs.