Skip to content
This repository has been archived by the owner on Aug 11, 2023. It is now read-only.

EXTRA_SIGN in combination w/ e.g. sd-boot can lead to an attacker being able to sign a malicious file #36

Open
ljrk0 opened this issue Feb 2, 2021 · 4 comments
Labels

Comments

@ljrk0
Copy link

ljrk0 commented Feb 2, 2021

I was just made aware that EXTRA_SIGN allows for the following attack scenario, with the example given in the README:

EXTRA_SIGN=('/boot/EFI/BOOT/BOOTX64.EFI' '/boot/EFI/systemd/systemd-bootx64.efi')

Suppose you boot via systemd-bootx64.efi.

  1. The attacker can easily control BOOTX64.EFI as well as systemd-bootx64.efi. Suppose they maliciously modify the former file (i.e., the one you dont boot from).
  2. The user boots using the latter file and updates the system, a Linux kernel update is pulled in and sbupdate automatically signs both files, the attacker now has hold of a signed but malicious bootloader.
  3. The attacker copies BOOTX64.EFI to systemd-bootx64.efi and has now control over the bootloader.

I think there are two solutions which, at best, could be combined:

  1. Don't let the attacker control (possibly) unsigned files, i.e. allow for EXTRA_FILES to support input as well as output (say, pull in the file from /usr/lib/systemd/boot/efi/systemd-bootx64.efi).
  2. Only sign those files you actually booted from, put a warning into the README.md and modify the example.

The second adjustment is easily made, but the former guards against further, similar attacks:

If the unsigned kernel files are stored on the ESP as well, say you adhere to XBOOTLDR 1 and have the ESP mounted in /boot, s.t. (by default) ArchLinux initramfs/vmlinuz will be put into /boot/..., the same attack can be carried out in a modified fashion:

  1. You boot into kernel A but the attacker modifies kernel A-fallback.
  2. sbupdate signs the malicious kernel A-fallback*.

Since sbupdate by default is only run on updates, thus overwriting A-fallback* with A-fallback', this will only work if the user triggers it manually. However, if the user has actually multiple kernels installed, say linux and linux-lts, then this attack is even more likely since:

  1. You boot into kernel A but the attacker modified kernel B.
  2. An update for kernel A triggers sbupdate hook and the malicious kernel B* is signed.

Now the attacker could use the sd-boot menu to boot the kernel B*

@andreyv
Copy link
Owner

andreyv commented Mar 15, 2021

Hi,

Thanks for the report.

This is already described in the README. To prevent the attack, sbupdate doesn't sign extra files when running from the hook, but only when invoked manually (presumably after the user just updated the extra files).

The second attack is also described in the same section. /boot should be separate from ESP and should be on a secure filesystem.

The overall recommendation is not to use a boot loader at all, but use direct booting. Then the only files on ESP are signed UEFI images.

@gilbsgilbs
Copy link

The second attack is also described in the same section. /boot should be separate from ESP and should be on a secure filesystem.

This is definitely the way to go, thanks for pointing that out. I suspect we're more than two to have fell for that:

  • The current README section isn't too clear about what the actual threat is. If you're a bit careless, it looks more like an advice for troubleshooting some random issue than a real security advice that everyone should follow for a secure setup. As mounting ESP to /boot is a very common pattern (it's even the default configuration in sbupdate) and given that sbupdate just seems to work fine with this, it may not be that easy for users to realize the problem. Maybe the section could be moved more to the top as a separate "Configuration" step, with a better emphasis on the risks and a recommended setup.
  • as the risk is quite high (basically allowing attackers to trick users into booting arbitrary images defeating the whole purpose of SB), maybe sbupdate could somehow detect when ESP is mounted on /boot and display some warning should that is the case.
  • as I mentioned in Wrong kernel output after system update #38 , the risk is even worse since 4e6d106 because sbupdate now even picks the kernel from /boot. It's not just about EXTRA_SIGN and ucodes anymore. The attack can be timed.

Let me know what you think and if I can help.

@ljrk0
Copy link
Author

ljrk0 commented Mar 26, 2021

Sorry for not replying for such a long time.

While the issue is described correctly in the README, I think it's rather hidden, or rather, the implications aren't that clear. To quote

Typically ESP is mounted on /boot and contains also the original, unsigned files such as the Linux kernel image and initramfs. You may choose to mount ESP on a different directory (for example, /efi) and keep /boot itself on the secure root file system. This way ESP will only contain signed images which cannot be tampered with.

This sounds like 'an optional tweak' to enhance security -- but without this change, most setups are simply insecure and secure boot does nothing but add 'fake' security.

See Configuration to change the ESP directory.

Unfortunately, as @gilbsgilbs pointed out, the default configuration is insecure for many setups.

Note that if you use a boot manager such as systemd-boot, then its files still need to be on the ESP before they are signed. It is customary to sign these files right after they have been installed on the ESP. Direct booting is recommended for increased security.

Again, 'increased security' sounds like indirect booting (with the default configuration) is secure already, and this just adds "another layer" of security. However, the combination of systemd-boot & sbupdate is, as of now, pretty much impossible to done securely.

I think adding an INPUT_FILES section or similar would do a great deal to fix this. Then, the wording could be easily made more clear:

If the INPUT_FILES reside on an unsecured medium, an attacker can tamper with these and inject malicious code.

Of course, if the INPUT_FILES are only "intermediate" files that are only generated directly before running sbupdate, this would not apply. But in that case one could, perhaps, use pacman hooks to force running those hooks which generate the INPUT_FILES before sbupdate and delete the INPUT_FILES afterwards?

andreyv added a commit that referenced this issue May 13, 2022
andreyv added a commit that referenced this issue May 13, 2022
@andreyv
Copy link
Owner

andreyv commented May 13, 2022

This should now be improved in master.

785bcd1 added support for automatic signing of systemd-boot. This happens before systemd-boot is installed on the EFI system partition.

2e4d58c clarified in README that a separate ESP is recommended due to the risk of tampering.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants