深入fastjson源码命令执行调试
字数 1284 2025-08-10 19:49:08

Fastjson反序列化漏洞深入分析与调试指南

1. 漏洞背景与概述

Fastjson是阿里巴巴开源的一个高性能JSON处理库,广泛用于Java应用程序中。然而,Fastjson在反序列化过程中存在安全漏洞,攻击者可以通过精心构造的JSON数据实现远程代码执行(RCE)。

本教学文档将详细分析Fastjson反序列化漏洞的原理、利用方式以及调试过程,帮助安全研究人员深入理解该漏洞。

2. 漏洞环境搭建

2.1 创建漏洞演示类

import java.util.Properties;

public class Person {
    private String name;
    private int age;
    private String sex;
    private Properties properties;
    
    public Person() {
        System.out.println("构造方法");
    }
    
    // Getter和Setter方法
    public String getName() {
        System.out.println("getName");
        return name;
    }
    
    public void setName(String name) {
        System.out.println("setName");
        this.name = name;
    }
    
    public int getAge() {
        System.out.println("getAge");
        return age;
    }
    
    public String getSex(){
        System.out.println("getAddress");
        return sex;
    }
    
    public Properties getProperties() throws Exception {
        System.out.println("getProperties");
        Runtime.getRuntime().exec("open -a /System/Applications/Calculator.app");
        return properties;
    }
}

2.2 反序列化测试代码

import com.alibaba.fastjson.JSON;

public class Demo {
    public static void main(String[] args){
        String jsonstring = "{\"@type\":\"com.FastjsonDemo.Person\",\"age\":18,\"name\":\"lili\",\"address\":\"china\",\"properties\":{}}";
        Object obj = JSON.parseObject(jsonstring, Object.class);
        System.out.println(obj);
    }
}

3. 漏洞利用原理

3.1 关键点分析

  1. @type属性:Fastjson通过该属性指定要反序列化的目标类
  2. Getter方法触发:反序列化过程中会自动调用目标类的Getter方法
  3. 危险方法调用:在Getter方法中执行危险操作(如Runtime.exec()

3.2 漏洞触发流程

  1. Fastjson解析JSON字符串时,发现@type属性
  2. 根据@type指定的类名加载并实例化目标类
  3. 为JSON中的每个属性调用对应的Setter或Getter方法
  4. 当调用到getProperties()方法时,执行其中的命令

4. 详细调试分析

4.1 调试入口

JSON.parseObject()方法处设置断点,开始调试:

Object obj = JSON.parseObject(jsonstring, Object.class);

4.2 调用栈分析

  1. 初始parseObject调用

    public static <T> T parseObject(String text, Class<T> clazz) {
        return parseObject(text, clazz);
    }
    
  2. 重载方法调用

    public static <T> T parseObject(String json, Class<T> clazz, Feature... features) {
        return parseObject(json, clazz, ParserConfig.global, (ParseProcess)null, DEFAULT_PARSER_FEATURE, features);
    }
    
  3. 核心解析方法

    public static <T> T parseObject(String input, Type clazz, ParserConfig config, ParseProcess processor, int featureValues, Feature... features) {
        // 创建解析器
        DefaultJSONParser parser = new DefaultJSONParser(input, config, featureValues);
        // 解析对象
        T value = parser.parseObject(clazz, (Object)null);
        // 处理解析结果
        parser.handleResovleTask(value);
        parser.close();
        return value;
    }
    

4.3 关键解析过程

  1. DefaultJSONParser初始化

    • 创建DefaultJSONParser对象
    • 初始化JSONLexer用于词法分析
  2. parseObject方法

    public <T> T parseObject(Type type, Object fieldName) {
        int token = this.lexer.token();
        // 获取反序列化器
        ObjectDeserializer derializer = this.config.getDeserializer(type);
        // 执行反序列化
        return derializer.deserialze(this, type, fieldName);
    }
    
  3. 反序列化器获取

    • 通过ParserConfig.getDeserializer()获取对应类型的反序列化器
    • 对于自定义类,会使用JavaBeanDeserializer
  4. 字段解析

    boolean match = this.parseField(parser, key, object, type, fieldValues);
    
    • 通过smartMatch方法匹配字段和反序列化器
    • 调用字段对应的Getter/Setter方法

4.4 漏洞触发点

Person.getProperties()方法中:

public Properties getProperties() throws Exception {
    System.out.println("getProperties");
    Runtime.getRuntime().exec("open -a /System/Applications/Calculator.app");
    return properties;
}

当Fastjson解析到properties字段时:

  1. 检查并调用getProperties()方法
  2. 方法中的Runtime.exec()被执行
  3. 弹出计算器,实现命令执行

5. 漏洞防御措施

  1. 升级Fastjson版本:使用已修复漏洞的最新版本
  2. 关闭autotype功能
    ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
    
  3. 使用安全模式
    ParserConfig.getGlobalInstance().addAccept("com.yourpackage.")
    
  4. 输入验证:对JSON输入进行严格验证
  5. 使用白名单:限制可反序列化的类

6. 调试技巧与总结

  1. 调试关键点

    • @type属性的处理
    • 反序列化器的获取过程
    • 字段解析和Getter方法调用
  2. 调试工具

    • IDE调试器(IntelliJ IDEA/Eclipse)
    • 条件断点
    • 调用栈分析
  3. 学习建议

    • 多次重复调试过程,理解每个步骤
    • 关注Fastjson的核心解析逻辑
    • 分析不同版本间的差异

通过本教学文档,读者可以深入理解Fastjson反序列化漏洞的原理和利用方式,掌握相关的调试技巧,并学习如何防御此类漏洞。

Fastjson反序列化漏洞深入分析与调试指南 1. 漏洞背景与概述 Fastjson是阿里巴巴开源的一个高性能JSON处理库,广泛用于Java应用程序中。然而,Fastjson在反序列化过程中存在安全漏洞,攻击者可以通过精心构造的JSON数据实现远程代码执行(RCE)。 本教学文档将详细分析Fastjson反序列化漏洞的原理、利用方式以及调试过程,帮助安全研究人员深入理解该漏洞。 2. 漏洞环境搭建 2.1 创建漏洞演示类 2.2 反序列化测试代码 3. 漏洞利用原理 3.1 关键点分析 @type属性 :Fastjson通过该属性指定要反序列化的目标类 Getter方法触发 :反序列化过程中会自动调用目标类的Getter方法 危险方法调用 :在Getter方法中执行危险操作(如 Runtime.exec() ) 3.2 漏洞触发流程 Fastjson解析JSON字符串时,发现 @type 属性 根据 @type 指定的类名加载并实例化目标类 为JSON中的每个属性调用对应的Setter或Getter方法 当调用到 getProperties() 方法时,执行其中的命令 4. 详细调试分析 4.1 调试入口 在 JSON.parseObject() 方法处设置断点,开始调试: 4.2 调用栈分析 初始parseObject调用 : 重载方法调用 : 核心解析方法 : 4.3 关键解析过程 DefaultJSONParser初始化 : 创建 DefaultJSONParser 对象 初始化 JSONLexer 用于词法分析 parseObject方法 : 反序列化器获取 : 通过 ParserConfig.getDeserializer() 获取对应类型的反序列化器 对于自定义类,会使用 JavaBeanDeserializer 字段解析 : 通过 smartMatch 方法匹配字段和反序列化器 调用字段对应的Getter/Setter方法 4.4 漏洞触发点 在 Person.getProperties() 方法中: 当Fastjson解析到 properties 字段时: 检查并调用 getProperties() 方法 方法中的 Runtime.exec() 被执行 弹出计算器,实现命令执行 5. 漏洞防御措施 升级Fastjson版本 :使用已修复漏洞的最新版本 关闭autotype功能 : 使用安全模式 : 输入验证 :对JSON输入进行严格验证 使用白名单 :限制可反序列化的类 6. 调试技巧与总结 调试关键点 : @type 属性的处理 反序列化器的获取过程 字段解析和Getter方法调用 调试工具 : IDE调试器(IntelliJ IDEA/Eclipse) 条件断点 调用栈分析 学习建议 : 多次重复调试过程,理解每个步骤 关注Fastjson的核心解析逻辑 分析不同版本间的差异 通过本教学文档,读者可以深入理解Fastjson反序列化漏洞的原理和利用方式,掌握相关的调试技巧,并学习如何防御此类漏洞。