CVE-2022-26809 was patched in Microsoft’s previous Patch Tuesday (April 12) and it’s a doozy: remote code execution on affected versions of DCE/RPC hosts. The vulnerability attracted a lot of attention in the security community, both because of its severity but also because it appears to be really hard to trigger. That and the current (as of May 16) lack of a POC floating around is somewhat comforting—plus what should put you more at ease is that (1) Microsoft has suggested temporary mitigations, and (2) we are open-sourcing a Zeek® package that detects attempts and successful exploitation in unencrypted DCE/RPC.
From a POC given to us through the Microsoft Active Protections Program, we were able to generate network traffic of an exploit in action, as well as reverse-engineer the behavior sufficiently to write a robust detection for it. And due to our extensive Polaris program, we have been able to improve the code’s accuracy such that we can still detect exploits while reducing the false positives to zero, as best as we can tell.
At a high-level, the exploit relies on a specially crafted Bind_ack
packet to trigger the vulnerable code. These are detected in our Zeek package and the CVE_2022_26809::ExploitSuccess
notice is raised. To aid in detecting scanners, we also flag possible attempts with the CVE_2022_26809::ExploitAttempt
notice.
Figure 1: Attack Bind_ack
packet.
Figure 1 shows a malicious Bind_ack
. We’ve highlighted the important aspects in the Wireshark window:
Bind_ack
),Scndry Addr len
is 0, andThis third and fourth are worth highlighting. No. 3 leads to an integer underflow, which was (more or less) hypothesized by at least @MalwareJake’s and @MalwareTechBlog’s patch analysis efforts and confirmed by Microsoft. No. 4 is to force the DCE/RPC server to convert the endianness of the input data. This leads to a code path where the underflowed value is used for out-of-bound reads and writes, which can lead to RCE. Given that most implementations of DCE/RPC default to little-endian byte order (see Endianness selection, pg 23), we look for big-endian. Our Zeek package explicitly checks #1, #3, and #4 and implicitly checks #2 by using the dce_rpc_message
event, instead of dce_rpc_bind_ack
. The latter will only fire for well-formed Bind_ack
packets, which isn’t the case here. We suspect the malformed aspect exacerbates the underflow, but have not confirmed that this is the case.
Figure 2: Initial request to begin unauthorized access.
We may also want to flag attempts, regardless if they were successful or not. We can detect this by looking for a malicious Samba server being referenced by the attacker in a DCE/RPC request. Figure 2 shows a Wireshark snippet of the type of packet we alert on. In our lab, 192.168.56.104
is the IP of the attacking SMB server and 192.168.56.102
is the victim server. The attacker is sending an EfsRpcDecryptFileSrv
request over DCE/RPC to the victim machine as a DCE/RPC request. Note that the path of the file is located on the attacker’s file server. This particular kind of request is not common from what we have seen in the wild. Since we need the request’s stub data to check for the attacker’s IP address in the file path, we use the dce_rpc_request_stub
event handler.
The flexibility of Zeek not only makes it easy to write detections, but also auxiliary functionality to make the detections more robust. Note the additional function correct_frag_length, which ensures that the Frag Length field reported above in Figure 1 also matches the payload size. This makes it less likely we raise a notice erroneously. One of the many reasons we love Zeek!
Zeek users can install this logic via zkg with the following command:
$ zkg install cve-2022-26809
Corelight customers can install this package via the CVE bundle.