CVE-2021-26892: An Authorization Bypass on the Microsoft Windows EFI System Partition

June 30, 2021 | Simon Zuckerbraun

In October 2020, researcher Abdelhamid Naceri, also known as halov, submitted a unique vulnerability to the ZDI. This vulnerability in Windows 10 allows a low-privileged user to wipe out arbitrary files needed for UEFI boot. The attack can even be conducted from a low integrity level.

There is a great deal of mystery surrounding this case and I will explain the parts that I am able to.

The vulnerability is identified as ZDI-21-330/CVE-2021-26892 and was patched by Microsoft in March 2021.

Background

When any computer system starts up from a cold state, the very first instructions that the processor executes come from firmware. Although we would like to quickly transition to executing instructions that are stored on disk (e.g., the operating system), those instruction bytes are not yet available in memory upon a cold start. Hence the processor must start by executing firmware instructions. The firmware provides the needed instructions for retrieving OS boot instructions from disk, and eventually jumping into the OS.

UEFI is a type of firmware. An in-depth treatment of UEFI is beyond the scope of this article, but for our purposes, we need to know that UEFI firmware will look for a boot device (for example, the primary fixed drive) that contains a special partition known as the EFI System Partition or ESP. This partition is formatted with one of the variants of the FAT file system that the firmware can parse. Within this file system, the firmware expects to find a file with extension .EFI, known as a boot loader, from which it can read the further steps needed in order to continue starting the OS. There are often multiple .EFI files present corresponding to different architectures. A UEFI firmware is also capable of handling the case of multiple available boot devices.

The EFI System Partition and Security

As is known, FAT file systems do not record ACLs or any other security information for files. If a FAT file system is mounted on Windows, every file has, in effect, an empty security descriptor, making the file both world-readable and world-writable. Clearly this is unacceptable for the EFI System Partition. If the files on the ESP were world-writable, it would be trivial for any user to damage the system by deleting critical files needed for boot. An unprivileged user could even install a bootkit by replacing the .EFI file with one containing malicious instructions.

Accordingly, Windows does some behind-the-scenes work to impose special restrictions on access to the ESP. To begin with, the EFI partition is not mounted to any drive letter by default. If a non-administrative user attempts to mount it to a drive letter, access is denied. Even if an administrator mounts it to a driver letter (and there is, in fact, a special command-line syntax for mounting the EFI partition: mountvol F: /S), a non-administrative user will still not have any access to the mounted drive.

Bypassing the ESP Authorization Restrictions

Despite these restrictions, the researcher found that a low-privileged user, even running at low integrity, can still gain some access to the files on the EFI System Partition.

To avoid the need to assign a drive letter, an attacker can call the CreateFile API with a full volume name and path to a specific known file, for example:

      \\?\Volume{641e9a14-b3d6-425c-af6e-7d585169951e}\EFI\Microsoft\Boot\bootmgfw.efi

The volume GUID can be obtained via enumeration of volumes, using the FindFirstVolume and FindNextVolume APIs. In this way, an attacker can obtain a handle to an arbitrary file within the EFI partition, as long as the path is predictable, which is common. I did an experiment and called GetSecurityInfo on the resulting handle, and as would be expected, I received an empty security descriptor, indicating that the file is world-readable and writable: O:WDG:WDD:NO_ACCESS_CONTROL. Even so, Windows does not behave in the way that this security descriptor would imply. Attempts to open the file for reading or writing (GENERIC_READ or GENERIC_WRITE) are denied.

Despite this – and here is the researcher's key finding – there is still a way for an attacker to gain a limited amount of write access. The trick is to call CreateFile without requesting any access at all (neither GENERIC_READ nor GENERIC_WRITE) but specifying a disposition of CREATE_ALWAYS. This flag requests that if the destination file exists, it should be immediately truncated to zero length. Somehow, this combination slips past the authorization logic that Windows implements for the ESP. Although the access mask on the resulting handle does not permit the attacker to write any bytes to the file, Windows nevertheless truncates the file during the CreateFile call as requested. By wiping out the contents of critical .EFI files, the attacker can render the system unable to boot.

Difficulties in Reproduction of the Vulnerability

While analyzing this case, I was mystified to find that it cannot be reproduced on certain hypervisor platforms. I found it could be reproduced on bare metal as well as on HyperV. On ESXi, however, even though the security descriptor comes up as the world-writable O:WDG:WDD:NO_ACCESS_CONTROL, an attempt to truncate the .EFI files fails with ERROR_ACCESS_DENIED. I have no explanation for the difference in behavior between bare metal and ESXi.

Conclusion

When experimenting with this vulnerability it is a good idea to make backups of the .EFI files that will be deleted, particularly when running on bare metal. A successful reproduction results in a complete inability to boot the machine.

The researcher who submitted this bug (halov) is a frequent contributor to the ZDI program, and we hope to continue to see his always interesting research in the future.

You can find me on Twitter at @HexKitchen, and follow the team for the latest in exploit techniques and security patches.