By Adam Paulina, Threat Researcher Intern
Usually when we think of malware infections, we think of malicious programs running on top of the operating system, usually Windows. These programs might use techniques like privilege escalation, running in memory only, injecting code into other processes, and obfuscating their code and activities. All of these techniques are used with the end goal of compromising a system, achieving persistence, and remaining undetected.
In the past, it was very easy to write a malicious kernel driver and take complete control over the Windows operating system, with no attempts by the OS to prevent this from happening. This is no longer the case. A laundry list of mitigations in modern Windows largely shut out this attack vector*. There are still some ways around these mitigations, such as Bring Your Own Vulnerable Driver (BYOVD) techniques or signing using leaked certificates, but these efforts are much more difficult than the infamously simple attacks of old.
In response to the rising prevalence of these modern mitigations, attackers have been taking a different approach. The easiest way to circumvent a protection is to disable it before it ever runs. As a result, attackers have been increasingly driven to attacking the boot process, often before the OS even launches.
This methodology has a few strong benefits for an attacker: By infecting the device firmware, they can survive OS reinstallations and even hard drive replacements. Additionally, this method opens an entirely new attack vector in the supply chain – if a manufacturer can be compromised before the victim even receives the product, they could be infected the second they first touch the device and have absolutely no idea. Detection of these threats is still an area of active research.
Further, attacking the boot process so early allows an attacker to completely disable all of the mitigations and protections described above, without even alerting the victim that they are disabled. Since the attacker is working below the operating system level, nothing the operating system says can be trusted. For this reason, bootkits make up some of the most dangerous malware in existence due to their capabilities, their persistence, and their high difficulty of detection.
In part one of this blog series, we will explain the boot process of modern UEFI machines, as well as some of its built-in protections, and we will explore the techniques used by various real-world bootkits to circumvent these protections and hijack the boot process. Bootkits in this blog will be classified by the techniques they use.
The UEFI boot process
Nearly all modern computers have firmware conforming to the UEFI open standard. UEFI was introduced to replace the older BIOS standard nearly 17 years ago and has been widely adopted for more than 10 years. BIOS is obsolete and should not be used on modern computers. As a result, BIOS is outside of the scope of this article and will not be mentioned beyond this point.
The primary purpose of UEFI is to initialize device hardware and bring the machine to a bootable state. UEFI is an open standard, and it is also designed to be comprehensive. The intent is that any motherboard that uses UEFI will have the exact same behavior, even across different manufacturers.
UEFI is also designed to be secure from the ground up. It incorporates a complex string of verifications and security measures, creating a chain of trust from the first instructions to run all the way to the final OS boot. Assuming the chain is implemented correctly (meaning all the verifications at each stage work properly), is still can’t be implicitly trusted, unless the code that initializes the chain is trusted. If malicious code starts the chain, the verification steps are pointless as they can be easily bypassed or spoofed. This initial state of trust is what’s usually referred to as the “root-of-trust”.
The root-of-trust used in UEFI is dependent on which specific security technologies are enabled. Without any security features enabled (such as when in Compatibility Support Mode (CSM)*), there’s obviously no root-of-trust at all as there is no chain-of-trust. With UEFI Secure Boot enabled, the root-of-trust is centered in the platform initialization firmware, the first code to run on the computer. Unfortunately, this isn’t the best choice as under the right conditions it can be modifiable with software, breaking the entire chain. A better root-of-trust is available with technologies that implement verified boot, such as Intel Boot Guard – where the root-of-trust is moved into immutable hardware logic and cannot be attacked without physical access.
The rest of this blog post will primarily focus on machines with UEFI Secure Boot enabled, but without Intel Boot Guard, as these are what most bootkits target. There have been a couple leaks in the past year that resulted in exposure of some Intel Boot Guard private keys, which could potentially open the door for some attacks that can circumvent it, but at the time of writing there are currently no bootkits in the wild that do so.
The root-of-trust of UEFI Secure Boot is primarily implemented by the platform initialization firmware, which consists of some of the earliest code to run on the computer. Intel processors start by running some routines to check for updates for their microcode, updating if necessary, retrieving the microcode, verifying its signature, and running it. If we had Intel Boot Guard enabled, the hardware verification steps would occur now, but since that is disabled, the primary job of the microcode is simply to jump to the reset vector, which begins execution of the UEFI firmware.
The UEFI firmware is divided into three main stages:
- Security (SEC)
- Pre-EFI Initialization (PEI)
- Driver Execution Environment (DXE)
The SEC stage covers the code that runs immediately upon jumping to the reset vector. The code is executed directly out of the SPI flash. It’s first job is to switch from real mode to protected mode, which opens proper memory addressing instead of having to deal with segmentation. Next, it sets up a temporary emulation of RAM using the CPU caches. This allows it to run code that requires memory access beyond the registers, without having actually initialized DRAM yet. Finally, the Security stage’s final job is to verify the PEI stage before running it. This verification step implements the core functionality of Secure Boot, which we will see again implemented at various stages throughout the boot process and will explore in more detail later in this post.
Once execution switches over to the PEI stage, its primary job is to initialize the essential hardware necessary for the system to operate. More specifically, it configures the memory controller to enable DRAM, switches from using the emulated RAM with the CPU caches to using true DRAM and initializes the chipset. If waking from sleep instead of booting for the first time, it also restores the contents of the CPU registers to what they were before it was asleep. Whether restoring from sleep or booting from scratch, its last step is always to verify and launch the final DXE stage, in a very similar manner to how the PEI stage was verified and launched.
DXE is the final stage of the UEFI firmware, and the longest. Its main job is to initialize all the rest of the hardware. Since hardware is vendor specific and UEFI is supposed to be a platform-agnostic specification, it is designed so that all of the hardware initialization is done by separate DXE drivers. A system can have as many or as few DXE modules as is necessary to initialize all the hardware. This stage is also responsible for initializing System Management Mode (SMM). It also sets up boot and runtime EFI services. Once all that is done, it enumerates all UEFI-compatible bootloaders on the PCI bus and chooses one to boot. Lastly, it performs the boot by consulting with NVRAM variables to find the location of the EFI System Partition (ESP), finding the location of the boot manager on it, and then verifying and launching that bootloader. On Windows machines the bootloader is called bootmgfw.efi and is stored at \EFI\Microsoft\Boot\. The UEFI firmware is able to access filesystems at this point thanks to hard drive access now being initialized, and it does so using its GUID Partition Table (GPT).
After the Windows bootloader is called, it performs a variety of steps. Before doing anything, it must first decompress its embedded PE file and hand over execution to it. Once this is done, it reads system parameters from the Boot Configuration Data (BCD) store, which controls many Windows security features (this is a common target for bootkits once they compromise the firmware). Then, bootmgr handles boot option selection screens (such as enabling safe mode), and then it calls winload to boot with whatever selected options.
Winload is responsible for enabling paging in protected mode, and for loading the OS kernel image and its dependencies:
- bootvid.dll : library for VGA support at boot time
- ci.dll : code integrity library
- clfs.dll : common logging filesystem driver
- hal.dll : hardware abstraction layer driver
- kdcom.dll : kernel debugger protocol communications library
- pshed.dll : platform specific hardware error driver
Additionally, winload loads boot-start drivers, the Early Launch Anti Malware (ELAM) service, and the registry. Assuming code integrity checks are enabled, it attempts to verify every module that it loads.
UEFI Secure Boot in depth
We mentioned above that each stage of the UEFI firmware verifies the next stage before booting it. But how does this verification work?
Secure Boot verification works via a complex web of hashes and signature checks. All UEFI firmware files are either PE or TE files. PE is the same kind of executable file as used by Windows, where TE is a stripped down version of PE with a significantly simplified header format. PE headers have the ability to store certificates inside of their Certificate Table Data Directory. TE headers do not have this field and therefore cannot pass certificate checks, they can only be authenticated with hashing.
For PE files with certificates, the certificates are made up of the following information:
- Description of the cryptographic algorithm used for signature generation and verification
- Hash of the PE image
- Vendor Signature
- Corresponding public key to verify signature
Certificates can be verified by the UEFI Firmware by calculating the hash of the image and comparing it with the hash provided. If the hashes don’t match, the image must have been modified in some way. After the hash check passes, the signature is verified using the public key. This ensures that the signature has not been modified either. The file must pass both checks to proceed.
However, these checks on their own are meaningless, since anyone can make a valid public key/signature combination that would pass. In order to verify that the signed file is signed by a trusted source, the public key must be a trusted public key. To determine which keys are trusted, the UEFI Firmware maintains a few databases as NVRAM variables. These databases include db (whitelist of valid public keys), dbx (blacklist of invalid public keys), dbr (public key certificates used for verifying the OS recovery loader), and dbt (timestamping certificates for verifying the timestamp of the UEFI firmware image’s certificate – the purpose of this is both to allow keys to expire, as well as to allow images signed by revoked/expired keys to still function, so long as they were signed before said keys were revoked or expired).
These databases also need to be protected from unauthorized modification and are themselves verified with signature verification using the Key Exchange Key, which is a public key list stored in NVRAM. The owner of this key is the only one who can modify the key databases. This key list is itself verified with another key called the Platform Key, which serves as the root-of-trust along with the UEFI firmware in the SPI flash.
Evidently, without Intel Boot Guard, this system is only really secure through obfuscation, and through hope that an attacker can’t figure out the right path to break it. Since the Platform Key is stored in the same location as the firmware it’s supposed to verify, any attacker with write access to that location would be able to modify both and still pass Secure Boot. This is one of the fundamental flaws of having a software-based root-of-trust.
Types of UEFI Bootkits
Now that we have a fundamental understanding of UEFI and its security mechanisms, we can start exploring the malicious software that attempts to break it.
There are different methodologies that UEFI bootkits can take. Some are very basic and only make a couple changes to the pre-existing code, completely ignoring Secure Boot. Some write their own modules and drivers. Some actually attempt to bypass Secure Boot via the weakness we explained in the last section. We will explore all of these methods below:
ESP only:
The earliest known technique is also the simplest. The basic premise is to modify the ESP partition on the hard drive, which only requires kernel access to write to. By modifying or replacing the existing bootmgfw.efi and winload.efi files, or by modifying the NVRAM variables that point to their location, it is possible to run a malicious bootloader instead of the real one.
This technique only works with Secure Boot disabled, because the modified/replaced efi files will no longer pass verification and therefore won’t boot at all.
ESP-only bootkits are fairly limited in what they can do as a consequence of running so late in the boot chain. They don’t execute until after the UEFI firmware is finished, when most security features are already initialized. Further, they have lower persistence than other bootkits as they wouldn’t survive hard drive wiping/replacement. They were only really viable threats in the early 2010s.
Consequently, even the ones that were discovered recently like FinSpy and ESPecter appear to have been developed close to 2012, and just went undetected for a few years due to the stealth of bootkits in general.
DreamBoot (POC published by QuarksLab in 2013):
- While only being a proof of concept, DreamBoot is notable because it was the first public attempt at a UEFI bootkit.
- The idea of DreamBoot is relatively simple, all it does is modify the two Windows bootloader files on the ESP (bootmgfw.efi and winload.efi) in order to make them do malicious things (for the proof of concept, the two are made to implement a Windows privilege escalation functionality).
- The original presentation claims that the POC could only be deployed with physical access using a CD, even providing the release as an ISO image to be burned to a disc. It turns out that this is completely unnecessary, and it is entirely possible to deploy the attack remotely.
QuarkMatter (developed by CIA, docs leaked online in 2016):
- QuarkMatter is a UEFI bootkit whose existence was revealed by WikiLeaks in 2016. The leaks included several documents describing the tool, and instructions for installing it and using it. They did not however include the tool itself, and they also aren’t terribly specific about how it works under the hood. From what can be gathered, the tool operated similarly to other ESP-only bootkits, except that it targeted macOS instead of Windows.
FinSpy (discovered by Kaspersky in 2021):
- FinFisher is the UEFI bootkit component of the FinFisher spyware suite, a collection of software tools marketed and sold to governments and law enforcement agencies. While it is unknown exactly when FinSpy’s UEFI bootkit component was first used in the wild, the FinSpy spyware suite itself was first seen in the wild in 2011, and it was known to have a legacy BIOS bootkit since 2014. As a result, the UEFI bootkit could have been developed any time between 2011 and 2021, but it’s not out of the question that it was developed early in the range and went undetected for years. It’s also possible that it reuses code from the legacy BIOS version, in which case it dates back to at least 2014.
- FinSpy’s UEFI bootkit component works very similarly to DreamBoot, except that it only replaces bootmgfw.efi, and instead of doing a basic privilege escalation it installs the spyware into the OS by dropping it as a trojan.
ESPecter (discovered by ESET in 2021):
- ESPecter is a UEFI bootkit made by an unknown threat actor, possibly Chinese speaking. The bootkit shares code with a previous legacy BIOS bootkit that dated all the way back to 2012.
- Under the hood, ESPecter operates very similarly to FinSpy, but instead of using a trojan, it installs a kernel driver to do its spyware work instead. It is able to do this because the bootkit can disable driver signing enforcement.
DXE only:
The next steps in bootkit complexity are those that go one step further back in the boot chain. DXE-only bootkits are much stealthier than their ESP-only counterparts because they don’t modify any pre-existing files. Instead, they add malicious DXE drivers that are executed during the DXE stage.
These are much harder to find as there are hundreds of DXE drivers on any given system, although the existence of unverified DXE modules means it’s still not possible to boot with Secure Boot enabled. They are also more persistent than ESP-only threats, as they are stored on the SPI flash, and would persist through hard drive replacements.
These bootkits are also harder to install than the ESP-only ones. In order to get direct access to the SPI flash, an attacker would require System Management Mode (SMM) access. ESP-only bootkit installers only ever require kernel access. However, it is also possible that a DXE-only bootkit could be installed via a compromised update mechanism instead.
VectorEDK (developed by Hacking Team, leaked online in 2015):
- VectorEDK is a UEFI bootkit created by the Italian company Hacking Team as part of a suite of tools that they sold to governments and law enforcement agencies. Unlike the previous bootkits we have talked about so far, VectorEDK doesn’t touch the EFI files directly, instead loading itself earlier in the process during the DXE phase. VectorEDK is made up of multiple DXE drivers, as well as a custom EFI file similar to the ones in the ESP-only bootkits we’ve discussed before. However, unlike the previous ones, this malicious EFI is not executed from the ESP, rather the malicious DXE drivers register a callback for EFI_EVENT_GROUP_READY_TO_BOOT which calls the EFI bootloader before the OS bootloader gets run.
- While this does execute earlier than its ESP-only peers, it still doesn’t pass Secure Boot because the DXE drivers are not signed.
- Hacking Team suggested to their clients that deployment required physical access using a USB drive, although it is potentially possible to deploy remotely.
DerStarke (developed by CIA, leaked online in 2016):
- DerStarke is a UEFI bootkit whose existence was revealed by WikiLeaks in 2016. Similarly to QuarkMatter, the leaks included documents describing the tool, and instructions for installing it and using it. They did not however include the tool itself, and they also aren’t terribly specific about how it works under the hood. From what can be gathered, the tool operated similarly to other DXE-only bootkits, except that it targeted macOS instead of Windows.
Spy Trojan (谍影木马) (discovered by Qihoo360 in 2017):
- Spy Trojan is a UEFI bootkit developed by an unknown Chinese-speaking threat actor. It was discovered by Qihoo360 in 2017, though mostly missed by English-speaking researchers. It was later widely reported on in 2022 when Kaspersky named it as an ancestor of CosmicStrand.
- Spy Trojan uses a technique involving the Compatibility Support Module, a UEFI component that allows booting from old MBR disks instead of modern GPT ones. The bootkit replaces the DXE driver intended to locate the bootable system partition from the MBR drive, and hooks some functions in order to copy its rootkit components into the Windows kernel during boot. As it involves unsigned DXE drivers, Spy Trojan does not bypass Secure Boot.
- Spy Trojan’s published research goes into detail about the infection vector of the sample they analyzed: a customer of theirs bought a used motherboard online that shipped with the malware preinstalled. It was only noticed by the user after the computer would repeatedly automatically create a suspicious user account.
MosaicRegressor (discovered by Kaspersky in 2020):
- MosaicRegressor is a UEFI bootkit developed by an unknown Chinese-speaking threat actor, based on the leaked source code for VectorEDK. MosaicRegressor uses the exact same callback registration method to load its malicious DXE drivers that VectorEDK uses. The main difference with MosaicRegressor was not in its bootkit component, but in the spyware malware that it bootstraps after infection. As MosaicRegressor uses the same techniques as VectorEDK, it also does not pass Secure Boot thanks to having unsigned DXE drivers.
- Kaspersky never determined the infection vector before publishing their research (they said that they noticed no suspicious events before detection of the malicious code), but speculated that it could have been physical access like described by the Hacking Team leak, or that it could have also been remotely deployed.
MoonBounce (discovered by Kaspersky in 2021):
- MoonBounce is a bootkit believed to have been developed by the APT Wicked Panda. Since Kasperspky discovered the infection after it was already in place, they didn’t have much to reveal about its infection method, though they believed it to have been installed remotely.
- MoonBounce operates a little differently than other DXE bootkits. Instead of simply adding more DXE drivers, it works by hooking some of the EFI Boot Services functions in order to inject more malware into the Windows kernel during boot.
CosmicStrand (discovered by Kaspersky in 2022):
- CosmicStrand is a UEFI bootkit developed by an unknown Chinese-speaking threat actor. It is a direct descendant of the earlier Spy Trojan bootkit discovered by Qihoo360 in 2017. Very similar to Spy Trojan, it works via patching the CSMCORE DXE driver in order to inject rootkit code into the windows bootloader.
- Once again, as an unsigned DXE driver CosmicStrand is unable to pass SecureBoot.
DXE and Secure Boot Bypass (SPI):
Eventually, someone realized that if you have SPI flash access to write DXE modules, that means you also have write access to the Platform Key, which is the root-of-trust of Secure Boot. As a result, advanced DXE bootkits are theoretically able to compromise this key, enabling the bootkits to function even when Secure Boot is enabled.
LoJax (discovered by ESET in 2018):
- LoJax is a bootkit developed by the APT Fancy Bear. It is a malicious modification of the legitimate software LoJack – which was a proprietary software for tracking the location of business laptops in the event of theft. This software utilized a signed DXE driver, which made it very difficult for a thief to remove, since it couldn’t simply be uninstalled.
- LoJax actually doesn’t modify the UEFI component of LoJack at all, it simply replaces the usermode component with a malicious one that contacts a C&C server instead of the real anti-theft server. In fact, it doesn’t even need to replace the executable, it just changes the name of the server that it tries to connect to, inside of the embedded configuration file in the usermode executable. In order to make this modification, it uses another pre-existing signed component – the non-malicious RwDrv.sys that is used by ReadWriteEverything (a security research tool) to gain complete hardware level access to the system, including to the SPI flash.
Since the original LoJack DXE module is signed and passes Secure Boot, and LoJax doesn’t modify it, LoJax completely bypasses Secure Boot
TrickBoot (discovered by Eclypsium in 2020):
- TrickBoot is not technically a bootkit at all, it’s a module within the larger TrickBot framework, a trojan botnet made by an unknown Russian-speaking threat actor. Specifically the module is designed to check the SPI flash for firmware writing capabilities. While it doesn’t actually do anything with these vulnerabilities, by investigating the presence of them at mass scale, it appears to be in preparation of some future bootkit functionality.
- Similarly to LoJax, TrickBoot repurposes the RdDrv.sys driver in order to do its SPI flash checks.
- Since TrickBoot doesn’t actually modify anything and isn’t a bootkit, it would of course bypass Secure Boot.
ESP and Secure Boot Bypass (MOK):
This last category of threats is new, having only been discovered a couple of months ago as of this writing. There is currently only one threat in this category, although there may be more in the future.
This threat takes advantage of a quirk of Secure Boot needed for Linux compatibility. With Windows systems, it is easy to verify what is a legitimate bootloader and what isn’t, as legitimate bootloaders will only ever be published by Microsoft. With Linux, a free and open-source operating system that anyone can modify, and that has thousands of distributions made by different people, and with new ones being made all the time – the idea of Secure Boot falls apart completely.
It took many years to get Secure Boot to work on Linux. The main idea was to use an intermediary bootloader that could be signed (called shim), that would then become the root-of-trust CA for signing and verifying the distro-specific bootloader. This program, acting as a certificate authority, allows users to register their own keys, referred to as Machine Owner Keys.
Machine Owner Keys are stored in a boot-only NVRAM variable called MokList. This variable is only supposed to be accessible while Boot Services are active, which makes it difficult to modify.
BlackLotus (discovered by ESET in 2023):
- BlackLotus is a UEFI bootkit that was first listed for sale on criminal hacking forums in late 2022. Despite being *just* an ESP bootkit, it is able to work on Secure Boot-enabled machines by taking advantage of an exploit (CVE-2022-21894) to register a custom Machine Owner Key before Boot Services are exited, allowing for the complete circumvention of UEFI Secure Boot. It uses its custom key to self-sign its malicious modified Windows bootloader, and then abuses shim to launch the now-signed bootloader.