We have published an initial blog on the Log4j exploit and a followup blog with a second detection method for detecting the first stage of exploits occurring over LDAP. Today, we will discuss a third detection method, this one focused on the second-stage download that happens after the first stage completes. In this case, the JVM will download additional Java code payloads over HTTP. Note that the technique we outline here works even if a vector other than LDAP is used for the first stage, as has been recently reported.
If you download this PCAP and open it in Wireshark, you will see the following headers in the exploit’s HTTP GET:
The User-Agent is “Java/1.8.0_51”, signifying Java initiated this download. It is downloading a file called “Exploit.class”, which is a Java class file. The server reports this file as having a MIME type of “application/java-vm”:
We can code a detection for this scenario using Zeek. We added this detection to our CVE-2020-44228 Zeek package in a file named “CVE_2021_44228_java_GET.zeek”. At the top of the file, we set up our new notices for this detection type (lines 3-5). In lines 7-9, we add a variable to the connection record to save some associated state. You will see in lines 12 and 14 regular expressions to detect Java in the User-Agent and MIME fields.
Next, we handle the event “http_header”. In that event handler, we use our patterns to search for the Java MIME type in the HTTP headers. If we find a match, we note it in the connection record variable we created previously. We skip this processing, however, if (1) the request method was something other than “GET”, (2) the headers are from the client rather than server, or (3) we’ve already seen what we’re looking for.
Lastly, we process the “http_end_entity” event. HTTP entities can be nested, so first we check to see that we’re processing the outermost (non-nested) entity. We then see whether either we’d already seen an HTTP header indicating that this entity is Java, or that Zeek assigned one or more MIME types to the entity (which it does by “sniffing” the body of the entity) and one of those matches the pattern we’re looking for. If either of these hold, and if the user agent indicates the request came from Java, then we mark the connection as reflecting a successful log4j RCE, and generate a Notice.
When this detection occurs, a Notice of type “LOG4J_JAVA_CLASS_DOWNLOAD” will be written to your notice log.
With this detection, we have now covered all stages of the most common LDAP based Log4j exploits that are currently found on the Internet.
We have identified the inbound attack attempts and harvested the sites that they will reach out to if successful.
We have identified LDAP connections used in the first stage of an attack to induce downloading of Java code.
We have found instances where a now-compromised JVM proceeds to the second stage and downloads the final payload.
An important benefit of this final detection is that it works even in the presence of a first stage vector other than LDAP.