sbupdate
sbupdate copied to clipboard
EXTRA_SIGN in combination w/ e.g. sd-boot can lead to an attacker being able to sign a malicious file
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.
- The attacker can easily control
BOOTX64.EFIas well assystemd-bootx64.efi. Suppose they maliciously modify the former file (i.e., the one you dont boot from). - 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.
- The attacker copies
BOOTX64.EFItosystemd-bootx64.efiand has now control over the bootloader.
I think there are two solutions which, at best, could be combined:
- 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). - 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:
- You boot into kernel A but the attacker modifies kernel A-fallback.
sbupdatesigns 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:
- You boot into kernel A but the attacker modified kernel B.
- An update for kernel A triggers
sbupdatehook and the malicious kernel B* is signed.
Now the attacker could use the sd-boot menu to boot the kernel B*
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.
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
/bootis 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 #38 , the risk is even worse since 4e6d1062a7cbacd6cddd086ac47a33d7e734036f 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.
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_FILESreside 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?
This should now be improved in master.
785bcd1693fe35023045912c8678bc254eb84fee added support for automatic signing of systemd-boot. This happens before systemd-boot is installed on the EFI system partition.
2e4d58c6c6fccbc97abe0bb1c8d3dc4bbb33ae4f clarified in README that a separate ESP is recommended due to the risk of tampering.