Add article about secure boot
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Florian Maury 2022-11-30 08:28:43 +01:00
parent 9347f7cf9f
commit 614ee6abff
No known key found for this signature in database

245
posts/secure_boot.md Normal file
View file

@ -0,0 +1,245 @@
---
title: "Secure Boot: this is not the protection we are looking for"
slug: "secure-boot-not"
description: "An article trying to prove that Secure Boot is often failing to provide any kind of meaningful protection, mostly because of the number of stuff that can go wrong."
date: 2022-11-30T00:00:00+00:00
type: posts
draft: false
categories:
- security
tags:
- tpm
- secure boot
- sysadmin
- linux
lang: en
---
Before being a technology, secure boot is an English expression. But, what does
it mean to boot securely? What are we trying to achieve and to protect?
First, we want user data protection from a secure system. User data is really
any piece of data a user might display or edit, including the obvious office
documents but also configuration files, databases, downloaded files, log files,
user commands, etc. These data must be protected in confidentiality. For this,
the system must ensure that these data are protected at rest, when the system
is shutdown. However, this is not enough, since access from unauthorized
software could leak the data, for instance over the network or by copying it on
an external removable drive. Hence, a secure system should only run authorized
software.
## Secure Boot, the technology
Secure Boot is an attempt at ensuring that only authorized software is run on a
machine. It does so by bootstrapping the security of the system at boot time,
giving way to other technologies to keep the system secure, later on. Secure
boot works by authorizing only select executables to be run. Authorized
executables are signed using public cryptography, and the keys used to verify
those signatures are stored securely in UEFI "databases".
UEFI is the successor of the now nearly defunct BIOS. It is an interface
between the operating system and the manufacturer platform, a firmware, that
runs very early on most modern systems. The platform is responsible of, among
many other things, executing the bootloader (for instance, Grub or
systemd-boot). Generally, the bootloader then starts an operating system. In
the case of GNU/Systemd/Linux, the bootloader runs the Linux kernel, which
shuts down all UEFI Boot Services, before dropping its privileges and then
doing "Linux stuff" (like starting the userland part of the operating system).
This privilege drop is very important because this is what ensures that no code
past that point is able to tamper with the UEFI environment, including UEFI
variables, which contains sensitive data.
Secure Boot aims at securing "everything" that is executed prior to that
privilege drop. Once the privileges are drop, it is up to the operating system
to ensure that only authorized software is run. Most Linux distros do not even
try to do it, although there are notable exceptions (Chrome OS, Android, just
to name a few). If we run one of the distros that do not leverage technologies
such as dm-verity, fs-verity (with signatures) or Linux IMA (Integrity
Management Architecture), then Secure Boot is strictly insufficient to protect
user data integrity or even system integrity in general.
Nevertheless, ANSSI, the French Infosec Agency recommends in its GNU/Linux
security guide[^linuxguide] to enable Secure Boot (R3) for all systems
requiring medium security level (level 2 out of 4, 1 being the minimal
requirements and 4 being for highly secure systems). Meanwhile, using a Unified
Kernel Image to bundle the Linux kernel with a initramfs into a single
executable that can be verified by Secure Boot is only recommended[^R6] for
highly secure systems (security level 4 out of 4). No recommendation is ever
done about using one of the aforementioned integrity features to ensure
operating system integrity.
[^linuxguide]: no English version yet. French version is https://www.ssi.gouv.fr/uploads/2019/02/fr_np_linux_configuration-v2.0.pdf
[^R6]: "Protect command line parameters and initramfs with Secure Boot"
Interestingly, a poll on the fediverse[^poll] revealed that 89% of the
respondants thinks that Secure Boot is necessary for intermediate security
level, and 45% even think that it should be a minimum requirement.
This article is a strong push-back against ANSSI "recommendation", and it
attempts to prove that it is not only useless but incoherent and misleading.
[^poll]: https://infosec.exchange/@x_cli/109348532363333158
## Signature verification and default public keys
Secure boot relies on a set of public keys to verify authorized software
authenticity. By default, most vendors ship Microsoft public keys. These keys
sign all Microsoft Windows version, of course, but to avoid a monopoly, other
executables were signed. The list is rather short because with each signature
and authorized software, the attack surface grows and the probability of a
vulnerability raises. Several were already found in the recent past (e.g.
CVE-2020-10713[^CVE-2020-10713], CVE-2022-34301[^CVE-2022-34301],
CVE-2022-34302[^CVE-2022-34302], CVE-2022-34303[^CVE-2022-34303].
[^CVE-2020-10713]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10713 
[^CVE-2022-34301]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-34301
[^CVE-2022-34302]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-34302
[^CVE-2022-34303]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-34303
For this reason, many software still require that Secure Boot be deactivated, including firmware updates by some manufacturers, including Intel[^intelUpgrade] or Lenovo[^lenovoUpgrade].
[^intelUpgrade]: https://www.intel.com/content/dam/support/us/en/documents/mini-pcs/UEFI-Flash-BIOS-Update-Instructions.pdf
[^lenovoUpgrade]: https://support.lenovo.com/us/en/solutions/ht118103-flash-bios-with-uefi-tool-ideacentre-stick-300
Grub and the kernels are not directly authorized by Microsoft, as it would
require for each and every single version to be signed individually by
Microsoft. Instead, a binary called Shim[^shim] was developed. This rather
small, auditable, innocuous-looking program is signed by Microsoft. Its role is
basically that of a trojan horse. Indeed, its only purpose is to
cryptographically verify the authenticity of any executable. However, this
time, the list of public keys used to verify these executables is not directly
under the control of Microsoft. These public keys are either built in Shim
itself or stored in a EFI variable serving as a database.
[^shim]: https://github.com/rhboot/shim
Additionally, shim public key list can be altered by any user able to prove
"presence". This is the case of any user using the local console or using a BMC
for remote console access. Once a new public key enrolled, all executables
verifiable by that key can run in the UEFI privileged mode, and for instance
create a persistent backdoor in the bootstrapping code of the machine.
If this was not enough, users able to prove "presence" can also disable shim
verification of authorized software. This means that shim can be used to have
the system believe that Secure Boot was used to bootstrap security, while
untrusted code was ultimately run within the UEFI privileged mode.
Hence, thanks to shim, just about any signed or unsigned, trusted or untrusted
executable can be validated by proxy by Secure Boot using Microsoft keys. 
And this conclusion signs (pun intended) the second incoherence in ANSSI
recommendations. Indeed, they recommend replacing Microsoft keys by our own set
of keys only for highly secure security level (R4). This means that all systems
with intermediate (2/4) and enhanced (3/4) security levels will have the false
sense of security of running Secure Boot while exposing themselves to attackers
capable of proving "presence".
For what it is worth, shim does provide a way secure all operations, including
disabling verification or enrolling new keys by setting a password on shim's 
MOK (Machine Owner Keys) Manager[^mokpass]. However, the feature is mostly
unused because no Linux distro enables it (it requires user interaction during
the boot procedure) and system administrators often mistake the MOK Manager
password, which secures the access to the MOK Manager as a whole, with the
password that is asked when running mokutil commands (including `--import` and
`--disable-verification`), which is just a password used to confirm the will of
the user in the MOK Manager. The author of this article failed to find a single
tutorial or article discussing the necessity of setting a MOK Manager for a
Secure Boot. ANSSI also failed to recommend that. Most interestingly, setting a
MOK Manager password is recommended even for Windows administrators that have
no intention of ever running Linux, because MOK Manager is one of
the executables signed by the Microsoft keys.
[^mokpass]: The command is `mokutil --password`. Please consider using it.
## Using our own set of Secure Boot keys (PK and KEK)
Since replacing the Microsoft keys and signing only authorized binaries (i.e.
our own Unified Kernel Image and specifically not shim) is an option, why not
do that? It just requires that the system administrators replace the Secure
Boot keys. The question of who controls the private key and the signature
process is entirely up to whether the signed executable is altered or not by
the system administrator. Distros could ship public keys and Unified Kernel
Images instead of relying on Shim. If we run our own kernel, as recommended by
ANSSI (R15 to R27), then we need to handle the private key and the signature
process ourselves.
With a Unified Kernel Image signed and verified by Secure Boot, we are now sure
that only our code is executed, and we can safely ask for the user passphrase
to unlock the LUKS container. This way, user data is protected at rest, and
accessed only by authorized software. Cool. Except it is not.
First, as mentioned earlier, the only thing that we verified is that the
Unified Kernel Image is authentic. That kernel must then verify the operating
system to ensure that only verified software is run. This requires
cryptographic verification of every single executable (binaries, scripts and
executable configuration files (because... yeah... that's a thing)) in the
operating system. This can be achieved if we, at minimum, do the following:
* use a read-only filesystem for our partitions containing executable code,
enforced using dm-verity, or fs-verity with file signature or Linux IMA, or
something similar;
* use the noexec mount option on data partitions;
* modify command interpreters to ensure they do not execute scripts from mount
points with noexec nor from STDIN;
* prevent writable memory from ever getting executed, by patching the kernel;
* ensure that no executable configuration file is writable.
Welcome in Wonderland, Alice.
Ok, but let's assume we go down that rabbit hole... are we secure yet?
No. No, we are not.
Because there is no way of telling if our Secure Boot implementation is tainted
by an attacker or not. Indeed, someone could have flashed our UEFI firmware
before we enabled Secure Boot. Or they could have disabled it, flashed and
reenabled it, if we did not have a UEFI administration password at some point.
Or they could have abused shim when we were using the default keys to flash
UEFI.
## Nirvana Fallacy much?
So, if Secure Boot is not a good answer, especially against an attacker capable
of physical access or remote access through a BMC, what is? Is there a better
solution?
Well, to the best of the author knowledge, there is one: using a TPM. Using a
TPM will not necessarily  prevent an attacker from tainting the firmware. It
will not necessarily prevent booting untrusted and unverified executables. What
a TPM can give us is the ability to unseal a LUKS passphrase and get access to
user data if and only if the cryptographically verified right version of UEFI
firmware, Unified Kernel Image and operating system image have been booted.
This is based on PCR policies, that ties the sealed passphrase to a particular
signed set of executables measured by the TPM. This approach ensures user data
confidentiality at rest and the authenticity of the executables that are on
disk during boot. Of course, it does not prevent executing writable memory, nor
user data flagged as executable, including scripts, and executable
configuration files. And of course, having a signed set of policies means
handling a private key and designing a signature procedure. There is no free
lunch. Sorry.
However, using a TPM offers the same security level against attackers with
physical access, attackers with remote access through a BMC, and a rogue system
administrator, and that is something that Secure Boot cannot brag about.
## Conclusion
So there you have it: recommending idly Secure Boot for all systems requiring
intermediate security level accomplishes nothing, except maybe giving more work
to system administrators that are recompiling their kernel, while offering
exactly no measurable security against many threats if UEFI Administrative
password and MOK Manager passwords are not set. This is especially true for
laptop systems where physical access cannot be prevented for obvious reasons.
For servers in colocation, the risk of physical access is not null. And finally
for many servers, the risk of a rogue employee somewhere in the supply chain,
or the maintenance chain cannot be easily ruled out.