
baton drop (CVE-2022-21894): Secure Boot Security Feature Bypass Vulnerability
Windows Boot Applications allow the truncatememory setting to remove blocks of memory containing "persistent" ranges of serialised data from the memory map, leading to Secure Boot bypass.
truncatememory BCD element will remove all memory above a specified physical address from the memory map.bootdebug, testsigning, nointegritychecks), thus breaking Secure Boot.This issue was fixed by two different changes:
bootmgr, boot application initialisation fails.VERSIONINFO resource containing an OriginalFilename, if that filename is included in a blocklist (containing bootmgr.exe and hvloader.exe; in Nickel, hvloader.efi was added but this did not get backported), the load fails.
hvloader.exe is not included in winload's blocklist - it originally was, which broke Hyper-V loading!flightedbootmgr element to load bootmgr from disk), the OriginalFilename is required to be bootmgr.exe.The attacker needs to ensure the serialised Secure Boot Policy is allocated above a known physical address.
osdevice is a BitLocker-encrypted partition where the VMK was derived using the TPM.
The avoidlowmemory element can be used to ensure all allocations of physical memory are above a specified physical address:
bootmgr and specifying a custom BCD path (using bcdfilepath element aka custom:22000023) can be used to bypass this.bootmgr to disable VBS and then swap back to the original bootloader.
bootmgr will fail to unseal the VMK on a Windows 10+ system.hvloader.efi can be loaded with the nointegritychecks element to load a self-signed mcupdate.dll, whose entry point will be called before ExitBootServices.
Alternatively, on non-AMD64 systems, winload.efi before TH2 can be used with the testsigning element; this allows self-signed binaries with the szOID_NT5_CRYPTO EKU in the certificate.
On ARMv7 systems, loading a patched self-signed hal.dll with an import to mcupdate.dll will be necessary to get code execution.
On x86 and AMD64 systems, the file loaded as mcupdate.dll must be named mcupdate_*.dll, where * is the CPUID manufacturer string (GenuineIntel, AuthenticAMD etc).
On ARM64 systems, this technique cannot be used due to the earliest available production signed build being a WinPE of RS2; thus currently only tethered code execution can be performed (using bootdebug).
This repository includes the following files:
mcupdate.dll runs at a virtual address with paging enabled, it is impossible to call EFI functions directly (paging needs to be disabled to call EFI functions, returning to a virtual address with paging off does not lead to a good time).BlImgLoadPEImageEx or BlImgLoadPEImageFromSourceBuffer with bit 0 set in the flags to load an additional payload at a 1:1 physical address-virtual address mapping.
BlImgAllocateImageBuffer with the same bit set to allocate memory at a 1:1 physical address-virtual address mapping; then load a payload itself (or remap itself there).bootmgfw from Windows 8 RTM and the hvloader from TH1 RTM.
hvloader obtained by offset and then infinite loops.bootmgr from RS1 and the hvloader from TH1 RTM.bootmgr version 19041.1081 and the hvloader from TH1 RTM.This issue can be used to dump BitLocker keys (where Secure Boot is used for integrity validation).
The fix for this issue also fixed another issue which has no CVE.
bootmgr ignores any BitLocker keytable already in memory and allocates a new one, without wiping the old one.
bootmgr from bootmgr (specifying an arbitrary osdevice where Secure Boot is used for integrity validation), boot to WinPE, load a known vulnerable driver, and use it to search for and dump the existing BitLocker keytable in physical memory.No known vulnerable boot application has been revoked yet.
bootmgr checking its own signature.An incomplete revocation occured, and another CVE (CVE-2023-24932). There's still vulnerable bootmgfws that were not revoked, as well as additional patches only fixing the case where bootmgr loads bootmgr. It only took a pasted bootkit to get MS to act ;)
If you're creative enough you'll find a way to work around the revocation of over 2000 bootmgfw files ;)