EfiGuard is a portable x64 UEFI bootkit that patches the Windows boot manager, boot loader and kernel at boot time in order to disable PatchGuard and Driver Signature Enforcement (DSE).
Features
bootmgfw.efi
by the firmware boot manager via the boot selection menu or an EFI application such as the loader. If a non-Windows OS is booted, the driver will automatically unload itself. bootmgfw.efi
starts bootmgr.efi
rather than winload.efi
. This is the case when a WIM file is loaded to boot WinPE, Windows Setup or Windows Recovery mode. ExitBootServices
is called. Many UEFI Windows bootkits hook OslArchTransferToKernel
which, while easy to find by pattern matching, is a function that executes in protected mode after ExitBootServices
. This means no boot services are available to tell the user that something went wrong.Simulated patch failure with error information
Debuggable: can output messages to a kernel debugger and to the screen (albeit buffered) during the kernel patching stage, and to a serial port or unbuffered to the screen during the boot manager and boot loader patching stages.
If the driver is compiled with PDB debug information, it is possible to load the debug symbols at any point after HAL initialization by specifying the virtual DXE driver base and debugging it as you would a regular NT driver.
DSE bypasses: available as either a straightforward UPGDSED-style DSE disable at boot time or as a hook on the SetVariable()
EFI runtime service.
The latter serves as an arbitrary kernel mode read/write backdoor that can be called from Windows using NtSetSystemEnvironmentValueEx
and allows setting g_CiEnabled
/g_CiOptions
to the desired value.
A small DSEFix-style application named EfiDSEFix.exe
is provided that can be used to do this. It is also possible to leave DSE enabled and to disable only PatchGuard.
The loader will use the SetVariable
hook method by default, due to the fact that some anti-cheat and anti-virus programs do not understand the difference between cheats or malware and self-signed drivers in general and target the UPGDSED fix.
Supports on-disk modified kernels and boot loaders by patching ImgpValidateImageHash
at every stage as well as ImgpFilterValidationFailure
, which may silently rat out some classes of violations to a TPM or the SI log file.
Allows Secure Boot to work with Windows 7 (not a joke!). Windows 7 itself is oblivious to Secure Boot as it does not support it, or (officially) even booting without CSM.
This is useful for people who want to use Windows 7 on a locked down device that requires WHQL Secure Boot. Wiki entry on how to get this to work here.
Issues and limitations
SetVariable
hook will cause a SECURE_KERNEL_ERROR
bugcheck if it is used to write to g_CiOptions
.How to use
There are two ways to use EfiGuard: booting the loader (easiest), or using the UEFI shell to load the driver.
Booting the loader
EFI/Boot
and rename one of Loader.efi
or Loader.config.efi
to bootx64.efi
. The two are identical, except Loader.efi
boots without user interaction whereas Loader.config.efi
will prompt you to configure the DSE patch method used by the driver (if you want to change this)./EFI/Boot/{bootx64|EfiGuardDxe}.efi
. It is recommended to use FAT32 formatted USB sticks.SetVariable
hook (the default), run EfiDSEFix.exe -d
from a command prompt after boot to disable DSE. Run EfiDSEFix.exe
to see the full list of options.Using the UEFI shell to load the driver
bootx64.efi
. Instead, either use the BIOS-provided shell (if you have one), or download the EDK2 UEFI Shell and rename it to bootx64.efi
.cd
to /EFI/Boot
on the correct filesystem and run load EfiGuardDxe.efi
to load the driver.Loader.efi
or Loader.config.efi
from the same directory to boot Windows. You can also continue working in the shell, or exit
to go back to the BIOS/boot menu and boot from there.Compilation
Compiling EfiGuardDxe and the loader
EfiGuard requires EDK2 to build. If you don’t have EDK2 installed, follow the steps in Getting Started with EDK2 first as the EDK2 build system is fairly complex to set up. This section assumes you have a workspace
directory that your WORKSPACE
environment variable points to, with a copy of EDK2 checked out in workspace/edk2
. Supported compilers are MSVC, Clang, GCC and ICL.
workspace/edk2/EfiGuardPkg
.build -a X64 -t VS2017 -p EfiGuardPkg/EfiGuardPkg.dsc -b RELEASE
, substituting your toolchain for VS2017.This will produce EfiGuardDxe.efi
and Loader.efi
in workspace/Build/EfiGuard/RELEASE_VS2017/X64
.
To build the interactively configurable loader, append -D CONFIGURE_DRIVER=1
to the build command.
Compiling EfiDSEFix
EfiDSEFix requires Visual Studio to build.
EfiGuard.sln
and build the solution.The output binary EfiDSEFix.exe
will be in Application/EfiDSEFix/bin
.
The Visual Studio solution also includes projects for EfiGuardDxe.efi
and Loader.efi
which can be used with VisualUefi, but these projects are not built by default as they will not link without additional code, and the build output will be inferior (bigger) than what EDK2 produces. Loader.efi
will not link at all due to VisualUefi missing UefiBootManagerLib.
These project files are thus meant as a development aid only and the EFI files should still be compiled with EDK2. To set up VisualUefi for this purpose, clone the repository into workspace/VisualUefi
and open EfiGuard.sln
.
Architecture
While EfiGuard is a UEFI bootkit, it did not start out as one. EfiGuard was originally an on-disk patcher running on NT (similar to UPGDSED), intended to test the viability of a disassembler-based aproach, as opposed to using PDB symbols and version-specific signatures.
PatchNtoskrnl.c still looks very much like this original design. Only after this approach proved successful, with no modifications to code needed in over a year of Windows updates, did UEFI come into the picture as a way to further improve capabilities and ease of use.
Some of the benefits provided by a bootkit approach include:
bcdedit
.ImgpValidateImageHash
(although this is still optionally done).db
store.The initial incarnation of EfiGuard as a bootkit was an attempt to get dude719’s UEFI-Bootkit to work with recent versions of Windows 10, because it had become dated and no longer works on the latest versions (like UPGDSED, often caused by version-sensitive pattern scans).
While I did eventually get this to work, I was unsatisfied with the result mostly due to the choice of hooking OslArchTransferToKernel
, which as noted above executes in protected mode and after ExitBootServices
has been called.
Apart from this, I was not satisfied with only being able to patch some versions of Windows 10; I wanted the bootkit to work on every EFI-compatible version of Windows x64 released to date. Because of this, I rewrote the bootkit from scratch with the following aims:
A big picture overview of the final EfiGuard boot flow is shown in the diagram above. For the individual component-specific hooks and patches, see EfiGuardDxe/PatchXxx.c
in the source files. For driver initialization/unloading and the EFI Boot and Runtime Services hooks, see EfiGuardDxe.c.
shadow-rs is a Windows kernel rootkit written in Rust, demonstrating advanced techniques for kernel manipulation…
Extract and execute a PE embedded within a PNG file using an LNK file. The…
Embark on the journey of becoming a certified Red Team professional with our definitive guide.…
This repository contains proof of concept exploits for CVE-2024-5836 and CVE-2024-6778, which are vulnerabilities within…
This took me like 4 days (+2 days for an update), but I got it…
MaLDAPtive is a framework for LDAP SearchFilter parsing, obfuscation, deobfuscation and detection. Its foundation is…