Hacker News new | ask | show | jobs
by abritishguy 3125 days ago
Just in case it is relevant for anyone here this is what our security team have established thus far:

- Can be mitigated by enabling the root user with a strong password

- Can be detected with `osquery` using `SELECT * FROM plist WHERE path = "/private/var/db/dslocal/nodes/Default/users/root.plist" AND key = "passwd" AND length(value) > 1;";`

- You can see what time the root account was enabled using `SELECT * FROM plist WHERE path = "/private/var/db/dslocal/nodes/Default/users/root.plist" WHERE key = "accountPolicyData";` then base 64 decoding that into a file and then running `plutil -convert xml1` and looking at the `passwordLastSetTime` field.

Note: osquery needs to be running with `sudo` but if you have it deployed across a fleet of macs as a daemon then it will be running with `sudo` anyway.

6 comments

osquery is not a built-in tool. You can get the same info with plutil(1):

  $ sudo plutil -p /private/var/db/dslocal/nodes/Default/users/root.plist
If I understand OP correctly, if passwd is a lone asterisk, then you haven't been exploited.

Edit: trying a little harder to dump accountPolicyData:

  $ sudo defaults read /private/var/db/dslocal/nodes/Default/users/root.plist accountPolicyData | grep -oE '[[:xdigit:]]+' | xxd -r -p
>if passwd is a lone asterisk, then you haven't been exploited.

At the risk of sounding a bit pedantic you can't really assume that, it's possible that somebody used this vulnerability, installed some sort of backdoor and then disabled the account to hide their tracks.

That's correct.
Bad news: I tried the exploit in my macOS Sierra installation and it didn't seem to work. However, the passwd entry on the output of your first command IS A LONE ASTERISK.

However I still can't login as root. This leads me to believe this behavior has always been there, and maybe the login methods just didn't allow an empty password.

This is very normal in 'nix' systems. '' indicates a locked account. (I've given up figuring out how to escape an asterisk)

ex:

  daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
  operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
  bin:*:3:7::0:0:Binaries Commands and Source:/:/usr/sbin/nologin
  tty:*:4:65533::0:0:Tty Sandbox:/:/usr/sbin/nologin
If the OS is letting you in with a '*'in the encrypted password field, something is very very wrong.
I'm confused, why do you have to escape an asterisk?
He's stuck inside
Markdown in HN comments.
Famous last words of a Roman centurion.
Nah, I've never seen them do worse than knock people out. Probably the next thing the centurion said was "Ow, what hit me!".
wildcard.
Only High Sierra is affected.
`sudo dscl . -read Users/root accountPolicyData`
When you do this you'll get the creationTime and passwordLastSetTime as seconds since the 'epoch' – January 1, 1970, 00:00:00 (UTC). These are numbers like 1474441704.265237 which aren't very easy for a human to read :-)

To convert this into a human-readable date and time, open a terminal and do this:

  python

  >>> import time

  >>> time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(1474441704.265237))
You'll get something like 'Wed, 21 Sep 2016 07:08:24'

(I'm sure you can do this in other languages than python...)

If you're already in the terminal you could instead enter

  date -r 1474441704
This is a much better answer!
One of my Macs is showing a root password change date of Nov 10th 2017. I can't explain that, so I'm reinstalling now. It did have sshd enabled and remotely accessible, though I thought root login was prohibited.

If I understood correctly, this particular bug was only exploitable from the GUI and this machine hasn't been away from home, so it's likely this isn't related, but posting here, in case it's part of a bigger picture.

OK, I guess when doing OP's root trick, the root user gets activated/created, and that's that's when the PW gets set to empty. I guess that's where my passwordLastSetTime comes from.
This works remotely as well (although not through SSH, obviously).
possibly the same timestamp here: 1510300538.767916 'Fri, 10 Nov 2017 04:55:38'
Oh wow. Is there any other explanation for this other than this having been exploited in the wild for almost three weeks? Or maybe someone just tried to log in over SSH to exploit some other weakness (something like predictable SSH passwords on jailbroken iOS devices), and happened to create the root user on your machine?

Did you also have sshd running, and do you know what kind of network you were using at the time?

My root pw passwordLastSetTime says this morning.. the fuck??
Wait, isn't the point of having root you can erase your traces? Are these logs immutable, even to root? That sounds pretty next level.. and how do I trust the tools?

As far as I know, possibility of root = root = pwn, game over, time to format.

System Integrity Protection (SIP)[1] does prevent even the root user from modifying some system files[2]. It seems possible, at least in principle, to protect system logs from modification by user root. In practice, I think most system logs are stored in /var, and that part of the directory tree does not appear to be protected by SIP (but I hope I'm wrong!)

[1] https://support.apple.com/en-us/HT204899

[2] Unless/until you reboot to a diagnostic monitor on a special partition (which requires pressing command-R from a local keyboard during the POST), then run a command to disable SIP, and then reboot again. Continuity Activation Tool requires users to perform this step as part of the install process to allow installation of Bluetooth drivers not originally signed by Apple.

A motivated and knowledgeable adversary could most likely load a custom kext to bypass the integrity measures. Am I right?
You can't load unsigned kexts anymore, due to that same SIP. It's a pain in the gonads when hacking your own kexts. I had forgotten about this, but it does indeed allow for a system that leaves an audit trail which cannot be hidden, even by root.

However, user labcomputer is right, I doubt that applies to the solutions proposed by OP here. Well, I'm certain: root can switch out the shell or terminal emulator binary itself and have it lie about executing those commands and return something trustworthy. One way or another, to truly check this, you'd need an immutable audit log (probably not currently available), AND a reboot into safe mode or a mount as a HDD onto a safe system.

> Can be mitigated by enabling the root user with a strong password

Instructions from Apple: https://support.apple.com/en-us/HT204012

And if you're thinking that manually disabling root might also fix this, it won't. You have to leave root enabled.
Security update now available: https://support.apple.com/en-us/HT208315
You can also get the password last set time with:

    sudo dscl . -readpl "/Users/dan.koepke" accountPolicyData passwordLastSetTime
ok dan...
Excellent! Thanks for sharing
apple have a security update out now: https://support.apple.com/en-au/HT208315