Skip to content

Latest commit

 

History

History
62 lines (51 loc) · 5.18 KB

File metadata and controls

62 lines (51 loc) · 5.18 KB

XString 调用toString链(XString1)

  • 类别:javanative 别名:— 优先级:—
  • 作者:—
  • 依赖spring-aop:org.springframework.aop.target.HotSwappableTargetSourcejdk:com.sun.org.apache.xpath.internal.objects.XString

作用

构造一个「两键哈希碰撞」的 HashMap,键为两个 HotSwappableTargetSource,使其在 HashMap.readObject 期间触发 HotSwappableTargetSource.equals → JDK 内置 com.sun.org.apache.xpath.internal.objects.XString.equals对内层对象调用任意 toString()。是把「原生/Hessian 反序列化入口」转接到「toString 型 sink」的经典跳板,属 CommonsCollections6/K 系列常用的 HashMap 碰撞变体。

链接标签

  • 入口 tagsJavaNativeDeserializeHessianDeserialize
    • JavaNativeDeserialize —— 承接 Java 原生反序列化入口(HashMap.readObject 天然可被 JDK 反序列化触发)。
    • HessianDeserialize —— 同样适用于 Hessian 反序列化场景(Hessian 会调用 HashMap 的反序列化并可触发键的 hashCode/equals)。
  • 衔接 nextTagsToString —— 之后需接一个「入口为 toString()」的 gadget(如 JacksonToStringFastjsonToString1XBeanToString 等)。
  • excludes:(无)

源码剖析

public Object getObject(Object object) throws Exception {
    XString xString = new XString("");                               // 空字符串的 XString
    HotSwappableTargetSource h1 = new HotSwappableTargetSource(object);   // 包装内层目标对象
    HotSwappableTargetSource h2 = new HotSwappableTargetSource((Object)xString); // 包装 XString
    HashMap map = PayloadHelper.makeMap(h1, h2);                     // 构造哈希碰撞 Map
    return map;
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    Object object = chain.doCreate(context);                        // 取内层对象(下游 ToString gadget 的产物)
    Object getterObject = context.get(ContextTag.FASTJSON_HANDLE_BYPASS_KEY);
    Object resultObject = this.getObject(object);
    if (getterObject != null) {
        return CommonMethod.listWrap(getterObject, resultObject);   // Fastjson handle 绕过场景:套一层 List
    }
    return resultObject;
}

触发原理(逐跳)

  1. PayloadHelper.makeMap(h1, h2) 生成一个两键的 HashMap,并令 h1h2 落入同一个桶(哈希碰撞)。反序列化时 HashMap.readObjectputVal 在同桶内做键比对,触发 h1.equals(h2)(或反向)。
  2. HotSwappableTargetSource.equals(other) 的实现为「两者都是 HotSwappableTargetSource 时,比较各自 target」,于是转为 xString.equals(object)(即 h2.target.equals(h1.target))。
  3. com.sun.org.apache.xpath.internal.objects.XString.equals(Object obj2) 内部会执行 this.str().equals(obj2.toString()),即对传入的 object 调用 toString()
  4. object 正是 chain.doCreate 得到的下游 gadget(nextTags=ToString),其 toString() 被触发后继续展开利用链。

关键点new XString("") 用空串占位,保证 equals 走到 obj2.toString() 分支而非提前返回;真正的攻击载体是 object(下游对象)。invoke 中对 FASTJSON_HANDLE_BYPASS_KEY 的判断用于 Fastjson autoType/handle 绕过场景——当上下文注入了 getterObject 时,用 CommonMethod.listWrap 把结果再包一层 List,以适配 Fastjson 的解析路径;常规原生/Hessian 场景该值为空,直接返回 HashMap

参数(@Param)

本类无 @Param,无用户可配字段;内层对象与上下文(是否 Fastjson 绕过)均由链自动注入。

适用版本与原理要点

  • 使用 JDK 内置 com.sun.org.apache.xpath.internal.objects.XStringrt.jar 自带),因此无需第三方 XML 依赖,仅需目标存在 spring-aopHotSwappableTargetSource
  • JDK 高版本(模块化后)若移除/封装了 com.sun.org.apache.xpath.internal.*,则本变体不可用,需改用 XalanXString1(依赖 xalan:2.6.0 的独立包)。
  • HotSwappableTargetSource 来自 spring-aop,属极常见依赖,落地面广。
  • 依赖 HashMap 碰撞技巧,属纯逻辑跳板,不触及字节码,适配 Java 原生与 Hessian 两类反序列化入口。

所属预设链

自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。是「反序列化入口 → toString sink」的可插拔中间件。

关联