How I Cleared an Un-clearable BIOS Password

I recently managed to snag an IBM QRadar QFlow Collector 1201 for a whopping $25. It's just a regular IBM x3550 M3 with a QRadar decal on the front and some pre-installed software, so I was planning on just wiping the drives and repurposing it as a regular host.

I booted it up for the first time to start configuring the BIOS and immediately had my hopes crushed by the following message:

            An Administrative Password has been set
<ENTER> Enter Administrative Password for complete setup access
          <ESC> Continue with limited access to setup

"No problem," I thought, "I'll just reset the CMOS and the password will get wiped out along with everything else."

So I cleared the CMOS and rebooted, only to find that the password was still there.

Hm, maybe I should check the documentation...

Uh oh.
Uh oh.

A new x3550 M3 motherboard is only about $40-60 on eBay, so this wasn't a huge deal. But I didn't want to give up without a fight.

Enter these blog posts:

People have been reverse engineering UEFI images for various laptops to figure out how to get around their setup passwords. That's how password generators like this one were built. However, there hasn't been much work done on the server side.

Armed with the UEFITool suite, I was able to extract the UEFI binaries from an IBM update package. Then it was a matter of disassembling the binaries and analyzing them to figure out how the setup password gets set and/or cleared. The EFISwissKnife IDA plugin made this a lot easier by automatically identifying and tagging common UEFI functions.

There are a huge number of binaries in a single UEFI firmware image, so it took a combination of educated guessing, lots of digging, a good deal of backtracking, and several days (and late nights) to finally find where the password management was handled. There was one particular method that appeared to have something to do with either querying the existence of a password or (I hoped) clearing a password. The function signature looked something like this:

int func(void* protocol_interface, int pw_sel)
  • protocol_interface is a large, messy data structure used to access the password manager - it holds some state and a ton of function pointers
  • pw_sel is used to select which password to operate on
    • 0 = power-on password
    • 1 = setup password

I couldn't conclusively determine what the function did though. The deeper I delved in to the guts of the UEFI drivers, the more complicated the code got. After almost a whole day of getting nowhere, I decided to just try calling that function to see what it did.

To do that, I wrote a small program that just called func() and exited. But how was I going to run my program if I couldn't select a boot device?

PXE came to my rescue. The default CMOS settings turn on PXE boot, so it was just a matter of setting up DHCP and TFTP servers and pointing them to a UEFI shell like this one. Once I had booted into the shell, I was able to mount a USB drive and run the binary.

And it worked! The password was gone when I rebooted!

I've posted my code to Github in case others run into this problem in the future.

Now I'm off to play with my new server.