Mac OSX Password Cracking

Mac OSX Password Cracking

TL;DR: There are several ways to enumerate information from a Mac shell and to collect encrypted credentials for OSX password cracking.

Problem and Rationale

During a recent assessment the client had close to 10,000 Mac OSX systems throughout their global presence. All of these Macs were authenticating to Active Directory and allowed all logged in users local admin rights; via a misconfigured sudoers rule. Since this blog is lacking any real reference material specifically for OSX, I figured I would detail the information gathering and attacks I preformed during the assessment.

Attacks and Methodology

The default base install of Apple OSX will allow the primary user configured on that workstation to sudo to  root. When Active Directory backed authentication is used, newly logged in users can inherit the primary user role if system defaults are not changed. This would effectively make all domain users local admins on all of the affected Macs. This is good news since root level permission is required to pull local password hashes.

If the OSX systems do not use AD authentication don’t fret. By default the SSH server is enabled and it does not have any lock outs on failed login attempts. If all else fails, physical attacks still work very well against OSX. Just walk up to one and hold Command+S during boot to log into a single user root terminal. If the system isn’t using full disk encryption you can simply copy files over to a USB flash drive.

Once you have a terminal on a Mac, it’s good to check user and group memberships. Again, if the user is a part of the admin group they can sudo by default; and if they are part of the wheel group they are effectively root.The following is a list of useful commands to use when in a terminal:

dscl . -list /Users #List local users
dscl . -list /Groups #List local groups
dscl . -read /Groups/<Groupname> #List local group membership
dscl . -read /Users/<usersname> #List a user’s information and settings

Note: The commands above all have a target of ‘.’ or ‘localhost’. If the system is connected to Active Directory it can be queried in a similar manner.To list all Domain Admins use the following command:

dscl /Active\ Directory/<domain>/<domain.local> -list /Groups/Domain\ Admins

If the user doesn’t have sudo or root privileges, you can try to elevate to root privileges with one of several local privilege escalation vulnerabilities. Some recent noteworthy options include CVE-2015-5889, CVE-2015-1130, or just use some of the Yosemite environment variables like the following:

echo 'echo "$(whoami) ALL=(ALL) NOPASSWD:ALL" >&3' | DYLD_PRINT_TO_FILE=/etc/sudoers newgrp; sudo -s

If the device is up to date on its patches about all one can do is some file pillaging. The two things I would note are Apple scripts (.scpt) and property list (.plist) files are very popular in OSX. Both file types are stored to disk as binary files. As such they need to be converted back to ASCII, to be human readable.
To view the contents of an Apple script file use a command like:

osadecode logon.scpt

To convert a .plist file from binary to its native XML use a command like:

plutil -convert xml1 /path/to/file.plist

Note: plutil will convert files in place, so take care to make copies of files you’re working with.Alternatively the plist files can be exfiltrated to Kali and converted to XML using the libplist-utils library. The conversion command might look something like this:

plistutil -i user.plist -o user.xml

If root level access is acquired, we can go straight after the local user’s plist files. Each user’s plist file contains their individual settings and their encrypted credentials. The directory that contains all local users’ plist files is /private/var/db/dslocal/nodes/Default/users/.
If another user is currently logged into the system, the user’s keychain can be dumped by root. This will provide clear text access to all saved credentials, iCloud keys, the file vault encryption key, and the user’s clear text password. To dump the users keychain use a security command like:

security dump-keychain -d /Users/<user>/Library/Keychains/login.keychain

WARNING: In newer versions of OSX this will generate a dialog box on the user’s screen. This will obviously alert the user and only produce usable output if the user accepts.

OSX Password Cracking

There are several ways to gain access to the encrypted shadow data, which is needed to conduct OSX password cracking. Two of them have already been mentioned above. If you have root access preform a dscl . -read /Users/<user> or if you grab the users plist file from /private/var/db/dslocal/nodes/Default/users/ and covert it to XML, there will be a XML element called ShadowHashData. The ShadowHashData is a base64 encoded blob containing a plist file with the base64 encoded entropy, salt, and iterations within it.

Note: Before the base64 can be cleanly decoded in each of these steps, the XML elements, spaces, and line breaks will need to be removed manually.
The first step is to extract the plist file form the shadow hash data and convert it back to XML. This can be done with the following commands:

echo "<hash data>" | base64 -D > shadowhash
file shadowhash
plutil -convert xml1 shadowhash

Next cleanup and convert the base64 encoded entropy to hex format. This can be done with the following commands:

echo "<entropy data>" | base64 -D > entropy
file entropy
xxd entropy

Third cleanup and convert the base64 encoded salt to hex format. This can be completed with the following set of commands:

echo "<salt data>" | base64 -D > salt
file salt
xxd salt

Next we can put all the hex value strings together into the following hashcat format (7100).

$ml$<iterations>$<salt>$<entropy>

Lastly put that baby in hashcat as OSX v10.8/v10.9 and watch it burn.

./hashcat-cli64.app -m 7100 hash.txt wordlist.txt

As Always:

ICBfICAgXyAgICAgICAgICAgIF8gICAgICBfX19fXyBfICAgICAgICAgICAgX19fXyAgXyAgICAg
ICAgICAgICAgICAgIF8gICANCiB8IHwgfCB8IF9fIF8gIF9fX3wgfCBfXyB8XyAgIF98IHxfXyAg
IF9fXyAgfCAgXyBcfCB8IF9fIF8gXyBfXyAgIF9fX3wgfF8gDQogfCB8X3wgfC8gX2AgfC8gX198
IHwvIC8gICB8IHwgfCAnXyBcIC8gXyBcIHwgfF8pIHwgfC8gX2AgfCAnXyBcIC8gXyBcIF9ffA0K
IHwgIF8gIHwgKF98IHwgKF9ffCAgIDwgICAgfCB8IHwgfCB8IHwgIF9fLyB8ICBfXy98IHwgKF98
IHwgfCB8IHwgIF9fLyB8XyANCiB8X3wgfF98XF9fLF98XF9fX3xffFxfXCAgIHxffCB8X3wgfF98
XF9fX3wgfF98ICAgfF98XF9fLF98X3wgfF98XF9fX3xcX198

My Top Three user account design Pet Peeves

In this internet infused world we live in today, it’s not uncommon for user to have to remember several username and password permutations (please note order of characters does matter and thus it’s a permutation not a combination). That being said there are three aspects of the user account design process that really grind my gears.

User Responsibility

This aspect of user account design doesn’t seem to be talked about very often, but it is extremely important. Individuals need to take responsibility for the protection of their usernames and passwords. In fact most web based services clearly indicate as such in their User Level Agreement. That is to say, if someone gains access to your account by means of your username and password permutation, you are responsible for any and all damages. Users need to understand that they are already being held legally responsible for their login information and should take it upon themselves to protect it as if it were any other valuable piece of information.

Secret Username

I grew up online and have watched large web based service provides change their user account design practices over time. Although, most of these changes have greatly increased the general security of user accounts online, I’ve always wondered why changes were never made to user names. In fact usernames have remained almost constant in the online landscape for years. For some reason, early adopters of this authentication model decided that the username should be shared to represent a person online. I personally believe that it is important to have an online identity and that it’s your choice weather to divulge your physical identity alongside a virtual one. This should not require me to log into a web service with such an identity or handle. My username, that I use to log in, should not be public information. In fact I’m a firm believer that it should be treated as if it were a second password. After all, two things you known might not be 2 factors of authenticate, but it is two facts. Web based service provides need to allow users to create usernames that are just as advanced as their passwords. These usernames should not be made public and another method of virtual identity handling should be used. If nothing else, please please stop using email addresses for account login. Email addresses are used everywhere online and are widely known pieces of information and one need only go to the password recovery prompt to see if an email is indeed in use.

Password Complexity

Password complexity is a double edged sword and I hope to make a far more technical and detailed posting about it in the near future. However password complexity, in my mind, has only come about as a method to force users into take more reasonability for their passwords. In a perfect world, a password of all lower case letters or all numbers would be just as difficult to decipher as a password that uses a range of characters. That is to say, if users were truly random in their character selections, the user who chose a password of 33784091 would be just as secure as the user who choose L(k&6hlY, because the available character space did not change. However users are not random and in fact are rather predictable. So our solution is to create a list of rules that a user must follow in order to use a service. This forces a user to create a password that is hopefully harder to guess and crack, but in my experience neither case really holds true. These rules restrict the user by reducing the useable character space and realm of possible passwords. These restrictions alongside the added pressure of maintain a secure posture, all but forces users to reuse old passwords and create ones from common phrases. This undo stress adds predictability to the equation and is at the root of the username and password problem. My solution is a simple one, use the same methodology that is commonplace for usernames. When a user sets or changes a password don’t let them use a password that someone else is already using. In the background, just add what every passwords your organization has deemed weak to the already in use list, just as many already do for usernames deemed inappropriate.