- 类别:common 别名:— 优先级:—(
@Deprecated) - 作者:—
- 依赖:
spring-aop(org.springframework.aop.target.HotSwappableTargetSource)
利用 HashMap.readObject 反序列化时对哈希碰撞键触发 key.equals() 的特性,把两个攻击者可控对象包进 HotSwappableTargetSource,在反序列化瞬间强制发起一次 obj1.equals(obj2) 调用。是一个「把 Java 原生/Hessian 反序列化入口转换为任意 equals 调用」的跳板构件,为下游 Equals 型 gadget(如 XString、AbstractTableModel 等借 equals 触发 toString/getter 的载体)提供入口。
- 入口
tags:JavaNativeDeserialize、HessianDeserialize—— 承接 Java 原生反序列化与 Hessian 反序列化两类入口。 - 衔接
nextTags:Equals—— 之后需接一个「利用equals触发危险行为」的 gadget,由它向本 gadget 提供参与比较的两个对象。 excludes:无。
@GadgetTags(tags={"JavaNativeDeserialize", "HessianDeserialize"}, nextTags={"Equals"})
@Deprecated
public class HotSTSourceEquals implements Gadget {
public Object getObject(Object obj1, Object obj2) throws Exception {
HotSwappableTargetSource h1 = new HotSwappableTargetSource(obj2);
HotSwappableTargetSource h2 = new HotSwappableTargetSource(obj1);
return PayloadHelper.makeMap(h1, h2);
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
Object[] objects = (Object[]) chain.doCreate(context);
Object getterObject = context.get(ContextTag.FASTJSON_HANDLE_BYPASS_KEY);
Object resultObject = this.getObject(objects[0], objects[1]);
if (getterObject != null) {
return CommonMethod.listWrap(getterObject, resultObject);
}
return resultObject;
}
}invoke先chain.doCreate(context),约定内层 gadget 返回一个长度为 2 的Object[](objects[0]、objects[1]),即下游Equalsgadget 需要参与equals比较的一对对象。getObject把这两个对象分别包进两个HotSwappableTargetSource:h1持有obj2,h2持有obj1。HotSwappableTargetSource.equals的语义是「对方也是HotSwappableTargetSource时,比较各自持有的target」,即h1.equals(h2)最终展开为obj2.equals(obj1)(对应 description 中「obj1、obj2 对象指定方法:obj1.equals(obj2)」的效果)。PayloadHelper.makeMap(h1, h2)构造一个HashMap,把h1、h2放成哈希碰撞的两个键。HashMap.readObject重建时会对落入同一桶的键调用equals,从而在反序列化过程中自动触发上述equals调用——这正是经典的HashMapequals 触发原语。- 末尾的
FASTJSON_HANDLE_BYPASS_KEY分支:当上下文中存在 Fastjson 绕过对象时,用CommonMethod.listWrap把结果与绕过对象一起包成List,用于 Fastjson 场景下的额外封装;普通场景直接返回HashMap。
本类无 @Param,无用户可配字段。参与比较的两个对象完全由下游 Equals gadget 通过 chain.doCreate 提供。
- 依赖 spring-aop 提供
HotSwappableTargetSource(其equals会比较内部target),故目标须存在 spring-aop。 - 触发链:
HashMap#readObject→ 桶内键碰撞 →HotSwappableTargetSource#equals→obj2.equals(obj1)。 - 本类被标注
@Deprecated:官方更倾向使用其它 equals 入口(如直接HashMapEquals/HashTableEquals等),此构件保留兼容。使用时须确保内层 gadget 返回Object[]{obj1, obj2}结构,否则invoke中的强制类型转换会失败。
自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。可与需要 equals 触发的下游 gadget 自由组合。
- 上游入口:Java 原生 / Hessian 反序列化 Payload。
- 下游(
nextTags=Equals):需要obj1.equals(obj2)触发危险行为的 gadget(XString 系、借equals派生toString/getter的载体)。 - 同族(equals 触发原语):HashMapEquals、HashTableEquals、ConcurrentHashMapEquals。