Matthew Garrett ([personal profile] mjg59) wrote2016-08-11 11:21 am
Entry tags:

Microsoft's compromised Secure Boot implementation

There's been a bunch of coverage of this attack on Microsoft's Secure Boot implementation, a lot of which has been somewhat confused or misleading. Here's my understanding of the situation.

Windows RT devices were shipped without the ability to disable Secure Boot. Secure Boot is the root of trust for Microsoft's User Mode Code Integrity (UMCI) feature, which is what restricts Windows RT devices to running applications signed by Microsoft. This restriction is somewhat inconvenient for developers, so Microsoft added support in the bootloader to disable UMCI. If you were a member of the appropriate developer program, you could give your device's unique ID to Microsoft and receive a signed blob that disabled image validation. The bootloader would execute a (Microsoft-signed) utility that verified that the blob was appropriately signed and matched the device in question, and would then insert it into an EFI Boot Services variable[1]. On reboot, the boot loader reads the blob from that variable and integrates that policy, telling later stages to disable code integrity validation.

The problem here is that the signed blob includes the entire policy, and so any policy change requires an entirely new signed blob. The Windows 10 Anniversary Update added a new feature to the boot loader, allowing it to load supplementary policies. These must also be signed, but aren't tied to a device id - the idea is that they'll be ignored unless a device-specific policy has also been loaded. This way you can get a single device-specific signed blob that allows you to set an arbitrary policy later by using a combination of supplementary policies.

This is all fine in the Anniversary Edition. Unfortunately older versions of the boot loader will happily load a supplementary policy as if it were a full policy, ignoring the fact that it doesn't include a device ID. The loaded policy replaces the built-in policy, so in the absence of a base policy a supplementary policy as simple as "Enable this feature" will effectively remove all other restrictions.

Unfortunately for Microsoft, such a supplementary policy leaked. Installing it as a base policy on pre-Anniversary Edition boot loaders will then allow you to disable all integrity verification, including in the boot loader. Which means you can ask the boot loader to chain to any other executable, in turn allowing you to boot a compromised copy of any operating system you want (not just Windows).

This does require you to be able to install the policy, though. The PoC released includes a signed copy of SecureBootDebug.efi for ARM, which is sufficient to install the policy on ARM systems. There doesn't (yet) appear to be a public equivalent for x86, which means it's not (yet) practical for arbitrary attackers to subvert the Secure Boot process on x86. I've been doing my testing on a setup where I've manually installed the policy, which isn't practical in an automated way.

How can this be prevented? Installing the policy requires the ability to run code in the firmware environment, and by default the boot loader will only load signed images. The number of signed applications that will copy the policy to the Boot Services variable is presumably limited, so if the Windows boot loader supported blacklisting second-stage bootloaders Microsoft could simply blacklist all policy installers that permit installation of a supplementary policy as a primary policy. If that's not possible, they'll have to blacklist of the vulnerable boot loaders themselves. That would mean all pre-Anniversary Edition install media would stop working, including recovery and deployment images. That's, well, a problem. Things are much easier if the first case is true.

Thankfully, if you're not running Windows this doesn't have to be a issue. There are two commonly used Microsoft Secure Boot keys. The first is the one used to sign all third party code, including drivers in option ROMs and non-Windows operating systems. The second is used purely to sign Windows. If you delete the second from your system, Windows boot loaders (including all the vulnerable ones) will be rejected by your firmware, but non-Windows operating systems will still work fine.

From what we know so far, this isn't an absolute disaster. The ARM policy installer requires user intervention, so if the x86 one is similar it'd be difficult to use this as an automated attack vector[2]. If Microsoft are able to blacklist the policy installers without blacklisting the boot loader, it's also going to be minimally annoying. But if it's possible to install a policy without triggering any boot loader blacklists, this could end up being embarrassing.

Even outside the immediate harm, this is an interesting vulnerability. Presumably when the older boot loaders were written, Microsoft policy was that they would never sign policy files that didn't include a device ID. That policy changed when support for supplemental policies was added. without this policy change, the older boot loaders could still be considered secure. Adding new features can break old assumptions, and your design needs to take that into account.

[1] EFI variables come in two main forms - those accessible at runtime (Runtime Services variables) and those only accessible in the early boot environment (Boot Services variables). Boot Services variables can only be accessed before ExitBootServices() is called, and in Secure Boot environments all code executing before this point is (theoretically) signed. This means that Boot Services variables are nominally tamper-resistant.

[2] Shim has explicit support for allowing a physically present machine owner to disable signature validation - this is basically equivalent

Early roots of trust are no more secure than the rest of our buggy software world

(Anonymous) 2016-08-12 10:26 am (UTC)(link)
So my pre-existing belief that Secure Boot is only useful for either preventing attacks or restricting users if its implementor can write perfectly bug-free code must be extended to note that the implementor also needs to have assumptions that all its developers can keep perfectly in mind and never violate, no matter how long ago they were set. Which is really just another way of saying the first thing, since violated assumptions are a common cause of bugs...

By extension, this feature is a waste of everyone's time: it will inevitably fall (via similar paths to those seen here, unless MS have a magic bug-preventing mechanism that none of the rest of us do) and when it does all that will be left of it is lots of annoying complexity that won't actually stop attackers but will just irritate people trying to use their "Secure" Boot devices like the non-secure ones they always had.

... sounds very much like all other boot-time firmware ever, really. Cruft layered on cruft layered on cruft, all useful once upon a time but rendered useless by the passing of years.

-- Nix

(Anonymous) 2016-08-15 09:44 am (UTC)(link)
Does this mean Windows RT tablets are now suddenly a lot more interesting to F/OSS hackers?

old times

(Anonymous) 2016-08-15 03:06 pm (UTC)(link)
I can still remember a time when the ability to install any software on your very own computer wasn't considered to be a "bug" or a "vulnerability".
Aaah, those were the days...

Re: old times

(Anonymous) 2016-08-18 12:19 am (UTC)(link)
When Atlantis stood serene above the sea.
A long time before our time when the world was free
Those were the days. Those were the days.

Re: old times

(Anonymous) 2016-09-20 12:52 am (UTC)(link)
Don't worry, Microsoft definitely isn't keeping a database of everyone who unlocks their devices, and all future devices and versions will definitely allow anyone to easily unlock them and install Linux on them. This isn't another step toward making all devices as locked-down as phones and killing off Linux and general-purpose computing, no siree.

Problem with Lenovo Yoga 900 ISK2 and Linux.

(Anonymous) 2016-09-20 10:38 pm (UTC)(link)
Hi there,

This isn't really related to this topic, but I wondered if I might have a moment of your time to discuss an issue with not being able to install Linux distributions to the Lenovo Yoga 900 ISK2 model Ultrabooks.

The BIOS seems to be locked in some sort of weird RAID mode, and Linux installers can't see the SSD. Lenovo removed the ability to change to AHCI mode deliberately. Thus far, the only way anyone managed to install Linux on it was to mod the BIOS to restore the option and then flash the new BIOS in with an external flasher to evade the signature check. After doing this, he reports that he is able to install Linux on that particular laptop.

I was wondering if maybe there would be a workaround.

The forum topic on this is here:


https://forums.lenovo.com/t5/Linux-Discussion/Yoga-900-13ISK2-BIOS-update-for-setting-RAID-mode-for-missing/td-p/3339206

If you could look into this, I would be extremely grateful.

Re: Problem with Lenovo Yoga 900 ISK2 and Linux.

(Anonymous) 2016-09-20 11:27 pm (UTC)(link)
Thanks for the reply. Do you happen to know if there is work in progress for the Linux kernel to support this configuration and, if so, which version this will show up in?

Thanks again!

Re: Problem with Lenovo Yoga 900 ISK2 and Linux.

(Anonymous) 2016-09-21 03:34 am (UTC)(link)
I got a reply from Lenovo on my Best Buy review. They admit they did this intentionally to lock out Linux as part of an agreement with Microsoft.

http://imgur.com/a/7s777

Lenovo Product Expert
September 20, 2016
This system has a Signature Edition of Windows 10 Home installed. It is locked per our agreement with Microsoft.