Fun with Apple EFI Firmware Passwords
I read somewhere that Apple uses weak encryption on its firmware passwords for Intel/EFI based computers, so I decided to take a look at it while on a long flight. I looked around for more specific discussion on the topic and didn’t find anything, so I’ll share what I found along with a tool I wrote to automate the changing and decrypting of the password. I wouldn’t consider the method that they employed encryption per se, but rather an obfuscation of the password. In either case, what they did is certainly not cryptographically secure. It’s not immediately clear to me why they didn’t just MD5 the password or something… the nvram appears to have sufficient space to store such a hashed value.
- OS X 10.5.6 on a 1st Gen (Core Duo) Macbook Pro
- OS X 10.5.6 on a Core 2 Duo Macbook Pro
- pen tests
- lab deployments
I take no responsibility with what you do with this information. Messing with the nvram can be potentially very serious business. Don’t contact me if your mac stops booting.
The method I employed requires root access, either via the root account or single user mode. In a pen test scenario, it may be possible to escalate to root via an exploit (as opposed to password compromise). If the firmware password is the same or similar to another password in use, this may allow for further escalation of privilege / decryption of files / access to other machines / etc. In a lab deployment scenario, it may be desirable to set a firmware password on deployed machines. This process would be more easily automated with a CLI program like the one I’m providing. Of course, there is the OFPW tool, but that was designed for the older Open Firmware and I’ve had problems running it on under Leopard/EFI and am unclear as to whether or not it supports the new hardware. The OFPW binary seems to be unnecessarily elusive and documentation even more so.
Here’s now the obfuscation works:
- a <= 255 character ASCII string is accepted by Firmware Password Utility
- string is viewed as binary (ASCII decoded)
- every other bit is NOT’ted, beginning with a NOT (i.e. NOT, passthru, NOT, passthru, etc)
- resulting bitstream is stored as the password.
You can query the current password via Terminal (hex-ASCII encoding , %-delineated):
sudo nvram -p
… or you can get the contents of nvram in XML with the password in base64:
sudo nvram -x -p
Let’s run through an example. We’ll set our firmware password to:
… which is a fairly random ASCII string. Let’s interpret it as ASCII and translate to binary:
01101010 01101000 00110011 00110111 00110110 01100100 01110011 00111000
… now we apply the magic formula of NOT’ting every other bit, beginning with an initial NOT:
11000000 11000010 10011001 10011101 10011100 11001110 11011001 10010010
… then we hex-ify it:
c0 c2 99 9d 9c ce d9 92
… and finally add ‘%’ delimitors:
… now we run:
sudo nvram security-password=%c0%c2%99%9d%9c%ce%d9%92
… and our firmware password has been updated to jh376ds8.
Obviously the reverse could be employed to reveal a firmware password.
Note: there are three security levels included in Apple’s EFI:
- none: Firmware password is ignored, all boot actions allowed (single user, boot off external, etc). This is a default setting.
- command: Firmware password enforced if user requests to boot off another device by holding down ‘alt’ during boot. Single user, target disk mode, etc disabled.
- full: All actions are disallowed, unless correct password is entered (including normal boot to blessed drive).
Only ASCII characters with decimal values between 32 and 127 (inclusive) are allowed and the password cannot be longer than 255 characters. If the password is empty, Apple’s GUI utility actually stores “none” as the password, so I would recommend not using “none” as a password.
Takeaway: if you’re using an EFI password on your Apple computer, don’t use that password for anything else. It is easily recovered (granted with root access), but even this recovery could allow for easy future access or further compromise.