Fastjson68版本绕过autotype原理及利用场景分析
字数 1322 2025-08-15 21:31:09
Fastjson 1.2.68版本autotype绕过原理及利用分析
漏洞背景
Fastjson在1.2.68版本中存在autotype绕过漏洞,攻击者可以在autotype关闭的情况下通过特定构造的JSON数据实现任意类实例化。该漏洞于2020年5月被发现,并在1.2.69版本中修复。
漏洞原理
核心绕过机制
漏洞的核心在于ParserConfig.checkAutoType()方法中对expectClass参数的处理:
- 当
expectClass不为某些特定类时,可以将expectClassFlag设置为true - 当
expectClassFlag为true时,即使autotype为false也能生成期望类的实例
关键代码分析
checkAutoType方法签名:
public Class<?> checkAutoType(String typeName, Class<?> expectClass, int features)
漏洞利用需要满足以下条件:
- 能够找到一个不受autotype限制的类作为初始
expectClass - 后续通过嵌套
@type指定一个实现expectClass接口/继承expectClass类的恶意类
可用的初始expectClass来源
在autotype关闭的情况下,可以通过以下方式获取初始类:
- cache mapping:Fastjson启动时预加载的基础类
- 白名单:配置的白名单类
- 默认deserializers:
PaserConfig.initDeserializers()中初始化的基础类型
漏洞利用条件
要成功利用该漏洞,需要满足:
- 第一个
@type指定的类必须是不受autotype限制的类(来自上述三种来源之一) - 第二个
@type指定的类必须:- 实现第一个类的接口或继承第一个类
- 不在Fastjson黑名单中
- 具有可利用的setter方法或构造函数
漏洞利用示例
利用AutoCloseable接口
- 创建一个实现
AutoCloseable接口的类:
package defaultpack;
public class Person implements AutoCloseable {
private String name;
private int age;
// 构造方法和setter/getter
public void setAge(int age) {
this.age = age;
System.out.println("setAge invoked!");
}
@Override
public void close() throws Exception {}
}
- 构造恶意JSON:
{
"@type": "java.lang.AutoCloseable",
"@type": "defaultpack.Person",
"age": "13"
}
- 解析JSON时会调用
Person.setAge()方法:
JSON.parseObject(payload);
利用Throwable类
另一种利用方式是通过Throwable类及其子类,原理类似:
{
"@type": "java.lang.Exception",
"@type": "恶意类名",
...
}
利用限制
该漏洞利用受到以下限制:
- 黑名单限制:所有类仍需通过Fastjson的黑名单检查
- 父类/接口限制:恶意类必须实现特定的父类/接口(如68版本中的
AutoCloseable或Throwable) - 初始类获取限制:需要找到不受autotype限制的初始类
修复方案
Fastjson在1.2.69版本中修复了该漏洞,主要措施包括:
- 增加了对
AutoCloseable等接口的黑名单检查 - 改进了
expectClass的处理逻辑 - 加强了黑名单机制
防御建议
- 升级到Fastjson 1.2.69或更高版本
- 不要使用
@type特性时可完全关闭autotype - 严格限制Fastjson解析的JSON数据来源
- 实施严格的类白名单机制
总结
Fastjson 1.2.68的autotype绕过漏洞虽然利用条件较为苛刻,但在特定环境下仍可能造成RCE风险。理解该漏洞的原理有助于更好地防御类似的安全问题,同时也展示了反序列化漏洞的复杂性和多样性。