改造gadgetinspector篇-自动化挖掘Fastjson gadget chain
字数 1202 2025-08-25 22:58:55

Fastjson反序列化利用链自动化挖掘工具改造指南

0x01 前言

本文基于对gadgetinspector工具的改造,使其能够自动化挖掘Fastjson反序列化利用链。gadgetinspector是一款Java反序列化利用链自动挖掘工具,但原版存在一些局限性:

  1. 对于运行时确定的实现(多态性)无法进行准确的污点分析
  2. 调用链搜索不完整,同样由于多态性问题
  3. 缺少JNDI lookup的sink判断
  4. 不支持Fastjson利用链挖掘

0x02 添加新序列化方式的基础架构

gadgetinspector通过GIConfig接口支持多种反序列化方式的扩展,需要实现三个核心组件:

1. SerializableDecider(序列化决策者)

判断目标类是否可被反序列化

2. ImplementationFinder(实现查找器)

对于接口方法,判断其实现类是否可被反序列化

3. SourceDiscovery(源发现)

搜索整个gadget chain的入口点(触发方法)

以Jackson为例的实现:

public class JacksonDeserializationConfig implements GIConfig {
    @Override
    public String getName() { return "jackson"; }
    
    @Override
    public SerializableDecider getSerializableDecider(...) {
        return new JacksonSerializableDecider(methodMap);
    }
    
    @Override
    public ImplementationFinder getImplementationFinder(...) {
        return new JacksonImplementationFinder(getSerializableDecider(...));
    }
    
    @Override
    public SourceDiscovery getSourceDiscovery() {
        return new JacksonSourceDiscovery();
    }
}

0x03 Fastjson特性分析

可被反序列化的类特征

Fastjson反序列化时:

  1. 优先使用无参构造方法实例化
  2. 若无无参构造方法,则选择参数类型与自身一致的单参构造方法
  3. 若以上都不存在,会遍历构造方法取最后一个(但需要autoType支持)
  4. 通过TypeUtils.loadClass加载的类会被缓存,可绕过后续检查

结论:Fastjson理论上可以反序列化任何类,无论是否存在无参构造方法。

反序列化可触发执行的方法特征

Setter方法:

  • 方法名长度大于3
  • 非静态方法
  • 返回类型为void或自身class类型
  • 显式入参只有一个

Getter方法:

  • 对应setter不存在
  • 方法名长度大于3且第4个字符大写
  • 非静态方法
  • 无入参
  • 返回值类型是Collection/Map/AtomicBoolean/AtomicInteger/AtomicLong或其子类

0x04 Fastjson三件套实现

1. FastjsonSerializableDecider

public class FastjsonSerializableDecider implements SerializableDecider {
    @Override
    public Boolean apply(ClassReference.Handle handle) {
        return Boolean.TRUE; // Fastjson几乎可以反序列化任何类
    }
}

2. FastjsonSourceDiscovery

public class FastjsonSourceDiscovery extends SourceDiscovery {
    @Override
    public void discover(...) {
        for (MethodReference.Handle method : methodMap.keySet()) {
            // Getter方法判断
            if (method.getName().startsWith("get") 
                && method.getDesc().startsWith("()")) {
                // 检查返回值类型等条件
                addDiscoveredSource(new Source(method, 0));
            }
            // Setter方法判断
            if (method.getName().startsWith("set") 
                && method.getDesc().matches("\\(L[V")) {
                addDiscoveredSource(new Source(method, 1));
            }
        }
    }
}

3. FastjsonImplementationFinder

public class FastjsonImplementationFinder implements ImplementationFinder {
    @Override
    public Set<MethodReference.Handle> getImplementations(MethodReference.Handle target) {
        Set<MethodReference.Handle> allImpls = new HashSet<>();
        allImpls.add(target); // 直接添加目标方法
        return allImpls;
    }
}

4. 配置集成

public class FastjsonDeserializationConfig implements GIConfig {
    @Override public String getName() { return "fastjson"; }
    @Override public SerializableDecider getSerializableDecider(...) {
        return new FastjsonSerializableDecider(methodMap);
    }
    @Override public ImplementationFinder getImplementationFinder(...) {
        return new FastjsonImplementationFinder(getSerializableDecider(...));
    }
    @Override public SourceDiscovery getSourceDiscovery() {
        return new FastjsonSourceDiscovery();
    }
}

0x05 优化Sink判断 - 加入JNDI lookup

GadgetChainDiscovery.isSink方法中添加:

if (inheritanceMap.isSubclassOf(method.getClassReference(), 
    new ClassReference.Handle("javax/naming/Context")) 
    && method.getName().equals("lookup")) {
    return true;
}

0x06 测试效果

以HikariCP-3.4.1.jar测试,成功挖掘到以下利用链:

com/zaxxer/hikari/HikariConfig.setMetricRegistry(Ljava/lang/Object;)V (1)
com/zaxxer/hikari/HikariConfig.getObjectOrPerformJndiLookup(Ljava/lang/Object;)Ljava/lang/Object; (1)
javax/naming/InitialContext.lookup(Ljava/lang/String;)Ljava/lang/Object; (1)

总结

通过改造gadgetinspector,我们实现了:

  1. Fastjson反序列化链的自动化挖掘
  2. JNDI lookup sink的识别
  3. 完整的Fastjson特性支持

这种改造方法同样适用于其他反序列化框架的扩展,只需根据目标框架的特性调整三件套的实现逻辑即可。

Fastjson反序列化利用链自动化挖掘工具改造指南 0x01 前言 本文基于对gadgetinspector工具的改造,使其能够自动化挖掘Fastjson反序列化利用链。gadgetinspector是一款Java反序列化利用链自动挖掘工具,但原版存在一些局限性: 对于运行时确定的实现(多态性)无法进行准确的污点分析 调用链搜索不完整,同样由于多态性问题 缺少JNDI lookup的sink判断 不支持Fastjson利用链挖掘 0x02 添加新序列化方式的基础架构 gadgetinspector通过 GIConfig 接口支持多种反序列化方式的扩展,需要实现三个核心组件: 1. SerializableDecider(序列化决策者) 判断目标类是否可被反序列化 2. ImplementationFinder(实现查找器) 对于接口方法,判断其实现类是否可被反序列化 3. SourceDiscovery(源发现) 搜索整个gadget chain的入口点(触发方法) 以Jackson为例的实现: 0x03 Fastjson特性分析 可被反序列化的类特征 Fastjson反序列化时: 优先使用无参构造方法实例化 若无无参构造方法,则选择参数类型与自身一致的单参构造方法 若以上都不存在,会遍历构造方法取最后一个(但需要autoType支持) 通过 TypeUtils.loadClass 加载的类会被缓存,可绕过后续检查 结论 :Fastjson理论上可以反序列化任何类,无论是否存在无参构造方法。 反序列化可触发执行的方法特征 Setter方法: 方法名长度大于3 非静态方法 返回类型为void或自身class类型 显式入参只有一个 Getter方法: 对应setter不存在 方法名长度大于3且第4个字符大写 非静态方法 无入参 返回值类型是Collection/Map/AtomicBoolean/AtomicInteger/AtomicLong或其子类 0x04 Fastjson三件套实现 1. FastjsonSerializableDecider 2. FastjsonSourceDiscovery 3. FastjsonImplementationFinder 4. 配置集成 0x05 优化Sink判断 - 加入JNDI lookup 在 GadgetChainDiscovery.isSink 方法中添加: 0x06 测试效果 以HikariCP-3.4.1.jar测试,成功挖掘到以下利用链: 总结 通过改造gadgetinspector,我们实现了: Fastjson反序列化链的自动化挖掘 JNDI lookup sink的识别 完整的Fastjson特性支持 这种改造方法同样适用于其他反序列化框架的扩展,只需根据目标框架的特性调整三件套的实现逻辑即可。