I’ve updated my bitlocker attacks list https://github.com/Wack0/bitlocker-attacks
The main addition here is documentation of “break out in hives” (CVE-2024-20666, nice) and its variant (CVE-2025-21213).
The most interesting thing here is that it’s technically still not fixed - the fix was only applied to the PCA2023-signed bootmgr_ex
, so without the KB5025885 mitigations applied (and other default settings which nobody ever changes), you’re still vulnerable without even needing a downgrade attack for bootmgr
.
(If you’re using TPM-only bitlocker, you really should be using legacy integrity validation - that is, Allow Secure Boot for integrity validation policy DISABLED with PCRs 0,2,4,7,11 set - legacy integrity validation was never vulnerable to these issues in the first place! This would imply bitlocker potentially going into recovery more often with windows updates, but it’s a choice between that and currently broken bitlocker vulnerable to various boot-time software issues combined with downgrade attacks)
The main issue here is that starting from Windows 10 (th1), the systemdatadevice
element was added to winload; if present the SYSTEM hive is loaded from this block device instead of the (bitlocker encrypted) OS partition.
Therefore, the first (easiest) exploitation method was to pull a SYSTEM hive from boot.wim
, modify it to set SYSTEM\Setup!CmdLine
to cmd.exe
, and set up the WinRE boot entry to use it; booting WinRE would then pop a SYSTEM shell with bitlocker keys derived and in memory.
The original fix just removed the systemdatadevice
support from winload, but (at least in some cases) the older revisions of winload (for the same major Windows version) would still boot Windows successfully; thus the second exploitation method: configure BCD to load winload from somewhere else (downgrade attack), booting the bitlocker-encrypted OS with custom SYSTEM hive taken from install.wim
- it turned out that without winpe
also set, this corrupted the SYSTEM hive on the bitlocker-encrypted OS partition; also the Win32 subsystem would fail to load, but native code execution would still work when setting SYSTEM\ControlSet001\Control\Session Manager!SetupExecute
. Therefore, I took the old Native Shell codebase, ported it to AMD64, and modified it to acquire SeRestorePrivilege
and open files with FILE_OPEN_FOR_BACKUP_INTENT
(so permission checks would be ignored, so it’s possible to do the sethc trick at this point).