The issues described in this post have now been resolved by Apple. Users running OS X Lion 10.7.2 or security update 2011-006 are no longer affected by the vulnerabilities detailed below (CVE-2011-3435 and CVE-2011-3436). For further details on this security update please see Apple's advisory.
In 2009 I posted an article on Cracking Mac OS X passwords. Whilst this post has been quite popular, it was written for OS X 10.6 and prior. Since the release of Mac OS X Lion (10.7) in July, I have received numerous requests for an update. Typically, I would have just updated the existing article without the need for a new post. However, during my research I discovered something interesting about OS X Lion that I'd like to share.
In previous versions of OS X (10.6, 10.5, 10.4) the process to extract user password hashes has been the same: obtain the user's GeneratedUID and then use that ID to extract hashes from a specific user's shadow file (See my previous post for a more detailed description).
When it comes to Lion, the general premise is the same (albeit a few technical differences). Each user has their own shadow file, with each shadow file stored under a .plist file located in /var/db/dslocal/nodes/Default/users/.
The interesting thing when it comes to Lion's implementation, however, is privilege. As mentioned above, all OS X versions are using shadow files. For the unfamiliar, a shadow file is that which can only be accessed by users with a high privilege (typically root). So for all modern OS X platforms (Tiger, Leopard, Snow Leopard and Lion) each user has their own shadow file (hash database) whose data is accessible only by the root user… or at least it should be.
It appears in the redesign of OS X Lion's authentication scheme a critical step has been overlooked. Whilst non-root users are unable to access the shadow files directly, Lion actually provides non-root users the ability to still view password hash data. This is accomplished by extracting the data straight from Directory Services.
If we invoke a a directory services listing on user bob by specifying the /Local/ path we can see bob's standard profile information:
$ dscl localhost -read /Local/Default/Users/bob
This provides us with nothing too exciting. However, if we invoke the directory services listing using the /Search/ path, we see a different result:
$ dscl localhost -read /Search/Users/bob
From the output, we can see the following data:
62706c69 73743030 d101025d 53414c54 45442d53 48413531 324f1044 74911f72 3bd2f66a 3255e0af 4b85c639 776d510b 63f0b939 c432ab6e 082286c4 7586f19b 4e2f3aab 74229ae1 24ccb11e 916a7a1c 9b29c64b d6b0fd6c bd22e7b1 f0ba1673 080b1900 00000000 00010100 00000000 00000300 00000000 00000000 00000000 000060
Note: The SHA512 hash is stored from bytes 32-96 (green) and the salt is stored from bytes 28-31(red). For more information on these hashes please see this thread.
This ShadowHashData attribute actually contains the same hash stored in user bob's shadow .plist file. The interesting thing about this? root privileges are not required. All users on the system, regardless of privilege, have the ability to access the ShadowHashData attribute from any other user's profile.
Due to Lions relatively short time on the market, I am yet to find any of the major crackers supporting OS X Lion hashes (SHA512 + 4-byte salt). To simplify the cracking of these hashes I have created a simple python script which can be downloaded here.
Now, if the password is not found by the dictionary file you're out of luck, right? Well, no! Why crack hashes when you can just change the password directly! It appears Directory Services in Lion no longer requires authentication when requesting a password change for the current user. So, in order to change the password of the currently logged in user, simply use:
$ dscl localhost -passwd /Search/Users/bob
And voilà! You will be prompted to enter a new password without the need to authenticate.
There has been some conjecture surrounding the severity of these attacks. Whilst the ability to change the currently active user’s password is not a privilege escalation flaw per se, it can under some circumstances be used for these purposes. Allow me to provide a scenario:
A user with administrative rights is browsing the internet with Safari. The user happens to browse to a website hosting a malicious Java Applet. Unbeknownst to the user, they allow the innocent looking Java Applet to run. The Applet will proceed to make a connection back to the attacker, providing the attacker with full shell access. Whilst the attacker has access to the system, they are provided only with limited user privileges (they still do not have root access). This would limit what an attacker could accomplish. However, with the vulnerabilities described above the attacker now has an advantage: they can change the password of the current user. Now remember, the current user is an administrator. So now all the attacker has to do is sudo –s to become root. If lets say the victim did not have administrative rights, the attacker still has the ability to extract user hashes from the system and attempt to crack them.
As a temporary measure to mitigate these attacks (before Apple release a patch), it is recommended to limit standard access to the dscl utility. The can be done as follows:
$ sudo chmod 100 /usr/bin/dscl