Since the publication of the Log4Shell exploit there have been a lot of developments surrounding the Log4j CVE, leading to several new versions of the package to fix the workarounds that people found for the mitigations. During this time, there were also many people focusing their efforts on finding evasive methods to bypass mitigations put in place that block exploitation by monitoring for the exploitation string.
Because of the variety of the evasive methods, and the different protocols that can be used to exploit the vulnerability, we have created pcaps and an overview to assist security engineers in their endeavours to check their current detection coverage.
RIFT has used an environment to test different scenarios with the purpose of automatically creating pcaps and testing network coverage for the Remote Code Execution (RCE) vectors of Log4Shell using LDAP
and RMI
.
We tested different vectors that attackers could use in real-world scenarios, focusing on the HTTP protocol as this has been observed being used in the wild. Please keep in mind that HTTP is by no means the only protocol attackers can use to trigger the vulnerability in applications using a vulnerable version of Log4j. Any string that is logged by a vulnerable Log4j is subject to exploitation. We have also seen different evasion techniques, so these have also been tested for coverage.
We want to emphasize that we already observed attackers using encoded variants of the available protocols (HTTP Basic Authorization) and that there are plentiful other encoding methods that might still be logged decoded by the application using a vulnerable Log4j package.
We have used the following tools for testing the exploitation:
- JNDIExploit for LDAP github repo down
- JNDI-Exploit-Kit for LDAP and RMI
For web applications that is vulnerable to log4shell we have used:
The tables displayed below give an overview of the different evasion methods and their respective coverage. The PCAP filenames contain the ev
string to mark the evasion ID.
EV | Payload |
---|---|
1 | ${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}:// ${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}:// |
2 | ${${lower:jndi}:${lower:ldap}:// ${${::-j}ndi:rmi:// |
3 | ${${lower:${lower:jndi}}:${lower:ldap}:// ${${lower:jndi}:${lower:rmi}:// |
4 | ${${lower:j}${lower:n}${lower:d}i:${lower:ldap}:// ${${lower:${lower:jndi}}:${lower:rmi}:// |
5 | ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:l}d${lower:a}p:// ${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}:// |
6 | ${j${env:DOESNOTEXIST:-}ndi:ldap:// ${j${env:DOESNOTEXIST:-}ndi:rmi:// |
7 | ${${: : : : ::: :: :: : :::-j}ndi:ldap:// ${${: : : : ::: :: :: : :::-j}ndi:rmi:// |
8 | ${${::::::::::::::-j}ndi:ldap:// ${${::::::::::::::-j}ndi:rmi:// |
We have configured the RCE payload in our tests to execute the following ping command ping -c 10 1.1.1.1
, these can be observed in the PCAPs.
PS: You can hover of the signature ids (SIDS) to see the rule name.
PCAP examples using URL encoded forms of the Log4Shell exploit strings in the URI parameters, most http clients will URL encode these strings and thus need to be normalised for detection. Suricata has support for this when using the http
keywords.
LDAP pcaps
EV | PCAP | SIDS |
---|---|---|
0 | ldap-uri-params-ev0.pcap | 21003733, 21003742, 21003750, 21003751 |
1 | ldap-uri-params-ev1.pcap | 21003733, 21003742, 21003750, 21003751 |
2 | ldap-uri-params-ev2.pcap | 21003733, 21003735, 21003738, 21003740, 21003742, 21003750, 21003751 |
3 | ldap-uri-params-ev3.pcap | 21003733, 21003735, 21003738, 21003740, 21003742, 21003750, 21003751 |
4 | ldap-uri-params-ev4.pcap | 21003733, 21003735, 21003738, 21003740, 21003742, 21003750, 21003751 |
5 | ldap-uri-params-ev5.pcap | 21003733, 21003735, 21003738, 21003740, 21003742, 21003750, 21003751 |
6 | ldap-uri-params-ev6.pcap | 21003733, 21003735, 21003738, 21003740, 21003742, 21003750, 21003751 |
7 | ldap-uri-params-ev7.pcap failed exploitation |
21003733, 21003738, 21003742, 21003750, 21003751 |
8 | ldap-uri-params-ev8.pcap failed exploitation |
21003733, 21003738, 21003742, 21003750, 21003751 |
RMI pcaps
PCAP examples using different HTTP headers as a general means to illustrate this vector of exploitation. Note that the header used does not matter, as long as it is being logged by an application using a vulnerable Log4j version.
LDAP pcaps (User-Agent)
RMI pcaps (User-Agent)
RMI pcaps (X-Api-Version)
PCAP examples using the Log4Shell exploit strings in the Basic Authorization
header. Note that this header is Base64 encoded as username:password
which poses a tricky way for network detection. We use the base64_decode
keyword in Suricata rules for this.
LDAP pcaps
RMI pcaps
PCAP examples displaying the Log4Shell exploitation, using the TLS encrypted LDAP
callback with the supported ldaps
protocol in Log4j. The client random keys can be found in the .pcapng
files to decrypt the traffic to look at the plaintext contents.
In our research we found that the LDAPS server needs to have a valid TLS certificate as the exploited Java application verifies TLS connections by default. So for an attacker to ensure that the payloads go over TLS sucessfully the attacker needs to host a server with a valid TLS certificate. Because the traffic goes over TLS it is difficult to distinguish between normal Web TLS traffic if the attacker chooses port 443 as the LDAPS
port.
EV | PCAP | SIDS |
---|---|---|
None | log4shell-ldaps-port-443-dsb.pcapng | 21003748, 21003728, 21003730, 21003732, 21003734, 21003740, 21003727 |
None | log4shell-ldaps-port-1399-dsb.pcapng | 21003748, 21003728, 21003730, 21003732, 21003734, 21003740, 21003727 |
While detection of Log4Shell in TLS traffic (to port 443) is challenging, we have thought about the following detection opportunities:
- TLS packet sizes:
- The first TLS encrypted Application data request is tiny
- LDAP bindRequest: 85 bytes encrypted, 14 bytes decrypted
- The first TLS encrypted Application data response is also tiny
- LDAP bindResponse success: 85 bytes encrypted, 14 bytes decrypted
- The first TLS encrypted Application data request is tiny
- JA3(s) hashes
We hope the infosec community has some bright ideas on improving detection here.
Our Log4Shell Suricata signatures can be found here: log4shell-suricata.rules
We have found that our signatures for outgoing LDAP
and RMI
packets are the best indicators (sids 21003738 and 21003739) of detecting a successful Log4Shell detonation. This also covers the situation where the malicious JNDI string is not always detected, for example due to TLS, but the IDS still monitors outgoing traffic.
Furthermore, the exploit chain itself might not always succeed, for example, due to Java versions or hardening of the system and or network. However, when these signatures trigger, a vulnerable Log4j version performed the callback and should be further investigated to determine which application caused it.