September 21, 2021 by Ben Reardon
Researchers at wiz.io recently found a series of vulnerabilities in Windows Open Management Infrastructure (OMI) software, which is widely installed on cloud-based Azure Linux Agents. We have open-sourced a Zeek package for the most severe of these vulnerabilities, which we’ll discuss later in this blog. You can access the repo here: https://github.com/corelight/CVE-2021-38647
One of the four vulnerabilities found is a trivially exploitable unauthenticated remote code execution (RCE). At the heart of the vulnerability is a simple bug in the authorization checking code whereby these checks are effectively bypassed by sending a request without an authorization header.
The researchers dubbed this bug “OMIGOD” and it received CVE-2021-38647 which has a CVSS score of 9.8 out of 10. If in doubt as to your exposure, you can check Microsoft’s advisory, which explains the issue in detail, including mitigating factors, notably that OMI is not always exposed on the network by default. https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-38647
The table below shows the effects of the removal of the authorization header:
To illustrate this vulnerability in a more visual network-centric manner, these screenshots show the same three scenarios.
Figure 1: Scenario 1. Correct behavior with a proper authorization token
Figure 2: Scenario 2, Correct behavior with incorrect authorization token
Figure 3: Scenario 3, Incorrect behaviour with no authorization header
When we set about creating a Zeek package we found that the exploit itself was quite trivial to reproduce and proof of concept (POC) code was also readily circulating. We set up a lab to attain pcaps and quickly developed an initial package. One might initially think that looking for this exploit should be as simple as looking for connections to the default OMI ports without an authorization header, however there are almost always unexpected edge cases in real world traffic. An example of an edge case are Layer 7 Keep-alive packets with Zero content length; these don’t have authorization headers, but do not represent an attack. Performance issues are also often critical, particularly for high volume events like HTTP at busy sites. The code in the repo is commented to highlight some of these factors - and a tip of hat to our Justin Azoff for helping out yet again with performance suggestions. All of these issues often arise for detection algorithms that seem like they should be trivial, but actually can get complicated quite quickly. Thankfully we have access to at-scale real-world traffic, as this highlights these issues and is vital for increasing the performance and fidelity of packages like this.
As we continued tuning the package to cater for these cases, we noticed that the exploit was being actively used to install the Mirai botnet, as also described in this useful and timely OMI hunting guide released by Microsoft. In one of the Mirai cases, we observed the payload was a base64-encoded instruction to fetch and run the malicious code. As shown in the screenshot, by design the notice produced by our package provides the data that an IR analyst or threat hunter would be interested in, all without having to pivot to a pcap.
Figure 4: Notice showing exploit payload and decode of same
In other notices we found various payloads with instructions to wget content from an Indonesian IP address.
Figure 5: Additional payloads observed
In another case, we saw an IP from Russia spoofing a browser user agent, presumably to avoid detection. We had predicted this may occur, and designed the package so as not to rely on brittle indicators. Interesting, it’s also evident in the notice the lineage of POC exploit they copied from was https://attackerkb.com/topics/08O94gYdF1/cve-2021-38647 because the
MessageID was originally used in the attackerKB payload. The following screenshot shows the three notices that the package raised when this scan occured, highlighting useful IR triage information in the notice itself.
Figure 6: Spoofed Browser User Agent
This is a good opportunity to discuss the value of generalizing detection algorithms. In this case, a curl or python user agent connecting to your OMI may be highly unusual - and therefore a valid detection algorithm depending on your use case, however it can also be very brittle as the user agent can easily be spoofed, as shown above. Similarly, detections looking for highly specific indicators used by a particular proof of concept payload (for example the
MessageID uuid as described above) can also be quite brittle as these don’t take much effort for an attacker to change. These highly specific styles of detections may work on a particular POC, but when the POC is amended by a concerted attacker, or another POC is released, these detections can fail because the highly specific indicator is no longer present. This is where more general indicators (like the ones used in our package are useful) that detect the underlying vulnerability being exploited are required. Generalizing detection algorithms almost always means more time and effort is needed to ensure that no (or not too many) False Positives are introduced, and this balancing act is where the art of performant and effective detection engineering comes into play. In practice, all detection algorithms live on a spectrum between highly specific and highly generalized, the challenge is to decide where on that spectrum is acceptable for your threat model.
In summary, here we have the following elements:
By Ben Reardon, Senior Security Researcher, Corelight Labs