There are new articles available, click to refresh the page.
Before yesterdayZero Day Initiative - Blog

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:


“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:


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:


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


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.


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

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.


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:


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.


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

CVE-2021-27076: A Replay-Style Deserialization Attack Against SharePoint

An attacker is frequently in the position of having to find a technique to evade some data integrity measure implemented by a target. One instructive example of a data integrity measure is a message authentication check. Generally, message authentication is achieved by appending some form of a cryptographic tag to a message. Calculating the correct value for the tag is possible only with knowledge of a secret key held by the legitimate sender. When the target receives a message, the target can check that the tag has been calculated correctly. A correct calculation proves that the message was authorized by the legitimate sender.

An attacker who wishes to concoct some other message and convince the target that it was authorized by the sender faces a challenge. Typically, the attacker cannot calculate the proper tag that must be appended, because the attacker is not in possession of the secret key.

In such a circumstance, what are the attacker’s options? An important realization is this: While the attacker herself does not know the secret key, there is at least one actor in the picture who does, namely, the legitimate sender. Perhaps the attacker can interact with the sender in such a way that the sender will be influenced to authorize the very message that the attacker wishes to send to the target (or one close enough).

Naturally, a system will not be designed in such a way that an attacker can ask directly to have an arbitrary message authorized. That would defeat the entire purpose of including an authorization code in the system’s design. On the contrary, the sender is presumably designed to authorize only those messages that it intends the target to accept as authentic. Nevertheless, there is an insidious and underappreciated danger lurking within this very common security design pattern we have just described.

The essence of the problem is centered on the word “intends” in the previous paragraph. For a secure system, what we really need is for the recipient to be able to prove that the sender has a particular intent. In reality, what we have is a cryptographic scheme that proves that the sender has emitted a message consisting of a particular sequence of bits. Is this good enough? The answer depends upon how precisely the sender’s intent can be inferred from the binary message.

Let us make this clear with a concrete example. Here, “Bob” and “Alice” are two legitimate actors. They could be automated systems, or they could be humans communicating over an electronic medium. Suppose that, in the course of an exchange, Bob asks Alice whether Alice wishes to proceed with a particular transaction. Alice replies “YES” and appends a cryptographic tag, proving that Alice authorizes the message that says “YES”. Bob receives the “YES” message together with the tag, verifies that the tag has been calculated correctly, and concludes that Alice has authorized proceeding with the transaction.

This conclusion is on shaky ground, though. When we look a bit more closely, we can easily see that all that Bob can really conclude is that Alice has said “YES” to someone, sometime, in regard to something. Bob is not really justified in concluding anything about Alice’s intent.

An attacker can exploit this as follows. First, the attacker records Alice’s “YES” response, in some context, perhaps an inconsequential one. Alice’s “YES” is accompanied by a valid message authorization code, calculated by Alice herself (or Alice’s equipment). Later, the attacker replays Alice’s “YES” response, together with the valid code, convincing Bob that Alice has said “YES” in an entirely different context (or perhaps simply at a later date). The essential problem is that Alice’s “YES” response does not contain enough information to uniquely identify her intent.

Interestingly, the FCC has warned that scammers have been executing an attack following this exact pattern, by eliciting a verbal “yes” from human victims over the phone. In this instance, no cryptographic authenticators are in use. Rather, an individual’s unique voice is the basis for authenticating messages.

For an example of an attack of this nature against an automated system using cryptographic message authentication, see Michal Zalewski’s ASP.NET VIEWSTATE bug CVE-2005-1664 (variant 1a).

Attacks of this sort are known as replay attacks since they involve replaying a response generated by a legitimate actor in a context not intended by that actor. The different context might simply be a later time, or it might involve taking the message out of its intended context in some more sophisticated fashion.

Attacking SharePoint Session

The above introduction will help us appreciate the nature of a rather amazing attack against SharePoint, submitted to us by an anonymous researcher and given the identifiers ZDI-21-276 / CVE-2021-27076.

In the implementation of SharePoint’s InfoPath functionality, documents are serialized and stored in session state. From there, they may be retrieved by key (editingSessionId) and deserialized. Relevant code outtakes are as follows:

Data read from session state is ultimately passed to BinaryFormatter.Deserialize. If an attacker can specify arbitrary data here, code execution can result.

The challenge facing the attacker here is somewhat similar to the scenario described above in regard to message authentication. The difference is that, in this case, what stands in the attacker’s way is not a cryptographic authentication code, but rather the fact that the attacker has no access to session state and cannot place arbitrary data there at will.

As above, though, the attacker still has an available option. While the attacker has no direct control over the contents of session state, there is another actor present that does: namely, the SharePoint application itself. Perhaps the SharePoint application can be influenced to place the attacker’s chosen data into session state?

Surely there is no direct way to accomplish this, as it would be folly to design an application in such a way that an untrusted user can make arbitrary modifications to session state. Rather, all edits to session state are moderated through the application itself, so that anything that ends up in session state is, in effect, authorized by the application to reside there.

This is the point where the thorny problem of intent rears its head. Though the SharePoint application would not place into session state arbitrary user-supplied data with the intent of that data being read back by the deserialization mechanism, it remains within the realm of possibility that SharePoint could be influenced to place such data there with some alternative intent. In fact, that turns out to be the case. SharePoint also uses the session state mechanism to store arbitrary user-supplied files during attachment upload operations. This is at the core of the vulnerability, though there is still more for us to explain.

Under normal operating conditions, these two different types of data in session state never mix. Each blob added to session state is stored under a unique key (as in the editingSessionId variable discussed above). During attachment upload operations, data is normally retrieved from session state using the key corresponding to a data item that was placed there with the intent of it being used in attachment upload operations. Similarly, during DocumentSessionState deserialization operations, data is normally retrieved using a key that corresponds to a data item that was placed into session state with the intent of it being used in DocumentSessionState deserialization. Hence nothing untoward happens during typical operations.

The next piece of the vulnerability is that the editingSessionId can be influenced from the client side. By replacing one key value for another on the client side, it becomes possible to influence the server to retrieve data from session state placed there with one intent (attachment upload), and replay it in a different context, so that it enters the DocumentSessionState deserialization code path.

There is one final difficulty for the attacker. When uploading an attachment, the corresponding session state key is not visible from the client side. It is present only on the server side, within the DocumentSessionState object. Our anonymous researcher solved this problem by performing an additional attack in the reverse direction: feeding the document’s state key into the attachment mechanism, so that the server replays a serialized DocumentSessionState as an attachment and returns it to the client. Within the serialized bytes, the state key of the attachment can be found.

The final exploit is highly reliable but has numerous steps. We present a simplified version below:

  1. Create an InfoPath list.
  2. Begin adding a new item to the list.
  3. Attach a file to the item. The file contains a fake InfoPath DocumentSessionState including arbitrary objects to be deserialized. The file’s extension can be set to anything InfoPath allows for extensions, for example, .png. After attaching this file, do not save the form.
  4. Scrape the document’s state key from the page’s HTML.
  5. Feed the document’s state key to the FormServerAttachments.aspx page, maliciously replaying the DocumentSessionState into the attachment mechanism. The entire serialized DocumentSessionState is returned to the client as if it were an attached file.
  6. From within the returned data, extract the state key of the attachment added in step 3.
  7. Feed the attachment’s state key into an undocumented client-side API, maliciously replaying the attachment into the deserialization mechanism. Remote code execution is achieved when the arbitrary objects present in the attachment are deserialized on the server.

Microsoft patched this vulnerability in March as CVE-2021-27076. All supported versions of SharePoint Server, including Microsoft Business Productivity Servers 2010 Service Pack 2, are affected by this vulnerability. We recommend applying the patch to affected systems.


Correct system design hinges upon the proper interchange of messages. It is well understood that cryptographic techniques such as message authentication codes are needed to assure the integrity of data in transit, and that access control is required to assure the integrity of data at rest, which we may think of as messages generated by a system to be consumed later by the same system. When applying these security techniques, however, it is also crucial to keep in mind the semantics of how the data will be consumed. Even where the integrity of binary data itself is assured by the application of appropriate security measures, the security of the system as a whole may nonetheless be compromised if an attacker can alter some context that affects how the data is ultimately interpreted.

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

CVE-2021-27076: A Replay-Style Deserialization Attack Against SharePoint

ZDI-CAN-12671: Windows Kernel DoS/Privilege Escalation via a NULL Pointer Deref

28 January 2021 at 16:16

This blog details a NULL pointer dereference in the Windows win32kfull.sys kernel-mode graphics module discovered by ZDI contributor Marcin Wiązowski. It can be used to create a denial-of-service condition. In limited circumstances, it can be used for privilege escalation, though if modern mitigations are present privilege escalation will not be possible. Due to the limited impact, Microsoft has made the decision not to service this bug report. As such, we disclosed the vulnerability as a 0-day according to our policy. This article details the vulnerability, ZDI-CAN-12671, and explains its impact.

The Vulnerability

In win32k, any drawing operation is performed upon an abstracted drawing surface (“surface”) represented in the kernel by a SURFOBJ structure:

Two fields are highlighted above. The field hdev is a handle to a particular device driver. The field flags is partially undocumented, but some of the flags that it can contain are the HOOK_* flags documented here. Each HOOK_* flag indicates that a particular graphics primitive should be delegated to the device driver specified by hdev. For example, HOOK_BITBLT indicates that every BitBlt drawing operation performed on the surface should be delegated to the appropriate DrvBitBlt primitive offered by the device driver.

The bug is found in the function win32kfull.sys!BLTRECORD::bRotate, specifically in the one that takes four parameters. Within this function, it performs a PlgBlt drawing operation on a surface. If HOOK_PLGBLT is set in the flags field of the SURFOBJ, it delegates to the underlying device driver’s DrvPlgBlt, as explained above. The problem, though, is that it fails to check whether the driver specified by hdev actually offers a native DrvPlgBlt. If no such function is offered by the driver, the corresponding entry in the driver’s function table will be NULL, and win32kfull.sys!BLTRECORD::bRotate will attempt to perform a call to the NULL address.

The various HOOK_* flags can be set from user mode by calling gdi32!EngAssociateSurface. There are some additional details involved in preparing a surface for exploiting this bug, but those are secondary to the vulnerability and are beyond the scope of this article.

Exploitation Potential

To exploit this, the first thing needed is a graphics output device driver that does not export a DrvPlgBlt function. One such driver is the multi-monitor driver implemented in win32kfull itself. The exported functions of this driver are recognizable by the Mul prefix in their names, for example, win32kfull!MulBitBlt. Notably for our purposes, there is no win32kfull!MulPlgBlt. This device driver is available on any system with multiple active monitors.

Without further preparation, triggering the vulnerability produces a branch to address 0 in kernel mode, crashing the system.

Is it possible to exploit this bug for greater impact, such as a kernel escalation of privilege? Yes, but there are significant preconditions that drastically restrict when it is possible:

  1. It must be possible to map the NULL page and place executable code there. On currently-supported Windows systems, mapping the NULL page is not possible from an unprivileged user-mode process. There is one known exception, though: The NULL page can still be mapped in a 16-bit process. 16-bit processes can be created only if the NTVDM subsystem is installed. Note that a non-administrator cannot install the NTVDM subsystem, but if this subsystem has already been installed by an administrator, it can be utilized afterward by a non-privileged user. NTVDM is available only on 32-bit installations of Windows.
  2. Even if a user-mode process maps a page of executable memory at address 0, this page will be executable in user mode only but will not be executable in kernel mode. This is due to SMEP [PDF]. Kernel execution at access 0 can be achieved only on processors that do not offer the SMEP mitigation, or by disabling SMEP via processor control register CR4.

In summary, privilege escalation is possible only on a 32-bit installation of Windows, with NTVDM installed, and where the processor does not offer the SMEP mitigation. However, it should be noted that these conditions may be relaxed if the attacker has knowledge of additional vulnerabilities that can be exploited for SMEP bypass or NULL page mapping. In his submission, Marcin did include working proof-of-concept code that demonstrates privilege escalation under a specific set of circumstances. While the risk to users is small, it is not zero. It is our hope Microsoft reconsiders and produces a patch to address this bug in the future.

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

ZDI-CAN-12671: Windows Kernel DoS/Privilege Escalation via a NULL Pointer Deref

  • There are no more articles