This post is the first part of a series of Safari sandbox escapes I found on macOS. This bug was found on High Sierra (10.13.x) two years ago.
I wrote about this bug once. Thought it was useless, and Apple wouldn't care about it, so I published the details before the response. Then the security team asked me to take it down because they were still working on it.
I've also talked about it on TyphoonCon 2019. I did not release the slides because I had some 0days at the time that shared the similar pattern: triggering XSS in a privileged WebView via sandbox reachable IPCs. This PoC worked on all Mojave until Catalina unintentionally broke some part of it.
Now here's the slides. The git history is still there so it's been public for quite a while:
You may have the experience that, when you hit media key ▶️ on mac, the iTunes shows up. It is so annoying.

With a little reverse engineering, I found that process rcd is responsible for this hotkey:
It sents the following XPC message to mediaremoted, activating the registered media player (even if not previous running).
The mediaremoted is responsible for the global music player control.

The MRXPC_MESSAGE_ID_KEY of the message controls routing, deciding which handleXPCMessage:fromClient: method should be invoked.

Finally the message reaches here. It searches installed application that matches a certain bundle identifier and then launches it.
I had a deja vu about this service. This mach service is reachable in Safari sandbox.
What about crafting a message to launch arbitrary application?
There is an MRXPC_NOWPLAYING_PLAYER_PATH_DATA_KEY in the message, which is a serialized buffer of an MRNowPlayingPlayerPathProtobuf object.
This class has three important properties: origin, client, and player. The field client points to an _MRNowPlayingClientProtobuf class, who has a bundleIdentifier string. This parameter will be passed to MSVLaunchApplication and we can spoof it. To craft the desired objects, some private APIs of MediaRemote can help.
MRNowPlayingClientCreateto create a client with arbitrary bundle idMRMediaRemoteSendCommandToClientto serialize and send the XPC message
Now let's pop a Calculator from Safari sandbox in only few lines of code!

Another interesting fact about it is that MediaRemote has side effects on iOS background apps. Usually third party apps have limited background execution time:
Extending Your App's Background Execution Time
If you periodically abuse this piece of code and spoof the bundle id to your own app, MediaRemote will grant you unlimited background time. This trick does not require any special entitlements, playing media quietly, or GPS. When you have more than one app you can even implement watchdogs for each other. Once activated, they become immortal unless you turn off the phone.
This bug has been completly patched after I gave the talk on TyphoonCon.
Yeah, at this point I can launch arbitrary installed applications, even Xcode. But it makes no sense at all if you can't execute a downloaded payload. Back then I couldn't find a way to register a custom app, but lately I learned something interesting that might bring it back to life.
Here is another useless sandbox voilation I reported to Apple. Apple did not publish any advisory about it. It's just another service that is reachable from Safari sandbox:
/System/Library/Frameworks/ApplicationServices.framework/ Versions/A/Frameworks/HIServices.framework/Versions/A/XPCServices/ com.apple.hiservices-xpcservice.xpc/Contents/MacOS/com.apple.hiservices-xpcservice
It looks like a legacy component related to input methods. The message is simply a remote procedure call to the service:
HIS_XPC_SELECTOR is the selector of the remote method (validated by a trusted list, of course). They are all implemented by XPCRequestHandler.
And you can find the corresponding client APIs in HIService.framework
In SendAppleEventToSystemProcess you can just reboot the system with an AppleEvent without any privilege, even inside the renderer sandbox.
_HIS_XPC_CFPreferencesCopyValue does not validate the path at all so you can read arbitrary plist file. This guided me to discover a real long standing CoreFoundation bug.
As for the HIS_XPC_RevealFileInFinder you can locate arbitrary file url in Finder app. I noticed that I can just specify a NFS share (/net/hostname/blah) like this:
There was a GateKeeper bypass at the time (<10.14.5) that remote contents from NFS share have no quarantine flag:
Here is the interesting part. When finder locates this remote resource, it automatically registers the app to the LaunchService.

Now let's go back to the MediaRemote framework. It can only launch known apps.
After mounting the NFS volume I can confirm that LSCopyApplicationURLsForBundleIdentifier does return the expected remote URL in my test case. It should be a full sandbox escape now if everything goes well. But it's very strange that LSCopyApplicationURLsForBundleIdentifier doesn't work when it's in mediaremoted.

I don't feel like digging deeper since it's an outdated bug.
In the incoming posts (hopefully) I am gonna reveal 3 more different macOS Safari sandbox escapes abusing inter process XSS. Yup. XSS. I meant it. Stay tuned.
