Fastjson反序列化RCE核心-四个关键点分析
字数 2257 2025-08-25 22:58:56
Fastjson反序列化RCE核心分析
0x01 前言
Fastjson是阿里巴巴开源的一个Java JSON解析/生成库,具有以下特点:
- 高性能的JSON处理能力
- 提供简单的toJSONString()和parseObject()方法
- 支持任意Java对象转换
- 广泛支持Java泛型
- 支持复杂对象结构
由于Fastjson在国内广泛使用,一旦出现安全漏洞影响范围极大。本文将从四个关键点深入分析Fastjson反序列化RCE漏洞的核心原理。
0x02 四个关键点分析
1. 词法解析
Fastjson的词法解析是反序列化过程中的重要环节,主要涉及以下内容:
解析流程
- 通过
JSON.parse(text)开始解析,使用默认配置DEFAULT_PARSER_FEATURE - 创建
DefaultJSONParser实例,内部使用JSONScanner进行词法解析 JSONScanner继承自JSONLexerBase,为性能优化做了特别处理
关键变量
text: JSON文本数据len: 文本长度token: 当前解析到的数据类型ch: 当前读取到的字符bp: 当前字符索引sbuf: 正在解析的段数据(char数组)sp: sbuf最后一个数据的索引
特殊字符处理
Fastjson对JSON字符串中的转义字符有特殊处理:
\0 \1 \2 \3 \4 \5 \6 \7 \b \t \n \r等双字节字符会被转换为单字符\f \F双字符都会转成单字符\f\v双字符转成\u000B单字符\x..四字符16进制数读取转成单字符\u....六字符16进制数读取转成单字符
绕过技巧
利用\x和\u的词法处理可以绕过某些过滤:
@\u0074ype -> @type
@\x74ype -> @type
2. 构造方法选择
Fastjson在反序列化时需要选择合适的构造方法实例化对象:
构造方法选择逻辑
- 首先尝试获取
defaultConstructor:- 无参构造方法
- 或单参数且参数类型为自身类的构造方法
- 如果没有
defaultConstructor,则遍历查找creatorConstructor:- 必须是public方法
- 使用ASM获取参数名不为空
- 选择最后一个符合条件的构造方法
特殊类处理
以下类会直接作为creatorConstructor:
org.springframework.security.web.authentication.WebAuthenticationDetailsorg.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationTokenorg.springframework.security.core.authority.SimpleGrantedAuthority
3. 缓存绕过
Fastjson的checkAutoType检查机制可以通过缓存绕过:
检查流程
- 对
typeName进行基本检查(长度等) - 检查期望类
expectClass - 进行黑白名单检查
- 尝试从缓存中获取类:
TypeUtils.getClassFromMappingdeserializers.findClasstypeMapping.get
关键绕过点
- 当
autoTypeSupport为true时,会缓存加载的类到mappings:if (clazz == null && (autoTypeSupport || jsonType || expectClassFlag)) { boolean cacheClass = autoTypeSupport || jsonType; clazz = TypeUtils.loadClass(typeName, defaultClassLoader, cacheClass); } - 通过两次反序列化:
- 第一次:虽然会抛出异常,但已将类缓存到
mappings - 第二次:直接从缓存获取,绕过后续检查
- 第一次:虽然会抛出异常,但已将类缓存到
绕过限制
即使绕过缓存,仍需满足:
- 不能是
ClassLoader、DataSource、RowSet等危险类 - 如果
creatorConstructor不为空且autoTypeSupport为true,仍会抛出异常
4. 反射调用
反序列化的最后阶段通过反射调用完成攻击链:
FieldInfo构建
- 三种情况下会创建
FieldInfo:- 基于
JSONCreator注解的构造方法 - 工厂方法
- 普通构造方法
- 基于
FieldInfo有多种构造方法,其中包含Method参数的构造方法可能导致方法调用
方法收集逻辑
- 第一遍收集setter方法:
- 跳过静态方法
- 跳过返回值类型不符合的方法
- 处理
JSONField注解 - 处理常规setter方法(方法名长度>4,以"set"开头)
- 第二遍收集getter方法:
- 跳过静态方法
- 方法名长度>4且以"get"开头
- 无参数
- 返回值类型为特定集合类
反序列化执行
- 如果token为
},直接反射实例化返回 - 如果token为
[,进行数组处理 - 调用构造方法实例化对象
- 通过
FieldDeserializer处理字段:- 对于
method不为空的fieldInfo:- 如果
getOnly为false,直接反射执行method - 如果
getOnly为true,检查返回类型后反射执行
- 如果
- 对于
method为空的fieldInfo,直接设置字段值
- 对于
0x03 总结
Fastjson反序列化RCE漏洞的核心在于:
- 利用词法解析特性绕过过滤
- 选择合适的构造方法实例化对象
- 通过缓存机制绕过安全检查
- 通过反射调用触发攻击链
理解这四个关键点可以帮助我们更好地分析Fastjson漏洞,也能帮助开发人员编写更安全的代码。