safeboot: Booting Linux more safely
This is the transcript of my talk at on safeboot at OSFC 2020, the Open Source Firmware Conference. In 2018, I gave a keynote on open source security and really enjoyed the community. Due to the pandemic, the conference was virtual this year, which meant that the talks were pre-recorded and the Q&A was live. The video is online, which includes the audience questions afterwards. Much of the content is restated in the safeboot threat model and safeboot frequently asked questions.
tl;dr: The elevator pitch for safeboot is that it makes booting Linux somewhat safer by replacing the built-in OEM and Microsoft UEFI keys with an owner controlled key stored in a hardware token, which is used for signing the kernel, initrd and command line, and enable UEFI firmware features to ensure that the system will only boot the signed unified image, and running it directly as an UEFI executable without an on-disk bootloader. Additionally, safeboot attests to the user that the firmware configuration has not been modified using a time-based one-time password, which tells the user that it is safe to enter their PIN to unseal the disk encryption keys from the TPM. It also has scripts to enable Linux lockdown and filesystem integrity protections, all of which together help prevent a range of hardware, firmware and software attacks.
There is a lot wrapped up in that pitch… To better understand the resiliency of the safeboot configuration, let's look at how it prevents many classes of attacks, detects other attacks, and helps the computer owner recover to a safe state. Specifically, let's focus on one that is often considered "game over" for most threat models: an attacker with physical access to the systems, including internal access. This is "out of scope" for most systems, although if we assume a reasonable time and dollar budget (so no decaping chips, for instance), I think there is a reasonable chance of protecting our computers.
To help look at it from an attacker's perspective, I've invited my hacker alter-ego to demonstrate common techniques for getting into Linux machines, as well as some of their research into firmware security. I'm giving them physical access to my safeboot laptop ...
Split screen to "hacker" in black hoodie
BH: and I'm going to try to get access into it. It's powered off, so first thing I'll try is getting into the UEFI boot manager menu, and selecting to boot from an external USB with a live Linux install.
TH: and that won't work since the UEFI firmware will only boot a kernel with a valid owner signature on it. The live Linux install has an official SecureBoot signature, but safeboot has removed the Microsoft key from the UEFI database, so it won't run that image.
BH: Next step, I'll try to get to the grub console and change the kernel command line to boot with
rdinit=/bin/sh or something so that I can modify the
/boot/grub.cfg, initrd or kernel on disk. But it goes straight to the kernel.
TH: safeboot doesn't use grub - it has the signed image booted directly from the UEFI Boot Manager, so there is no grub.cfg to modify. Also no grub boothole to worry about.
BH: No worries… I'll drop into the UEFI shell and boot with a different kernel command line that way.
TH: The kernel command line is part of the signed image, so you can't override it via the shell.
BH: ok, let's open it open. There are two easily avenues of attack here - the disk and the flash.
TH: That might work on most systems, but boot it up again and notice that you now need the firmware password to restart. This Thinkpad has tamper switches on the case and disk, so you need an EC exploit to reset the state of the switch if you've opened the laptop and removed the disk.
BH: doh. I knew that since I worked with Lenovo to fix that vulnerability. Luckily I know the UEFI password or have an EC exploit, since as Matrosov said it isn't really a secure chip. I can mount the disk in another machine and replace the initrd with one of my own.
TH: That works if the system were using grub, since Trusted Grub doesn't include the initrd in its signature, but safeboot doesn't use grub and includes the kernel, the command line, and the initrd in the signed executable. You can't replace any piece of it without access to the signing key, which is stored in an offline hardware token.
BH: Fine… then I pull out my flash programmer and modify the SecureBoot variable to turn off signature checking. Now my modified kernel and initrd boot and can ask for the user's PIN.
TH: That gives you a running kernel, but the TPM won't display a valid TOTP token since the UEFI SecureBoot related variables are included in the sealing authorization. The user will know that they are not talking to a valid kernel.
BH: Then I leave secure boot on, but write my own key into the UEFI NVRAM firmware volume, then sign my own backdoored kernel and copy that to the disk.
TH: Same thing: the keys are included in the sealing state, so modifying it prevents the TPM from HMAC'ing the TOTP secret as well as unsealing the disk encryption key.
BH: Ok, maybe there was an old signed version with a security vulnerability, so I can rollback to that one. Success, now I have a running kernel on the machine with the same UEFI configuration!
TH: Just because the signature is valid doesn't mean that it is acceptable -- the TPM's monotonic counter doesn't match the signed one for that kernel, so the TPM won't HMAC the TOTP secret. Again, the initrd won't display a valid TOTP, so the user will know there's been a rollback.
BH: Ah, but the PCRs used to authenticate to the TPM for the are not secret, so while I have the device open, I can use my LPC tool to pretend to send the right values to the TPM and ask it for the disk encryption secret. The user PIN is only a few digits, so maybe a few thousand tries to guess it.
TH: The sealed disk encryption secret is protected with the TPM's dictionary attack counter, so you're both rate limited and get locked out after a few tries. You need to get the PIN from the user some how.
BH: Ok, so the fake kernel needs to be able to produce TOTP codes, so we need to find the TOTP secret. Luckily the LPC tool is still wired up, so send the PCRs to the TPM and ask it for the secret.
TH: Nope, that works for TPM v1 TOTP, but
tpm2-totp is an improvement since the TPM2 can do the HMAC internally without revealing the secret to the OS.
BH: While we're talking to the TPM, we could pre-generate a set of the values for times into the future.
TH: That could work, although it limits your time window to get the system back to the user and have them type in their PIN. We need to look into if the HMAC can be rate limited, which would make it much harder for you to compile a dictionary of future values.
BH: Time for the nitric acid and microscope, then!
TH: Doable, but expensive and invasive. There's not much we can do on a commodity system to protect against that. Likewise if you have a zero-day against Bootguard and can add a firmware bootkit to the SPI flash.
BH: Let's shift gears then, and "assume compromise". Say that I already have code execution on the OS and have escalated to root. Next goal is to gain persistence. from the previous attacks, I know that changing the kernel or initrd in /boot won't work due to UEFI SecureBoot keys, and it looks like the root fs is mounted read-only. mount -o rw,remount / and add a bootkit.
TH: The block device is readonly since it is going through dmverity. safeboot borrows ideas from Android, ChromeOS or CoreOS to make the runtime system immutable and to protect it with a cryptographic merkle tree. The root hash of the tree is included in the signed kernel command line, so any modifications to the root filesystem are detected and changing it requires the offline signing key.
BH: Ok, let's try exfiltrating the sensitive corporate data on a USB flash drive.
TH: safeboot has added the USB module to the modules.deny list, so it doesn't mount.
BH: that list only prevents modprobe from loading modules, so I run insmod usb-storage.ko
TH: It is not signed by a trusted key, so it doesn't load.
dd if=/dev/mem to find the disk encryption key and then use that to decrypt the copy of the disk I made when I had it out of the hardware.
TH: thanks to the tireless effort of matthew garret, the lockdown patches prevent that from working. The
lockdown=integrity mode is the default if UEFI SecureBoot is enabled, and safeboot enables the stricter
BH: Let's kexec into a new kernel then that doesn't have these restrictions.
TH: lockdown also checks signatures on the new kernel. And the TPM won't unseal the keys since the PCRs will attest to the entire boot chain, including the current running kernel.
BH: Let's continue to assume compromise. Maybe I'm a malicious insider and want to connect to the corporate resources inside the firewall, exfiltrating them to my compromised machine. I've extracted the disk encryption key and am booting my own kernel + initrd, so I can ssh to the vpn with the user certificate.
TH: Luckily the TPM measurements are a bit harder to fake. In order to authenticate you need a quote from the tpm2-attest program with the PCR values that includes the loaded kernel and initrd and command line. Since the kernel command line also includes the dmverity root hash, it implicitly also includes the entire runtime of the system. The remote attestation server won't return a one-time authorization without those values.
BH: Ok, I boot it in a clean configuration, generate an attestation and send it to the server. Then reboot into the modified config before the reply comes back.
TH: The attestation key used to seal the authentication data is generated with the st-clear attribute, so it is only valid for this one boot. Rebooting invalidates the ephemeral key, so it can't be used to access the auth value.
BH: Ah, but I have another machine without Bootguard, so I can fake the TPM PCRs. This quote has the correct PCR values for the clean firmware, kernel, etc.
TH: the TPM's endorsement key is unique per device, so the remote attestation server won't even look at the quote since it came from an unknown TPM.
BH: I could desolder the TPM from the valid machine and move it to the unprotected one.
TH: Yeah, that will break it. One possibility is to use the fTPM in the Management Engine instead of the discrete TPM since theBGA PCH is much harder to replace than the SOIC TPM. If the modified hardware is detected, the individual TPM authorization to the remote resources can be revoked, so this can at least be shutdown.
BH: Although trusting the ME in this case has its own separate threats.
TH: That's true, and since the ME tells the x86 about the bootguard configuration, it is inside the TCB no matter what. Do you want to talk a bit about your recent research there?
BH: Sure, the Sleep attack (CVE-2020-8705) was disclosed in November and allows a local attacker to gain code execution in ring 0 when the system is resuming from sleep. The root cause is essentially a time-of-check/time-of-use vulnerability - the Bootguard ACM checks the OEM signature on the firmware when booting, but skips it when resuming to make the wakeup process faster. It loads codes from the flash, however, so someone with a spispy or similar flash emulator can provide a modified version of the firmware that will be trusted by the system. SMM is unlocked as this point as well, so they can escalate to ring -2.
TH: I'm really glad that Intel considers this sort of physical threat in the Bootguard attack model and that they addressed it in the fix. For too long local physical attacks were "out of scope" for most threat models and it is an important step that they are taking them seriously now.
BH: Not all of the BIOS vendors are onboard yet, but hopefully they'll come around, too. Until then it is an interesting area to look into for security researchers like me.
TH: Indeed. Thanks to my alter-ego for their help in this walk-through of some of the threats that safeboot is considering, and thanks for watching this talk. For more info safeboot.dev.
However, it is important to note that what is not included is custom firmware or radically new architectures. safeboot is about enabling the existing security mechanisms in the commodity UEFI firmware and mainline Linux kernel. That's one of the reasons I say safeboot is only incrementally improving boot security: CPU issues, OEM firmware bugs, and Linux vulnerabilities are still concerns. However, if we can reduce the attack surface, harden the configuration, and have a way to detect many types of attacks, then we can raise the difficulty of launching an attack and force the attackers to use more sophisticated attacks.
The UEFI SecureBoot features used by safeboot are present in almost every modern system, although they are not enabled by default by many Linux users. In fact, many Linux and even Qubes install guides start with "Turn off SecureBoot", which is really unacceptable for modern platforms since it means that there is zero integrity protection for the bootloader, kernel, initrd, filesystem, etc. And even if you leave SecureBoot enabled, the default configuration doesn't secure as much of the runtime as you might expect: only the grub bootloader and the kernel are signed, the command line and initrd are unprotected.
I'm disappointed that the Linux community has't adopted a secure-by-default approach that companies like Apple and Chromebooks have done. iPhones no longer ask if you want to enable disk encryption, but Ubuntu has it as an "Advanced" option. iPhones no longer ask if you want to store encryption keys in a hardware enclave; try to find a concise guide for doing so with the TPM in Debian. Chromebooks don't ask if you want an immutable filesystem with integrity protection; try to find an easy way to enable dm-verity on Fedora. Chromebooks don't ask if you want to remotely attest to the firmware configuration before authorizing access to your Google account; are there any other services that do this? As a community we need to do much more to make usable security usable.
If we don't make it usable and secure, the users will make it usable and insecure.
So my take home message from this talk is not that you should install safeboot on your machines; although please do so that we can improve it and make it more usable. Instead my take home message is that safeboot shouldn't exist and you shouldn't have to install it. We need to work with the distributions to ensure that everyone's machine is configured in a secure way by default. Until then, however, let's talk about some of the known attacks and threat models that safeboot can defend against…