Small update. A few changes since v0.2:
- if new password is set and mode is not, default mode to “command” (this will cause password to be enforced rather than ignored)
- clarified usage
- added ‘-c’ option
If you were getting a message like this:
sudo: ./efipw_0.2b.py: command not found
it’s because you hadn’t flagged the file as executable. I neglected to mention this in the instructions before, but it’s in there now. If you’re getting the above, just run:
chmod +x ./efipw*
…assuming efipw is in your working directory, of course.
I’ve also added a ‘-c’ option that disables the EFI password properly (or at least the way Apple does it). When an EFI password is cleared with Apple’s GUI utility, ‘none’ is written to nvram as the password and the ‘none’ mode is selected. Rather than forcing people to specify ‘none’ for both fields themselves, users can just do:
sudo ./efipw* -c
to disable the EFI password properly.
I released v0.2 of my efipw tool originally discussed here. It’s a complete rewrite in Python for a number of reasons (manageability, simplicity, and v0.1 stopped working on Snow Leopard at some point).
# lolCrypt: Apple's lolzy encryption function def lolCrypt(input): output = "" for i in range(0, len(input)): output += (chr(ord(input[i]) ^ 170)) return output
efipw is a tool a I wrote for two reasons: pentests & lab deployments. Apple doesn’t provide administrators with a command line tool for changing EFI (a.k.a. Open Firmware) passwords – this is where efipw comes in. These passwords may be employed to require physical access to boot off non-blessed drives, NetBoot shares, etc. More information here. efipw allows root to set and reveal EFI passwords as well as set EFI modes.
usage: sudo ./efipw* -h
While doing some reverse engineering of Apple’s Open Firmware Password GUI utility, I found something I thought was interesting. Depending on the length of the chosen password, several things may happen:
length = 0: not allowed (error given) length = [1-48]: no error, password set correctly length = [49-255]: fail silently (password not set and no error given) length = 256: Open Firmware Password utility crashes length > 256: a really unhelpful error is given, password not set
Isn’t 48 kind of an odd cutting off point? I can understand 256 and the obvious off by one error going on here. I assume whats being stored in nvram is ASCII-encoded. If that’s true, then each password character consumes three ASCII characters (a % followed by two hex values). So if the maximum password length that actually works is 48, that means nvram stores at most 48*3 = 144 ASCII values in that field in nvram, which is still kind of an odd number in my opinion. If you have any ideas, comment below.
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.