Blocking logins to the root account on macOS High Sierra
A security vulnerability was discovered in macOS High Sierra today, where you could enable and log into the root account without providing a password.
Update 11-29-2017: Apple has released Security Update 2017-001 to fix this issue. Please install this update as soon as possible.
Update 11-30-2017: Apple is now automatically installing Security Update 2017-001 on vulnerable Macs.
To address this this issue until Apple releases an update to fix it, there’s two steps you can take which will block logins to the root account:
- Set a password for the root account on your Mac
- Change the root’s account’s login shell to /usr/bin/false
When you set the root account’s login shell to /usr/bin/false, the shell is changed to point to a command that does nothing except return a status code which reports an error. The login process will interpret that error status code as being a failed login, so it will stop the login process at that point and prompt for the password again.
Since the login process will always receive the error code from the false command, the login process will never succeed. For more details, see below the jump.
I’ve written a script which does the following:
- Sets the root account’s password to a random 32 character long password
- Sets the root account’s login shell to /usr/bin/false
Update 11-28-2017: After more testing of my script, I noticed one side effect of setting the root account’s password was that the root account was now enabled. I’ve added a section to the script to disable the root account again using Apple’s dsenableroot tool.
An admin user’s authentication is needed to disable the root account using the dsenableroot tool, so the script is using the just-set randomly generated password for the root account to provide the necessary authentication to disable the root account.
Never mind! It looks like disabling root just re-introduces the vulnerability all over again. Reverting my script changes.
It’s available on GitHub via the link below:
https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/block_root_account_login
This script is also available as a payload-free installer package, stored as a .zip file in the payload-free_package directory.
The script is also available here:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
ERROR=0 | |
# Set root password to randomized 32 character long password | |
rootpassword=$(openssl rand -base64 32) | |
/usr/bin/dscl . -passwd /Users/root "$rootpassword" | |
# Disable root login by setting root's shell to /usr/bin/false. | |
# The original UserShell value is as follows: | |
# | |
# /bin/sh | |
# | |
# To revert it back to /bin/sh, run the following command: | |
# /usr/bin/dscl . -change /Users/root UserShell /usr/bin/false /bin/sh | |
rootshell=$(/usr/bin/dscl . -read /Users/root UserShell | awk '{print $2}') | |
if [[ -z "$rootshell" ]]; then | |
# If root shell is blank or otherwise not set, | |
# use dscl to set /usr/bin/false as the shell. | |
echo "Setting blank root shell to /usr/bin/false" | |
/usr/bin/dscl . -create /Users/root UserShell /usr/bin/false | |
else | |
# If root shell is set to an existing value, use dscl | |
# to change the shell from the existing value and set | |
# /usr/bin/false as the shell. | |
echo "Changing root shell from $rootshell to /usr/bin/false" | |
/usr/bin/dscl . -change /Users/root UserShell "$rootshell" /usr/bin/false | |
fi | |
exit "$ERROR" |
would setting a password lock on root also work?
( such as dscl . -create /Users/root Password ‘*’ ) — I think that is ? or less equivalent to the traditional ‘passwd -l’ in older unix/linux systems
First thing I do on a new Mac is enable the root account and set a real password for it.
Eff you, Apple. Only idiots working on macOS nowadays, it seems.
That’s hostile, and not useful.
I beg to differ. (1) It’s useful because enabling the root account and setting a password for it is a good thing, and in this case it would have thwarted any iamroot attack; (2) Apple have long abandoned their dedicated macOS development team, which in itself was a big slap in the face of all Mac users, and for years since the OS has been a bug-ridden mess, and it’s getting worse with every release, it seems. So Apple has basically been saying “eff you” to its customers, and they deserve every bit of ire that’s currently thrown at them, for iamroot, but also for all the rest of their failures.
Apparently the problem also affects all system accounts, not just root.
Most have the shell set to /usr/bin/false but _mbsetupuser and _uucp don’t?
thanks very much for this.
Thanks for this. Of course after you posted your fix, Apple plugged up the security hole. I appreciate all you do, and I look forward to attending your sessions at JNUC next year (if you will be presenting).