πŸ”’
❌
There are new articles available, click to refresh the page.
Before yesterdayZero Day Initiative - Blog

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

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.

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

ProxyToken: An Authentication Bypass in Microsoft Exchange Server

30 August 2021 at 12:59

Continuing with the theme of serious vulnerabilities that have recently come to light in Microsoft Exchange Server, in this article we present a new vulnerability we call ProxyToken. It was reported to the Zero Day Initiative in March 2021 by researcher Le Xuan Tuyen of VNPT ISC, and it was patched by Microsoft in the July 2021 Exchange cumulative updates. Identifiers for this vulnerability are CVE-2021-33766 and ZDI-CAN-13477.

With this vulnerability, an unauthenticated attacker can perform configuration actions on mailboxes belonging to arbitrary users. As an illustration of the impact, this can be used to copy all emails addressed to a target and account and forward them to an account controlled by the attacker.

The Trigger

The essential HTTP traffic needed to trigger the vulnerability is as follows:

Picture1.png

β€œSecurityToken=x”? What might this be, some secret backdoor access code?

Understanding the Root Cause

To understand what has happened here, it is necessary to discuss a bit about the architecture of Exchange Server. Recently, security researcher Orange Tsai has done excellent work in this area, and readers are encouraged to read his full findings here as well as the recent guest blog he wrote on this site. However, for the purposes of this particular vulnerability, the salient points will be summarized below.

Microsoft Exchange creates two sites in IIS. One is the default website, listening on ports 80 for HTTP and 443 for HTTPS. This is the site that all clients connect to for web access (OWA, ECP) and for externally facing web services. It is known as the β€œfront end”. The other site is named β€œExchange Back End” and listens on ports 81 for HTTP and 444 for HTTPS.

The front-end website is mostly just a proxy to the back end. To allow access that requires forms authentication, the front end serves pages such as /owa/auth/logon.aspx. For all post-authentication requests, the front end’s main role is to repackage the requests and proxy them to corresponding endpoints on the Exchange Back End site. It then collects the responses from the back end and forwards them to the client.

Exchange is a highly complex product, though, and this can lead to some wrinkles in the usual flow. In particular, Exchange supports a feature called β€œDelegated Authentication” supporting cross-forest topologies. In such deployments, the front end is not able to perform authentication decisions on its own. Instead, the front end passes requests directly to the back end, relying on the back end to determine whether the request is properly authenticated. These requests that are to be authenticated using back-end logic are identified by the presence of a SecurityToken cookie:

In Microsoft.Exchange.HttpProxy.ProxyModule.SelectHandlerForUnauthenticatedRequest:

Picture2.png
Picture3.png

Thus, for requests within /ecp, if the front end finds a non-empty cookie named SecurityToken, it delegates authentication to the back end.

Code on the back end that examines and validates the SecurityToken cookie is found in the class Microsoft.Exchange.Configuration.DelegatedAuthentication.DelegatedAuthenticationModule. What goes wrong on the validation side? To see the answer, have a look at /ecp/web.config on the back end:

As you can see, in a default configuration of the product, a <remove> element appears, so that the module DelegatedAuthModule will not be loaded at all for the back-end ECP site.

In summary, when the front end sees the SecurityToken cookie, it knows that the back end alone is responsible for authenticating this request. Meanwhile, the back end is completely unaware that it needs to authenticate some incoming requests based upon the SecurityToken cookie, since the DelegatedAuthModule is not loaded in installations that have not been configured to use the special delegated authentication feature. The net result is that requests can sail through, without being subjected to authentication on either the front or back end.

Bagging a Canary

There is one additional hurdle to clear before we can successfully issue an unauthenticated request, but it turns out to be a minor one. Each request to an /ecp page is required to have a ticket known as the β€œECP canary”. Without a canary, the request will come back with an HTTP 500. However, the attacker is still in luck, because the 500 error response is accompanied by a valid canary:

Picture4.png

An example of the final request would then be as follows:

Picture5.png

This particular exploit assumes that the attacker has an account on the same Exchange server as the victim. It installs a forwarding rule that allows the attacker to read all the victim’s incoming mail. On some Exchange installations, an administrator may have set a global configuration value that permits forwarding rules having arbitrary Internet destinations, and in that case, the attacker does not need any Exchange credentials at all. Furthermore, since the entire /ecp site is potentially affected, various other means of exploitation may be available as well.

Conclusion

Exchange Server continues to be an amazingly fertile area for vulnerability research. This can be attributed to the product’s enormous complexity, both in terms of feature set and architecture. We look forward to receiving additional vulnerability reports in the future from our talented researchers who are working in this space. Until then, follow the team for the latest in exploit techniques and security patches.

ProxyToken: An Authentication Bypass in Microsoft Exchange Server

The Top 5 Bugs Submitted in 2021

6 January 2022 at 17:04

As the new year begins, we thought it would be fun to look back at some of the best bugs submitted during 2021. We had another record-breaking year, with over 1,600 advisories published. In the end, we came up with the following submissions from 2021 that stood out from the pack. Without further ado and presented in no particular order, here are the Top 5 bug submissions for 2021.


Microsoft Exchange Server Remote Code Execution Vulnerability, a.k.a. ProxyShell

Β β€œProxyShell” is the name given to a devastating vulnerability in Microsoft Exchange Server, discovered by Orange Tsai of DEVCORE Research Team and used in his successful entry at the 2021 Pwn2Own contest. This critical vulnerability in Exchange Server garnered a great deal of attention in 2021, and for good reason. Actually a chain of three security flaws (CVE-2021-34473, CVE-2021-34523, and CVE-2021-31207), ProxyShell allows an unauthenticated attacker to execute arbitrary code in the context of SYSTEM on an Exchange server. As this is a pre-authentication vulnerability, there is no need for the attacker to start with any credentials to an Exchange account at the target organization. The chain does assume that the attacker knows or can guess a valid email address on the server, but this is a low bar indeed.

Compounding matters, it is frequently possible to conduct a ProxyShell attack from anywhere on the Internet, and not just from within the target organization’s network. The only requirement is that the attacker must be able to access the /autodiscover/autodiscover.json endpoint on the Exchange web server. Typical deployments make this endpoint available to the Internet.

Orange Tsai has graciously provided a wonderful write-up detailing his finding in a guest blog on the Zero Day Initiative website. His research into these and other Exchange vulnerabilities was also the subject of his 2021 presentations at Black Hat USA and DEF CON.

2021 has seen a major uptick in researcher interest in Microsoft Exchange Server as a target. This is definitely an area to watch in the future.

Microsoft SharePoint InfoPath List Deserialization of Untrusted Data Remote Code Execution Vulnerability

Besides Exchange Server, Microsoft SharePoint Server has also been an attractive target for vulnerability research recently. The Zero Day Initiative disclosed 10 SharePoint vulnerabilities in 2021. We’d like to highlight CVE-2021-27076, which was reported to us by an anonymous researcher. I was intrigued by the innovative method that this attack employs to expose a deserialization attack surface that normally is inaccessible. In short, the researcher discovered that by altering identifier values that are handled client-side within the browser, it is possible to cause an arbitrary upload to be fed into an incorrect context where it will be treated as trusted data. This lets any authenticated user (typically, any domain user) execute arbitrary code on the SharePoint server in the context of the web application. If you’re curious to learn more about this technique, I encourage you to read my full write-up, which can be found on the Zero Day Initiative website.

Microsoft Windows Lock Screen Improper Access Control Authentication Bypass Vulnerability

I love a good lock screen bypass, and CVE-2021-26431 by Abdelhamid Naceri (halov) doesn’t disappoint. This research builds upon a prior discovery by Jonas Lyk, who noted that that the Narrator feature can sometimes be used to navigate and interact with UI elements that are improperly launched from the lock screen, though hidden from view. Exploiting CVE-2021-26431 involves attempting to log in to a PC using a Microsoft account. After providing an incorrect PIN, it’s possible to arrive at a dialog containing a hyperlink. Clicking the hyperlink launches an β€œOpen With” dialog. Though this dialog is normally hidden from view, Jonas Lyk’s Narrator technique can then be used to interact with it. See Abdelhamid Naceri’s blog and his YouTube videos here and here to watch how he uses this to completely bypass the lock screen or to get a remote shell.

Don’t try this at home, though. From what we can tell, Microsoft has implemented a server-side fix, so that the HTML containing the vulnerable hyperlink is no longer delivered even on PCs that lack up-to-date patches.

Linux Kernel eBPF Improper Input Validation Privilege Escalation Vulnerability

eBPF (Extended Berkeley Packet Filter) is a technology used for the high-performance classification of streams of data packets. A common use case is user-mode software that needs to select a subset of incoming network data packets. To send all packets from kernel mode to user mode for evaluation is generally too expensive. eBPF provides an alternative: User-mode code sends a filter algorithm in the form of an eBPF bytecode program, which the kernel will compile and execute in the context of the kernel to evaluate each packet. The inherent security risks to this arrangement are unmistakable, though: the kernel’s eBPF compiler must be able to determine that the resulting compiled program is 100% free of memory safety issues, or else the security of the kernel will swiftly be compromised. There is little room for error. Furthermore, the competing needs for extreme optimization and perfect execution safety make the eBPF compiler a likely source of critical kernel vulnerabilities.

The bug we’d like to highlight is CVE-2021-31440, reported to the Zero Day Initiative by Manfred Paul in April of 2021 and fixed in this commit to the Linux kernel. The flaw is in the reasoning used by the eBPF compiler when tracking the upper and lower bounds of the value of the 32-bit subregister of a 64-bit wide register. In other words, when constructing a proof of the program’s memory safety, the compiler keeps track of the maximum and minimum values held in the program’s registers. Given knowledge of the bounds of a 64-bit register, the compiler sometimes needs to derive what the upper and lower bounds will be when the program uses just the register’s lower 32 bits.

The flaw is illustrated as follows: If the 64-bit register has a lower bound that is within the range of values that can be represented in 32 bits, then the compiler would reason that the lower bound of the 32-bit subregister has the same lower bound. For example, if it is known that the 64-bit register has a lower bound of 1, then the compiler would record that the lower bound of the 32-bit subregister is also 1. This is a mistake, though. For example, the 64-bit register’s lower bound could be 1, but its value at runtime might be 0x100000000 (= 2^32). This value is greater than 1, so the lower bound holds true. But in this case, the 32-bit subregister contains a value of 0. This shows that it is not correct to conclude that the lower bound of the 32-bit subregister is also 1.

The correct calculation is as follows: If there is a 64-bit register and both its lower and upper bounds are within the range that can be represented in 32 bits, then both the lower and upper bounds can be applied to the 32-bit subregister as well. Otherwise, neither bound can be inferred.

Failures in bounds checking within eBPF are typically catastrophic to kernel security, and this bug is no exception. An attacker can use this to escalate privileges from a low-privileged user account to code execution in the kernel.

Apple Safari Integer Overflow Remote Code Execution Vulnerability

Returning to Pwn2Own 2021, we have this Safari RCE by Jack Dates of RET2 Systems, Inc. (@ret2systems). Addressed by Apple as CVE-2021-30734, the bug is in WebKit’s implementation of WebAssembly. At the contest, it was paired with an out-of-bounds write in a driver (CVE-2021-30735) to get kernel-mode remote code execution.

WebKit handles WebAssembly via several tiers of execution. The first tier involves translating the WebAssembly to a bytecode format known as LLInt (Low-Level Interpreter). Following this translation, there are two additional tiers of JIT compilation. However, this vulnerability is in the LLIntGenerator tier, which is the conversion to LLInt bytecode.

As LLIntGenerator makes its pass through the code, it keeps track of the stack space required at each point by incrementing and decrementing a field named m_stackSize. Through the use of a clever combination of WebAssembly features, our Pwn2Own contestant succeeded in incrementing m_stackSize to its maximum value of UINT_MAX. After rounding, this produces in a stack allocation zero bytes in size. Reads and writes based at this zero-length allocation give the WebAssembly script read/write access to copious amounts of adjacent memory.

For a thorough write-up of the vulnerability and the techniques used in exploitation, see the researcher’s blog here.


Thanks for joining us as we recapped some of the best bugs submitted to the ZDI program this year. We appreciate all those who submitted to the program over this past year. We can’t do what we do without the input and work of our global community of independent researchers. The program has certainly changed and grown over the years, but our desire to work with independent security researchers from around the globe has never wavered. If you haven’t submitted to the program, we hope you consider doing so in the future.

Β Until then, you can follow the ZDIΒ teamΒ on Twitter for the latest in exploit techniques and security patches.

The Top 5 Bugs Submitted in 2021

Abusing Arbitrary File Deletes to Escalate Privilege and Other Great Tricks

What do you do when you’ve found an arbitrary file delete as NT AUTHORITY\SYSTEM? Probably just sigh and call it a DoS. Well, no more. In this article, we’ll show you some great techniques for getting much more out of your arbitrary file deletes, arbitrary folder deletes, and other seemingly low-impact filesystem-based exploit primitives.

The Trouble with Arbitrary File Deletes

When you consider how to leverage an arbitrary file delete on Windows, two great obstacles present themselves:

  1. Most critical Windows OS files are locked down with DACLs that prevent modification even by SYSTEM. Instead, most OS files are owned by TrustedInstaller, and only that account has permission to modify them. (Exercise for the reader: Find the critical Windows OS files that can still be deleted or overwritten by SYSTEM!)
  2. Even if you find a file that you can delete as SYSTEM, it needs to be something that causes a β€œfail-open” (degradation of security) if deleted.

A third problem that can arise is that some critical system files are inaccessible at all times due to sharing violations.

Experience shows that finding a file to delete that meets all the above criteria is very hard. When looking in the usual places, which would be within C:\Windows, C:\Program Files or C:\Program Data, we’re not aware of anything that fits the bill. There is some prior work that involves exploiting antivirus and other products, but this is dependent on vulnerable behavior in those products.

The Solution is Found Elsewhere: Windows Installer

In March of 2021, we received a vulnerability report from researcher Abdelhamid Naceri (halov). The vulnerability he reported was an arbitrary file delete in the User Profile service, running as SYSTEM. Remarkably, his submission also included a technique to parlay this file delete into an escalation of privilege (EoP), resulting in a command prompt running as SYSTEM. The EoP works by deleting a file, but not in any of the locations you would usually think of.

To understand the route to privilege escalation, we need to explain a bit about the operation of the Windows Installer service. The following explanation is simplified somewhat.

The Windows Installer service is responsible for performing installations of applications. An application author supplies an .msi file, which is a database defining the changes that must be made to install the application: folders to be created, files to be copied, registry keys to be modified, custom actions to be executed, and so forth.

To ensure that system integrity is maintained when an installation cannot be completed, and to make it possible to revert an installation cleanly, the Windows Installer service enforces transactionality. Each time it makes a change to the system, Windows Installer makes a record of the change, and each time it overwrites an existing file on the system with a newer version from the package being installed, it retains a copy of the older version. In case the install needs to be rolled back, these records allow the Windows Installer service to restore the system to its original state. In the simplest scenario, the location for these records is a folder named C:\Config.Msi.

During an installation, the Windows Installer service creates a folder named C:\Config.Msi and populates it with rollback information. Whenever the install process makes a change to the system, Windows Installer records the change in a file of type .rbs (rollback script) within C:\Config.Msi. Additionally, whenever the install overwrites an older version of some file with a newer version, Windows Installer will place a copy of the original file within C:\Config.Msi. This type of a file will be given the .rbf (rollback file) extension. In case an incomplete install needs to be rolled back, the service will read the .rbs and .rbf files and use them to revert the system to the state that existed before the install.

This mechanism must be protected against tampering. If a malicious user were able to alter the .rbs and/or .rbf files before they are read, arbitrary changes to the state of the system could occur during rollback. Therefore, Windows Installer sets a strong DACL on C:\Config.Msi and the enclosed files.

Here is where an opening arises, though: What if an attacker has an arbitrary folder delete vulnerability? They can use it to completely remove C:\Config.Msi immediately after Windows Installer creates it. The attacker can then recreate C:\Config.Msi with a weak DACL (note that ordinary users are allowed to create folders at the root of C:\). Once Windows Installer creates its rollback files within C:\Config.Msi, the attacker will be able to replace C:\Config.Msi with a fraudulent version that contains attacker-specified .rbs and .rbf files. Then, upon rollback, Windows Installer will make arbitrary changes to the system, as specified in the malicious rollback scripts.

Note that the only required exploit primitive here is the ability to delete an empty folder. Moving or renaming the folder works equally well.

From Arbitrary Folder Delete/Move/Rename to SYSTEM EoP

In conjunction with this article, we are releasing source code for Abdelhamid Naceri’s privilege escalation technique. This exploit has wide applicability in cases where you have a primitive for deleting, moving, or renaming an arbitrary empty folder in the context of SYSTEM or an administrator. The exploit should be built in the Release configuration for either x64 or x86 to match the architecture of the target system. Upon running the exploit, it will prompt you to initiate a delete of C:\Config.Msi. You can do this by triggering an arbitrary folder delete vulnerability, or, for testing purposes, you can simply run rmdir C:\Config.Msi from an elevated command prompt. Upon a successful run, the exploit will drop a file to C:\Program Files\Common Files\microsoft shared\ink\HID.DLL. You can then get a SYSTEM command prompt by starting the On-Screen Keyboard osk.exe and then switching to the Secure Desktop, for example by pressing Ctrl-Alt-Delete.

The exploit contains an .msi file. The main thing that’s special about this .msi is that it contains two custom actions: one that produces a short delay, and a second that throws an error. When the Windows Installer service tries to install this .msi, the installation will halt midway and rollback. By the time the rollback begins, the exploit will have replaced the contents of C:\Config.Msi with a malicious .rbs and .rbf. The .rbf contains the bits of the malicious HID.DLL, and the .rbs instructs Windows Installer to β€œrestore” it to our desired location (C:\Program Files\Common Files\microsoft shared\ink\).

The full mechanism of the EoP exploit is as follows:

  1. The EoP creates a dummy C:\Config.Msi and sets an oplock.
  2. The attacker triggers the folder delete vulnerability to delete C:\Config.Msi (or move C:\Config.Msi elsewhere) in the context of SYSTEM (or admin). Due to the oplock, the SYSTEM process is forced to wait.
  3. Within the EoP, the oplock callback is invoked. The following several steps take place within the callback.
  4. The EoP moves the dummy C:\Config.Msi elsewhere. This is done so that the oplock remains in place and the vulnerable process is forced to continue waiting, while the filesystem location C:\Config.Msi becomes available for other purposes (see further).
  5. The EoP spawns a new thread that invokes the Windows Installer service to install the .msi, with UI disabled.
  6. The callback thread of the EoP continues and begins polling for the existence of C:\Config.Msi. For reasons that are not clear to me, Windows Installer will create C:\Config.Msi, use it briefly for a temp file, delete it, and then create it a second time to use for rollback scripts. The callback thread polls C:\Config.Msi to wait for each of these actions to take place.
  7. As soon as the EoP detects that Windows Installer has created C:\Config.Msi for the second time, the callback thread exits, releasing the oplock. This allows the vulnerable process to proceed and delete (or move, or rename) the C:\Config.Msi created by Windows Installer.
  8. The EoP main thread resumes. It repeatedly attempts to create C:\Config.Msi with a weak DACL. As soon as the vulnerable process deletes (or moves, or renames) C:\Config.Msi, the EoP’s create operation succeeds.
  9. The EoP watches the contents of C:\Config.Msi and waits for Windows Installer to create an .rbs file there.
  10. The EoP repeatedly attempts to move C:\Config.Msi elsewhere. As soon as Windows Installer closes its handle to the .rbs, the move succeeds, and the EoP proceeds.
  11. The EoP creates C:\Config.Msi one final time. Within it, it places a malicious .rbs file having the same name as the original .rbs. Together with the .rbs, it writes a malicious .rbf.
  12. After the delay and the error action specified in the .msi, Windows Installer performs a rollback. It consumes the malicious .rbs and .rbf, dropping the DLL.

Note that at step 7, there is a race condition that sometimes causes problems. If the vulnerable process does not immediately awaken and delete C:\Config.Msi, the window of opportunity may be lost because Windows Installer will soon open a handle to C:\Config.Msi and begin writing an .rbs there. At that point, deleting C:\Config.Msi will no longer work, because it is not an empty folder. To avoid this, it is recommended to run the EoP on a system with a minimum of 4 processor cores. A quiet system, where not much other activity is taking place, is probably ideal. If you do experience a failure, it will be necessary to retry the EoP and trigger the vulnerability a second time.

From Arbitrary File Delete to SYSTEM EoP

The technique described above assumes a primitive that deletes an arbitrary empty folder. Often, though, one has a file delete primitive as opposed to a folder delete primitive. That was the case with Abdelhamid Naceri’s User Profile bug. To achieve SYSTEM EoP in this case, his exploit used one additional trick, which we will now explain.

In NTFS, the metadata (index data) associated with a folder is stored in an alternate data stream on that folder. If the folder is named C:\MyFolder, then the index data is found in a stream referred to as C:\MyFolder::$INDEX_ALLOCATION. Some implementation details can be found here. For our purposes, though, what we need to know is this: deleting the ::$INDEX_ALLOCATION stream of a folder effectively deletes the folder from the filesystem, and a stream name, such as C:\MyFolder::$INDEX_ALLOCATION, can be passed to APIs that expect the name of a file, including DeleteFileW.

So, if you are able to get a process running as SYSTEM or admin to pass an arbitrary string to DeleteFileW, then you can use it not only as a file delete primitive but also as a folder delete primitive. From there, you can get a SYSTEM EoP using the exploit technique discussed above. In our case, the string you want to pass is C:\Config.Msi::$INDEX_ALLOCATION.

Be advised that success depends on the particular code present in the vulnerable process. If the vulnerable process simply calls DeleteFileA/DeleteFileW, you should be fine. In other cases, though, the privileged process performs other associated actions, such as checking the attributes of the specified file. This is why you cannot test this scenario from the command prompt by running del C:\Config.Msi::$INDEX_ALLOCATION.

From Folder Contents Delete to SYSTEM EoP

Leveling up once more, let us suppose that the vulnerable SYSTEM process does not allow us to specify an arbitrary folder or file to be deleted, but we can get it to delete the contents of an arbitrary folder, or alternatively, to recursively delete files from an attacker-writable folder. Can this also be used for EoP? Researcher Abdelhamid Naceri demonstrated this as well, in a subsequent submission in July 2021. In this submission he detailed a vulnerability in the SilentCleanup scheduled task, running as SYSTEM. This task iterates over the contents of a temp folder and deletes each file it finds there. His technique was as follows:

  1. Create a subfolder, temp\folder1.
  2. Create a file, temp\folder1\file1.txt.
  3. Set an oplock on temp\folder1\file1.txt.
  4. Wait for the vulnerable process to enumerate the contents of temp\folder1 and try to delete the file file1.txt it finds there. This will trigger the oplock.
  5. When the oplock triggers, perform the following in the callback:
    a. Move file1.txt elsewhere, so that temp\folder1 is empty and can be deleted. We move file1.txt as opposed to just deleting it because deleting it would require us to first release the oplock. This way, we maintain the oplock so that the vulnerable process continues to wait, while we perform the next step.
    b. Recreate temp\folder1 as a junction to the β€˜\RPC Controlfolder of the object namespace. c. Create a symlink at\RPC Control\file1.txtpointing toC:\Config.Msi::$INDEX_ALLOCATION`.
  6. When the callback completes, the oplock is released and the vulnerable process continues execution. The delete of file1.txt becomes a delete of C:\Config.Msi.

Readers may recognize the symlink technique involving \RPC Control from James Forshaw’s symboliclink-testing-tools. Note, though, that it’s not sufficient to set up the junction from temp\folder1 to \RPC Control and then let the arbitrary file delete vulnerability do its thing. That’s because \RPC Control is not an enumerable file system location, so the vulnerable process would not be able to find \RPC Control\file1.txt via enumeration. Instead, we must start off by creating temp\folder1\file1.txt as a bona fide file, allowing the vulnerable process to find it through enumeration. Only afterward, just as the vulnerable process attempts to open the file for deletion, we turn temp\folder1 into a junction pointing into the object namespace.

For working exploit code, see project FolderContentsDeleteToFolderDelete. Note that the built-in malware detection in Windows will flag this process and shut it down. I recommend adding a β€œProcess” exclusion for FolderContentsDeleteToFolderDelete.exe.

You can chain these two exploits together. To begin, run FolderOrFileDeleteToSystem and wait for it to prompt you to trigger privileged deletion of Config.Msi. Then, run FolderContentsDeleteToFolderDelete /target C:\Config.Msi. It will prompt you to trigger privileged deletion of the contents of C:\test1. If necessary for your exploit primitive, you can customize this location using the /initial command-line switch. For testing purposes, you can simulate the privileged folder contents deletion primitive by running del /q C:\test1\* from an elevated command prompt. FolderContentsDeleteToFolderDelete will turn this into a delete of C:\Config.Msi, and this will enable FolderOrFileDeleteToSystem to drop the HID.DLL. Finally, open the On-Screen Keyboard and hit Ctrl-Alt-Delete for your SYSTEM shell.

From Arbitrary Folder Create to Permanent DoS

Before closing, we’d like to share one more technique we learned from this same researcher. Suppose you have an exploit primitive for creating an arbitrary folder as SYSTEM or admin. Unless the folder is created with a weak DACL, it doesn’t sound like this would be something that could have any security impact at all. Surprisingly, though, it does: it can be used for a powerful denial of service. The trick is to create a folder such as this one:

Β Β Β Β Β Β C:\Windows\System32\cng.sys

Normally there is no file or folder by that name. If an attacker name squats on that filesystem location with an extraneous file or even an empty folder, the Windows boot process is disrupted. The exact mechanism is a bit of a mystery. It would appear that Windows attempts to load the cng.sys kernel module from the improper location and fails, and there is no retry logic that allows it to continue and locate the proper driver. The result is a complete inability to boot the system. Other drivers can be used as well for the same effect.

Depending on the vulnerability at hand, this DoS exploit could even be a remote DoS, as nothing is required besides the ability to drop a single folder or file.

Conclusion

The techniques we’ve presented here show how some rather weak exploit primitives can be used for great effect. We have learned that:

β€’ An arbitrary folder delete/move/rename (even of an empty folder), as SYSTEM or admin, can be used to escalate to SYSTEM.
β€’ An arbitrary file delete, as SYSTEM or admin, can usually be used to escalate to SYSTEM.
β€’ A delete of contents of an arbitrary folder, as SYSTEM or admin, can be used to escalate to SYSTEM.
β€’ A recursive delete, as SYSTEM or admin, of contents of a fixed but attacker-writable folder (such as a temp folder), can be used to escalate to SYSTEM.
β€’ An arbitrary folder create, as SYSTEM or admin, can be used for a permanent system denial-of-service.
β€’ An arbitrary file delete or overwrite, as SYSTEM or admin, even if there is no control of contents, can be used for a permanent system denial-of-service.

We would like to thank researcher Abdelhamid Naceri for his great work in developing these exploit techniques, as well as for the vulnerabilities he has been reporting to our program. We look forward to seeing more from him in the future. Until then, you can find me on Twitter at @HexKitchen, and follow the team for the latest in exploit techniques and security patches.

Abusing Arbitrary File Deletes to Escalate Privilege and Other Great Tricks

  • There are no more articles
❌