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

CVE-2021-31969: Underflowing in the Clouds

21 July 2021 at 15:16

With the popularity of cloud storage, various operating systems have added services and functionalities to support such storage. You can now have your storage in the cloud while exploring it locally on your system. On Windows, this is done via the Cloud Sync Engine. This component exposes a native API known as the Cloud Filter API. The implementation is found in the Cloud Files Mini Filter Driver, or cldflt.sys. The purpose of this blog is to provide some details about an integer underflow vulnerability within this driver tracked as CVE-2021-31969/ZDI-21-797, which was originally reported to the ZDI by an anonymous researcher. It can be exploited to overflow a kernel buffer and gain code execution with escalated privileges.

A quick look at Cloud Sync Engines

The Cloud Files API in Windows has been available since Windows 10 version 1709. It offers support for cloud sync engines and handles tasks such as creating and managing placeholder files and directories. A sync engine is a service that syncs files between a remote host and a local client in a way that allows cloud-hosted files and directories to be available to local users through the Windows file system and File Explorer. In this scenario, the file itself resides in the cloud, while on your local filesystem, there is a representation of that file known as a β€œplaceholder.” Your file in the cloud might be huge, but a placeholder file might consume only the few bytes needed to store headers. When you access a placeholder file, Windows makes the associated cloud file available via syncing. The vulnerability can be triggered during the processing of placeholder files.

Method of triggering the vulnerability

Here is a description of the key steps in the proof of concept:

1: It starts by performing a sync root registration. It then initiates the communication between a sync provider and the sync filter API:

2: It gets a handle to the target directory and retrieves the reparse point data via an FSCTL_GET_REPARSE_POINT control code:

3: It modifies the retrieved reparse point data, setting the length to zero. It then sets it back via an FSCTL_SET_REPARSE_POINT_EX control code (with the tag set to 0x9000301A which is IO_REPARSE_TAG_CLOUD_3). Finally, it sets parameters to ask for a placeholder update (code= 0xC0000003) via the cloud filter FSCTL (0x903BC):

The Kernel Bug

As we mentioned, a kernel driver called cldflt.sys is responsible for processing cloud filter FSCTLs. As usual, this is accomplished using a function with a large switch statement. This function is named HsmFltProcessHSMControl:

Figure 1 - The HsmFltProcessHSMControl Function

Figure 1 - The HsmFltProcessHSMControl Function

For an operation with code 0xC0000003, it will eventually call HsmFltProcessUpdatePlaceholder:

Figure 2 - Call to HsmFltProcessUpdatePlaceholder

Figure 2 - Call to HsmFltProcessUpdatePlaceholder

After some processing, the execution flow will reach HsmpRpReadBuffer. It first allocates a buffer then retrieves reparse point data by issuing an FSCTL_GET_REPARSE_POINT control code. Note that the retrieved data may have been modified by the attacker. Afterward, it calls HsmpRpiDecompressBuffer:

Figure 3 - Calling HsmpRpiDecompressBuffer

Figure 3 - Calling HsmpRpiDecompressBuffer

Inside HsmpRpiDecompressBuffer, the provided length (which the attacker has set to zero) is retrieved and increased by 8. It is saved in a local variable (length) and then is used to allocate a kernel buffer. Shortly afterward, the code proceeds to decompress data via a call to RtlDecompressBuffer using the allocated buffer as the destination buffer for the uncompressed data. However, the pointer it passes to RtlDecompressBuffer is not the start of the allocated buffer. Instead, it is advanced by 12 bytes to make room for some metadata. Correspondingly, the buffer size it passes to RtlDecompressBuffer is length minus 12. In the disassembly shown below, the subtraction is seen optimized as an ADD. In our case, this subtraction produces an integer underflow, so that a huge buffer length value of 0xFFFFFFF4 is passed to RtlDecompressBuffer. This enables a kernel buffer overflow.

Figure 4 - Showing the integer underflow

Figure 4 - Showing the integer underflow

The Patch

Microsoft fixed this vulnerability by adding a check to make sure the retrieved length is not less than 4. This makes it impossible to trigger an integer underflow.

Figure 5 - Patch from Microsoft

Figure 5 - Patch from Microsoft

Final notes

New technologies are always on the way and operating systems must add new features to support such technologies and bring them to the end users. Researchers can always expect vulnerabilities in such a fresh piece of code no matter how good programmers are or how thorough a vendor checks and performs fuzzing to catch errors and vulnerabilities.

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

CVE-2021-31969: Underflowing in the Clouds

  • There are no more articles
❌