Vulnerability 10.13 - Root

rderewianko
Valued Contributor II

Since this is out there, and the original finder did not go through responsible disclosure. Figured i'd post it here so at least admins are aware.
https://twitter.com/lemiorhan/status/935578694541770752

Dear @AppleSupport, we noticed a HUGE security issue at MacOS High Sierra. Anyone can login as "root" with empty password after clicking on login button several times. Are you aware of it @Apple?

This works on User & Admin accounts.

That being said, if you enable root and have a password on it. You're not affected. If you don't it'll enable root and create an account.

Enabling a root password however may cause you more tech debt down the line.

82 REPLIES 82

dgreening
Valued Contributor II

Confirmed... Escalated with my Apple SE...

Taylor_Armstron
Valued Contributor

facepalm.

brytox
New Contributor III

Just tried this out and not only does it let you login as root but even if you have the account disabled, it reenables it again.

jlmorton
New Contributor

Did this and confirmed it happens here as well.

https://twitter.com/bruienne/status/935607437905809410

dgreening
Valued Contributor II

Might be good for someone to post how to enable root, set a password, and disable it again for those not in the know. ;)

stedrow
New Contributor

From what we've tested so far with macOS High Sierra 10.13 and FileVault 2:

  1. When a computer boots it goes to the FileVault 2 specific login screen which won't allow you to login as the root user.
  2. If a computer logs into an account then locks the computer/sleeps the computer you get a blank username/password login, using root:blank password works in this instance and gets you into the computer, you can then use a terminal to access FileVault 2 user's home directories. It appears that the drive may not be re-encrypting on lock/sleep?

signetmac
Contributor

I can confirm that if you have already set a root password, this vulnerability will not work.

I'd already set it on my own computer and could not validate the exploit until I went to another user's computer. Then I generated a random 30 character password and pushed it to all our 10.13 computers that don't already have a root pass set.

rderewianko
Valued Contributor II

So from macadmins slack, a way to stop it from working would be to run

/usr/bin/dscl . -create /Users/root UserShell /usr/bin/false

rderewianko
Valued Contributor II

The above being said, there are ways to still allow a user to elevate their privileges.. This is not a fix but a band aide.

The best fix is enabling a root password..

M0J077
New Contributor II

If anyone is testing this, it will enable the Root account on your machine, this will enable you to log into the machine as Root with no Password. Make sure to disable the account after testing: https://support.apple.com/en-us/HT204012

bentoms
Release Candidate Programs Tester

Just to second that @signetmac posted https://www.jamf.com/jamf-nation/discussions/26290/vulnerability-10-13-root#responseChild156530

Setting the shell to /usr/bin/false is a partial fix, sadly.

Also, root can be enabled as a non-admin too.. & without GUI interaction (as in, you can write a script to make use of the exploit)

mike_paul
Contributor III
Contributor III

Some possible means to mitigate things would be to push a Login Window config profile forcing "List of users able to use these computers" and un-check the box for "Show Other" they should not be able to login as root. FileVault login screen is already just the enabled users but if people log out of a computer instead of shutdown/start up you can have a login window that shows "Other", or if its unencrypted it may just show the blank Username/Password fields. This method does nothing for people logged into the computer enabling this via System Preferences.

Also if root is enabled you can push out a policy with the Local Accounts payload setting the root accounts password to something only known to IT and this would disable the root login with blank password.

steve_summers
Contributor III

Any idea if this is applicable to 10.13 .1 OR just 10.13? Has that determination been made yet...?

jamesandre
Contributor

Would doing the following resolve the vulnerability... (I grabbed it from this thread - https://www.jamf.com/jamf-nation/discussions/3340/disable-root )

remote the AuthenticationAuthority from the user's account

dscl . delete /Users/root AuthenticationAuthority

Put a single asterisk in the password entry, thus locking the acount.

dscl . -create /Users/root Password '*'

Disable root login by setting root's shell to /usr/bin/false

dscl . -create /Users/root UserShell /usr/bin/false

jamesandre
Contributor

@steve.summers 10.13.1 is vulnerable too.

easyedc
Valued Contributor II

Stupid question - anyone tried this on Sierra?

john_sherrod
Contributor II

I just tried this in Sierra and could not replicate it.

IQ-MacAdmin
New Contributor II

Not good. I just updated some users to High Sierra.

rderewianko
Valued Contributor II

This only happens on 10.13+

I tried to blog part of the solution process here.

elund
New Contributor III

Would this be a useable solution to run via Files and Processes / Execute Command in a Policy?

dscl . -passwd /Users/root 'YourPasswordHere'; dsenableroot -d -u root -p 'YourPasswordHere'

rupenv
New Contributor

I would read this:

https://derflounder.wordpress.com/2017/11/28/blocking-logins-to-the-root-account-on-macos-high-sierra/

charlesteese-mf
New Contributor II

I've written this script to randomize the root pass:

#!/usr/bin/expect
set NewPassword [exec openssl rand -base64 64]

spawn passwd -u root
expect "assword:"
send "$NewPassword
"
expect "password:"
send "$NewPassword
"

puts "
Password Changed."
expect eof
exit 0

pbenware1
Release Candidate Programs Tester

This appears in 10.13.1 and the 10.13.2 beta 17c79a (current until today's beta update) as well.

guidotti
Contributor II

Changing the root password in the manner described by Rich has absolutely no impact on the Jamf Binary to run as 'root', correct?

rderewianko
Valued Contributor II

Correct. The binary runs under the service user you have it set to in the jss.

signetmac
Contributor

@guidotti Correct. Almost everything on your system that doesn't run as a logged in user, is kicked off by user 0 .... root. If Rich's solution kept the jamf launchdaemons from working, then the whole system would be hosed.

ajamal
New Contributor

I tested the script from https://derflounder.wordpress.com/2017/11/28/blocking-logins-to-the-root-account-on-macos-high-sierra/ on a few machines and I'm getting this error on some of them - any ideas what it means exactly?

Script result: <dscl_cmd> DS Error: -14165 (eDSAuthPasswordQualityCheckFailed)<br/>passwd: DS error: eDSAuthPasswordQualityCheckFailed<br/>Changing root shell from /usr/local/bin/zsh to /usr/bin/false<br/>

EDIT: Figured it out, changed script to a hardcoded password that will always pass Apple's (TERRIBLE) password complexity rules

adriandupre
New Contributor

Thoughts on creating a smart group to identify vulnerable systems? (OS >= 10.13 and root password is null)

I'd settle for a quick check to detect if the password is null...

stas21
New Contributor

charlesteese-mfj's script seems to be working for me

dgreening
Valued Contributor II

Here is how I am solving it by setting a root password (using encrypted strings) as well as performing a test to make sure a password is set, and based on that, erroring out or leaving a touch file for an ext attr to pick up:

#!/bin/sh
# This script will set the root password to a known value via encrypted string, check to see that a password is set, and leave a cookie.

#Decrypt String Function for account passwords
function DecryptString() {
    # Usage: ~$ DecryptString "Encrypted String" "Salt" "Passphrase"
    echo "${1}" | /usr/bin/openssl enc -aes256 -d -a -A -S "${2}" -k "${3}"
}

#Encrypted strings for passwords
rootpwd=$( DecryptString "$4" salthere passphrasehere )

#Enable root user and set password
dscl . -passwd /Users/root '$rootpwd'

#Check if root password is enabled
rootpwdtest=$( dscl . -read /Users/root Password )
if [ "$rootpwdtest" == "Password: ********" ]; then
    echo "Root password set. Proceeding."
else
    echo "Root password not set. Exit 1."
    exit 1
fi

#Check for Management directory and create and place touchfile
managementDir="/Library/Management"
touchFile="/Library/Management/.macOSHighSierraRootPassFix"

if [ -d "${managementDir}" ]; then
                    /usr/bin/touch "${touchFile}"
                else
                    mkdir -p "${managementDir}"
                    /usr/bin/touch "${touchFile}"
fi
exit 0

nojorge
New Contributor

Does anyone know if this is remotely exploitable on computers with Casper installed? Or would it require physical access to the machine?

MacSysAdmin
Contributor

I've tried just changing the root password and disabling the account in the GUI and the settings take. However they do not appear to survive restart.

easyedc
Valued Contributor II

@BostonMac I believe you have to leave the root user enabled with your password. I haven’t tested but think I read that.

rderewianko
Valued Contributor II

@BostonMac , @easyedc is correct if you do it via gui it's gotta still be enabled.

stas21
New Contributor

@charlesteese-mfj I am thinking of using your script, but can I later overwrite randomly created root password into something else of my choosing?

signetmac
Contributor

@nojorge If you have admin users enabled for Remote Management (ARD) or Screen Sharing, it seems that it can be exploited remotely.

Twitter link to Patrick Wardle's test results

rodgerramjet
New Contributor

@adriandupre I just put together this extension attribute that returns if the root password is set or not.

#!/bin/bash

RESULT=$(sudo dscl . -read /Users/root Password)

if [[ $RESULT == "Password: ********" ]]; then
  echo "<result>Root password set</result>"
elif [[ $RESULT == "Password: *" ]]; then
  echo "<result>No root password set</result>"
else
  echo "<result>Unknown</result>"
fi

Then I push @rtrouton's package to any users which does not have "Root password set" and are on 10.13.

I have also set it up to do a recon after the package installs, so the extension attribute should immediately get updated and fall out of scope.

geoffrepoli
Contributor

@rodgerramjet ,

FYI: that will return the first result if the root user exists at all, regardless of its password. An enabled root user with a blank pass will appear there.

Using something like the following could pare down the most-exposed Macs better, but continue reading, as I still don't think this is worth the time:

#!/usr/bin/env bash

if [[ $(dscl . read /users/root Password | awk '{print $2}') = '********' ]]; then
  if dscl . authonly root '' &>/dev/null; then
    RESULT="Root Enabled - No Pass"
  else
    RESULT="Root Enabled - With Pass"
  fi
else
  RESULT="Root Disabled"
fi

echo "<result>$RESULT</result>"

The problem here is that while you can now determine whether root is enabled with or without a password, you cannot determine whether or not that root was enabled legitimately by the user or through the Authorization Plugin exploit (since you can also create any password you want in that prompt, it does not have to be blank).

The safer move is to just randomize all root passwords on all 10.13 machines and let the edge-case users submit a ticket when they find they cant su root anymore (which they shouldn't be doing anyway -- tell them to just use sudo -s or sudo su! ). The following will pre-emptively create a 32-character cryptographically-secure pseudo-random (CSPRNG) passphrase for root:

#!/usr/bin/env bash

dscl . passwd /users/root "$(env LC_CTYPE=C tr -dc 'A-Za-z0-9_ !@#$%^&*()-+=' < /dev/urandom | head -c 32)"

Obviously, every environment is different, and this is not a hard and fast rule; there could be some extenuating circumstances in your particular environment that require an enabled root user and the productivity impact on blowing all out root user passwords is a no-go. Keep in mind, however, that you're essentially unable to differentiate between whether that root user with a password was made legitimately or by an attacker creating a backdoor.

Note: Why I'm generating a random string by redirecting /dev/urandom to tr rather than use openssl rand: https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/. For the majority of cases, both are plenty secure. This is NSA-level threat surface stuff. But I would rather share the safest of the two to make the command applicable to the most environments as possible.

tsossong
New Contributor III

I don't understand why we go headless chicken mode on this issue. As long as we just need to delete one file to get Admin-rights (and this is an issue since Mac OS X came out) we don't need to try to secure macOS.