InsecureBoot
Secure Boot bypass via firmware patching
Background
Running unsigned or stealthily running self-signed EFI modules on a motherboard with properly implemented and enabled Secure Boot is theoretically impossible. Unsigned code gets blocked, and self-signed or hash-enrolled code allows for detection. To circumvent these restrictions, patching the return codes of the signature verification routines allows Secure Boot to remain active while allowing unsigned code execution.
Software can identify unauthorized EFI modules by parsing the firmware’s trusted database (db) and checking for untrusted certificates or hashes, such as self-signed certificates or unknown hashes. If either is found, the software assumes the system has executed non-standard modules during the current boot. These modules could range from those designed to undermine system security to harmless ones, such as a Linux Unified Kernel Image.
This solution arose from my need to dual boot Linux and Windows while playing games protected by Riot Games’ Vanguard, without constantly toggling Secure Boot in the UEFI firmware settings. To achieve this, I chose the path of least resistance: patching my firmware. Thanks, Riot Games, for forcing Linux users to compromise their firmware security.
History
SecureFakePkg
Previously, game integrity protection software accepted a hooked GetVariable that returned a fake Secure Boot status (as implemented in SecureFakePkg). Kernel-mode software now detects hooks on GetVariable, requiring a new solution to enable free dual booting.
MOKList
Previously, users could enroll their own keys or hashes into the MOKList, allowing self-signed binaries to be loaded and pass secure boot. MOKList is now checked for any non-OEM keys and users are blocked if unrecognized keys are found, harming legitimate Linux dual-booters once again.
PatchBoot
Samuel Tulach’s PatchBoot implements a modified image verification handler that returns EFI_SUCCESS early. Some motherboards have code related to TPM in the handler, thus returning early sometimes breaks TPM functionality. Requires manual extraction of SecurityStubDxe and identification of the image verification handler, followed by a byte patch of the handler.
New Method
To simplify the process and provide TPM compatibility, I propose an alternative method for patching SecurityStubDxe: replacing all occurrences of EFI_SECURITY_VIOLATION
with EFI_SUCCESS
. By referencing the EDK II source code or Akira Moroo’s convenient list, we find the following hex equivalents:
EFI_SECURITY_VIOLATION = 0x800000000000001A
EFI_SUCCESS = 0x0
With these values, we can ensure any loaded module always succeeds by replacing all instances of 0x800000000000001A
with 0x0000000000000000
. This approach is much easier to implement with a byte patch than using the PatchBoot method. After performing some endian conversion, we can create a UEFIPatch-compatible patch to apply the changes in a single step.1A00000000000080 -> 0000000000000000
For some firmware implementations, replacing EFI_ACCESS_DENIED
with EFI_SUCCESS
may also be required, depending on platform policy. I have not yet tested this because the need has not arisen on my hardware.0F00000000000080 -> 0000000000000000
Patching
Disclaimer
Patching your firmware is risky and can render your computer unbootable if done incorrectly. UEFIPatch has an issue with breaking certain firmware images, so you should pay attention to any warnings it produces. Proceed with caution, and ensure you have an SPI flash recovery method.
To patch your firmware, I’ve provided a browser compatible UEFIPatch, available at the link below. The tool performs all work locally on the device and no binaries are uploaded. Provide your firmware file, select “Circumvent Secure Boot” and then “Patch”.
Alternatively, use your own version of UEFIPatch with the below patch, saving patches.txt
to the directory of the UEFIPatch binary.
patches.txt
# Replace EFI_SECURITY_VIOLATION with EFI_SUCCESS in SecurityStubDxe
F80697E9-7FD6-4665-8646-88E33EF71DFC 10 P:1A00000000000080:0000000000000000
UEFIPatch usage:
.\UEFIPatch <UEFI_Firmware> patches.txt
Compatibility
This patch is not compatible with AMD PSB or Intel BootGuard, unless you have already created a bypass for those. Attempting to load unsigned motherboard firmware will prevent the motherboard from booting. Before flashing patched firmware, verify that the firmware signature enforcement mechanism for your platform is not enabled. See BootGuard / PSB Checker for a hastily written, and likely bug ridden tool to check this on Windows.
CPU Vendor | Signature Enforcement Mechanism | Linux Status Check Procedure | Windows Status Check Proceedure |
---|---|---|---|
Intel | BootGuard | https://github.com/felixsinger/bootguard-status | BootGuard / PSB Checker |
AMD | Platform Secure Boot (PSB) | https://github.com/mkopec/psb_status | BootGuard / PSB Checker |
I believe this method to be compatible with most AMD AMI based firmware, and have tested it on 2 different models of MSI motherboards, AM4 and AM5. I have also done a dry run of the patching process on some Intel AMI and Insyde firmware, and the patching process does complete. However, I do not possess any intel hardware to verify that the resultant firmware is bootable or bypasses secure boot. If you have success with this on non-BootGuard Intel platforms, I would be curious to know, feel free to leave a comment or shoot me an email: 0cNU0eWR2WV1pIT5t_zHGS6Y0cyevPzN12w
Flashing
Given that this firmware does not have a valid signature, depending on your motherboard vendor, you may have issues flashing it.
Vendor | Patching Resource |
---|---|
MSI | https://vanishingfork.net/info/msi-motherboard-flash-methods/ |
All others | Win-Raid forum |
I may write more guides for other vendors if I have time.
Detection
After transitioning into virtual mode, SecurityStubDxe does not have a virtual memory mapping, because it is not a runtime driver. Data still may exist in memory, but is not valid.
Software could theoretically verify Secure Boot functionality by dropping an unsigned EFI executable programmed to set a flag on the system and rewrite the BootOrder and Boot0000 variables to ensure the executable loads, followed by loading the OS bootloader. However, due to poor UEFI Specification implementation on many motherboards, this approach often results in unbootable PCs. This method would also flag many motherboards that shipped with faulty Secure Boot implementations, looking at you MSI.
ROM Analysis
Dumping of firmware remains the only viable detection method, and comes with its own issues related to compatibility, such as system lockup. Protecting your firmware against dumping remains an exercise for the reader.
Many motherboards previously shipped with Allow All execution policies in Secure Boot settings, so by default, they exhibited behavior similar to that of this patch.
TPM PCRs
If your TPM is enabled, loading different EFI executables will affect the PCRs. This alone is not a detection vector because PCRs only represent a hash of the computer’s state and can change with different hardware and firmware configurations (such as updating firmware or changing UEFI settings). However, you will almost certainly get a different hash for your PCRs when loading your own UEFI code.