As Apple fixes macOS root password hole, here's what went wrong

While you patch your Mac, take a look at what upset the Apple cart this week

Code dive Apple has emitted an emergency software patch to address the trivial to exploit vulnerability in macOS High Sierra, version 10.13.1, that allowed miscreants to log into Macs as administrators without passwords and let any app gain root privileges.

The Cupertino iPhone giant kicked out the fix, Security Update 2017-001, today after word of the bug and methods to exploit it ran wild over the internet. It was discussed on Apple's developer support forums two weeks ago, and hit Twitter on Tuesday.

The patch addresses a flaw in its operating system that allows anyone sitting at a Mac to gain administrator access by entering "root" as the username and leaving the password box blank in authentication prompts. This works when altering system settings, logging into the machine, and accessing it remotely via VNC, RDP, screen sharing, and so on. It can also be used to log into system accounts, such as _uucp, and via the command line, which is useful for malware seeking to gain superuser privileges.

If you're running High Sierra, you're urged to install the update as soon as possible.

"An attacker may be able to bypass administrator authentication without supplying the administrator’s password," read Apple's description of the flaw. "A logic error existed in the validation of credentials. This was addressed with improved credential validation."

Grab a disassembler and jump in

Now, let's take a look at this so-called #IAmRoot flaw, and how it affected High Sierra. The problem starts with the fact that the powerful root account is disabled by default. Essentially, it appears to be a fumble in some internal error code handling, leading to the enabling of root with a blank password.

When the OS tries to authenticate a user, in this case root, the security daemon opendirectoryd calls an internal function called odm_RecordVerifyPassword. This attempts to retrieve the shadow hash password for the account to check against the supplied password. Since root is disabled, and has no shadow hash entry, the subroutine returns a fail code. So far, so good.

Seeing as that shadow hash lookup failed, opendirectoryd next tries to retrieve and check a crypt password for the account using od_verify_crypt_password. Weirdly, that function returns the value 0x1, signaling it was successful, and rather than bail out and deny access, the code falls through to function calls that upgrade the crypt password to a shadow hash and stores it for the account.

That means the blank password is stored as the root account's password. This works for any system account that has its login disabled.

Reverse-engineered opendirectoryd code showing the heart of the bug, with od_verify_crypt_password returning 0x1 and screwing up the 0x0 check ... Source: Patrick Wardle

Mac security specialist and Synack chief researcher Patrick Wardle explained the programming cockup in more detail, summarizing it as:

For accounts that are disabled (i.e. don't have 'shadowhash' data) macOS will attempt to perform an upgrade. During this upgrade, od_verify_crypt_password returns a non-zero value. The user (or attacked) specified password is then 'upgraded' and saved for the account.

It appears that od_verify_crypt_password should fail (maybe it does and the check of the return code for 0x0 is just inverted?) Or perhaps the call to odm_RecordVerifyPassword assumes can only be called in a validated/authenticated context?

Fortunately, Apple has addressed the vulnerability. The fact that it was able to slip into production, however, could give fans, particularly in the enterprise market Apple is so keen to grab, pause when it comes to deploying macOS 10.13.

“We greatly regret this error and we apologize to all Mac users,” Apple said in a statement. “Our customers deserve better. We are auditing our development processes to help prevent this from happening again.” ?


Biting the hand that feeds IT ? 1998–2017