从原生反序列化到Hessian反序列化的hook方法
字数 1093 2025-08-29 22:41:01

Hessian反序列化Hook方法详解

1. Java原生反序列化Hook方法

在CTF比赛中,hook Java原生反序列化是最常见的需求,通常通过重写ObjectInputStreamresolveClass方法实现。

1.1 基本Hook方法

ObjectInputStream ois = new ObjectInputStream(inputStream) {
    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        String className = desc.getName();
        // 在这里添加黑名单检查逻辑
        if (BLACKLISTED_CLASSES.contains(className)) {
            throw new InvalidClassException("Unauthorized deserialization attempt", className);
        }
        return super.resolveClass(desc);
    }
};

1.2 实战建议

  1. 使用匿名内部类方式实现,便于快速修复
  2. 黑名单应尽可能全面,至少包含Java-chains中的每条链的一个节点
  3. 这种方法适用于awdp等线下赛事,修复速度快

2. Hessian反序列化Hook方法

Hessian反序列化的hook方法较少被讨论,但同样重要。

2.1 Hessian反序列化特点

  1. 不同于原生Java序列化
  2. 传统基于base64解码检测的方法存在缺陷
  3. 特别是面对"UTF-8 Overlong Encoding"攻击时不够安全

2.2 Hessian反序列化流程分析

通过调试Hessian2InputreadObject方法,发现关键点在findSerializerFactory方法,该方法返回一个SerializerFactory对象。

2.3 SerializerFactory核心方法

SerializerFactory类中有两个关键方法:

public Deserializer getDeserializer(String type)
public Deserializer getDeserializer(Class cl)

这两个方法在反序列化过程中会被调用,参数typecl就是当前反序列化的类名/类对象。

2.4 Hook实现方法

方法一:直接修改SerializerFactory

SerializerFactory factory = new SerializerFactory() {
    @Override
    public Deserializer getDeserializer(String type) {
        if (BLACKLISTED_CLASSES.contains(type)) {
            throw new RuntimeException("Blocked deserialization of " + type);
        }
        return super.getDeserializer(type);
    }
};

方法二:通过Hessian2Input设置

更推荐的方法是通过Hessian2InputsetSerializerFactory方法:

Hessian2Input input = new Hessian2Input(is);
input.setSerializerFactory(new SerializerFactory() {
    @Override
    public Deserializer getDeserializer(String type) {
        if (BLACKLISTED_CLASSES.contains(type)) {
            throw new RuntimeException("Blocked deserialization of " + type);
        }
        return super.getDeserializer(type);
    }
});

2.5 黑名单构建建议

根据Java-chains构建的防御性黑名单应包含:

  1. 常见反序列化利用链的关键节点类
  2. 避免误伤正常集合类
  3. 能够防御绝大多数已知利用链

3. 实战应用与注意事项

  1. 修复速度:在awdp等比赛中,快速修复至关重要
  2. 最小化改动:使用匿名内部类方式,便于快速部署
  3. 防御全面性:黑名单应尽可能覆盖所有已知利用链
  4. 调试技巧:通过断点调试确定关键hook点

4. 总结

Hessian反序列化的hook方法与原生Java序列化不同,主要通过拦截SerializerFactorygetDeserializer方法实现。这种方法:

  1. 能够有效防御各种Hessian反序列化攻击
  2. 包括UTF-8 Overlong Encoding等绕过方式
  3. 实现简单,适合CTF比赛快速修复
  4. 可以通过黑名单机制实现通防

在实际应用中,建议结合具体场景调整黑名单内容,并定期更新以应对新的攻击方式。

Hessian反序列化Hook方法详解 1. Java原生反序列化Hook方法 在CTF比赛中,hook Java原生反序列化是最常见的需求,通常通过重写 ObjectInputStream 的 resolveClass 方法实现。 1.1 基本Hook方法 1.2 实战建议 使用匿名内部类方式实现,便于快速修复 黑名单应尽可能全面,至少包含Java-chains中的每条链的一个节点 这种方法适用于awdp等线下赛事,修复速度快 2. Hessian反序列化Hook方法 Hessian反序列化的hook方法较少被讨论,但同样重要。 2.1 Hessian反序列化特点 不同于原生Java序列化 传统基于base64解码检测的方法存在缺陷 特别是面对"UTF-8 Overlong Encoding"攻击时不够安全 2.2 Hessian反序列化流程分析 通过调试 Hessian2Input 的 readObject 方法,发现关键点在 findSerializerFactory 方法,该方法返回一个 SerializerFactory 对象。 2.3 SerializerFactory核心方法 SerializerFactory 类中有两个关键方法: 这两个方法在反序列化过程中会被调用,参数 type 或 cl 就是当前反序列化的类名/类对象。 2.4 Hook实现方法 方法一:直接修改SerializerFactory 方法二:通过Hessian2Input设置 更推荐的方法是通过 Hessian2Input 的 setSerializerFactory 方法: 2.5 黑名单构建建议 根据Java-chains构建的防御性黑名单应包含: 常见反序列化利用链的关键节点类 避免误伤正常集合类 能够防御绝大多数已知利用链 3. 实战应用与注意事项 修复速度 :在awdp等比赛中,快速修复至关重要 最小化改动 :使用匿名内部类方式,便于快速部署 防御全面性 :黑名单应尽可能覆盖所有已知利用链 调试技巧 :通过断点调试确定关键hook点 4. 总结 Hessian反序列化的hook方法与原生Java序列化不同,主要通过拦截 SerializerFactory 的 getDeserializer 方法实现。这种方法: 能够有效防御各种Hessian反序列化攻击 包括UTF-8 Overlong Encoding等绕过方式 实现简单,适合CTF比赛快速修复 可以通过黑名单机制实现通防 在实际应用中,建议结合具体场景调整黑名单内容,并定期更新以应对新的攻击方式。