Skip to content

Latest commit

 

History

History
60 lines (50 loc) · 4.92 KB

File metadata and controls

60 lines (50 loc) · 4.92 KB

CC3.2.1 ChainedTransformer 链(CommonsCollectionsK3)

  • 类别:javanative 别名:K3 优先级:10
  • 作者:—
  • 依赖commons-collections:commons-collections:3.2.1

作用

基于 commons-collections 3.2.1 的 LazyMap + TiedMapEntry 触发点,但把触发器换成一个空的 ChainedTransformer,并把整串 Transformer[] 直接注入其 iTransformers 字段。它不自带 InvokerTransformer,而是让下游 gadget 提供任意 Transformer 数组来完成实际转换,适用于目标环境对某些类(如 InvokerTransformer)做了黑名单、但仍能加载 ChainedTransformer 的情况。

链接标签

  • 入口 tagsJavaNativeDeserialize —— 承接 Java 原生反序列化入口。
  • 衔接 nextTagsTransformerChains —— 下游必须产出一个 Transformer[] 数组(而非单个对象),由本 gadget 注入到 ChainedTransformer.iTransformers。典型下游是 TransformerWithTemplatesImpl
  • excludes:无。

源码剖析

public HashSet getObject(Object obj) throws Exception {
 ChainedTransformer transformerChain = new ChainedTransformer(new Transformer[0]);
 HashMap innerMap = new HashMap();
 Map lazyMap = LazyMap.decorate(innerMap, (Transformer)transformerChain);
 TiedMapEntry entry = new TiedMapEntry(lazyMap, (Object)"foo");
 HashSet set = PayloadHelper.makeHashSetWithEntry(entry);
 Reflections.setFieldValue(transformerChain, "iTransformers", obj);
 return set;
}

逐段解释:

  1. new ChainedTransformer(new Transformer[0]) —— 先建的链式转换器(内部 iTransformers 为空数组),避免本地构造时执行转换。
  2. LazyMap.decorate(innerMap, transformerChain) + new TiedMapEntry(lazyMap, "foo") —— 与 K1 相同的触发外壳:TiedMapEntry.getValue() 会触发 lazyMap.get("foo")transformerChain.transform("foo")。注意这里 TiedMapEntry 的 key 是无害的 "foo" 常量,真正的攻击载荷是 iTransformers 数组
  3. PayloadHelper.makeHashSetWithEntry(entry)(核心工具类,未含在本文档)—— 同 K1,把 entry 塞进 HashSet 的底层 HashMap,使 readObject 时经 hash → TiedMapEntry.hashCode → getValue 触发转换。
  4. Reflections.setFieldValue(transformerChain, "iTransformers", obj) —— 关键点:把下游产出的对象 obj(一个 Transformer[])反射写入 ChainedTransformer.iTransformers。反序列化触发时,ChainedTransformer.transform 会依次执行数组里的每个 Transformer,前一个的输出作为后一个的输入。
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
 context.put(ContextTag.CC_VERSION, ContextTag.CC_VERSION_3);
 return this.getObject(chain.doCreate(context));
}
  • 声明 CC_VERSION_3,直接把内层对象(应为 Transformer[])交给 getObject。本类不读取 SPECIAL_METHOD_NAME_KEY——它不通过方法名触发,而是委托下游 Transformer 数组完成逻辑。

触发链(反序列化时): HashSet.readObjectHashMap.puthash(key)TiedMapEntry.hashCode()getValue()LazyMap.get("foo")ChainedTransformer.transform("foo") → 依次调用注入的 iTransformers[i].transform(...)(链式)。

参数(@Param)

本类无 @Param。攻击载荷(Transformer[])由下游 TransformerChains gadget 提供并经 iTransformers 注入。

适用版本与原理要点

  • 适用 commons-collections 3.2.1
  • 与 K1 的本质区别:K1 内建 InvokerTransformer 并靠 SPECIAL_METHOD_NAME_KEY 触发单个方法;K3 内建的是ChainedTransformer,转换逻辑完全由下游注入的 Transformer[] 决定,因此更灵活,也能在 InvokerTransformer 被类黑名单拦截、但需要多步链式转换(如 TemplatesImplTrAXFilter/InstantiateTransformer 路线)时使用。
  • 由于本 gadget 自身不含危险 Transformer,其序列化指纹与纯 K1 略有不同(HashSet 内是 ChainedTransformer 而非 InvokerTransformer)。

所属预设链

  • K3链[CommonsCollectionsK3, TransformerWithTemplatesImpl, TemplatesImpl, BytecodeConvert, Exec]
  • K1链二次反序列化1(作为内层反序列化段:... JavaNativeSerialization, CommonsCollectionsK3, TransformerWithTemplatesImpl, ...
  • K1链二次反序列化2(同上,经 RMIConnector 桥接)

关联