CVE-2021-31969: Underflowing in the Clouds
July 21, 2021 | Hossein LotfiWith 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
:
For an operation with code 0xC0000003
, it will eventually call 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
:
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.
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.
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.