参考:
- https://mp.weixin.qq.com/s/HskIJZtl4fPRyc2G36JFow
反序列化漏洞中利用到很多反射的知识,
普通的new一个对象:
// 先拿到Class对象
Class<?> aClass = Class.forName("org.chabug.entity.ReflectionClass");
// new这个Class对应的对象
Object o = aClass.newInstance();
普通的public方法可以直接调用:这里是调用setName
方法,并传入参数"jack"
Method setName = aClass.getDeclaredMethod("setName", String.class);
setName.invoke(o, "jack" );
如果是private的方法,就要多一步,通过setAccessible
修改方法的修饰符:
Method evil = aClass.getDeclaredMethod("evil", String.class);
evil.setAccessible(true);
evil.invoke(o,"calc");
测试javaassist功能
先有一个Cqq.java文件:
package ysoserial;
public class Cqq {
public static void main(String[] args){
System.out.println("test Cqq!");
}
}
通过以下代码插入静态代码块(先于main方法执行):
public static void testJavaAssist2() throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(ysoserial.Cqq.class.getName());
String cmd = "System.out.println(\"evil code\");";
// 创建 static 代码块,并插入代码
cc.makeClassInitializer().insertBefore(cmd);
String randomClassName = "EvilCat" + System.nanoTime();
// 设置为随机的类名、文件名
cc.setName(randomClassName);
// 写入.class 文件
cc.writeFile();
}
写入之后发现生成了EvilCat17158211564099.class
文件,在IDEA中反编译得到以下java代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
public class EvilCat17158211564099 {
public EvilCat17158211564099() {
}
public static void main(String[] args) {
System.out.println("test Cqq!");
}
static {
System.out.println("evil code");
}
}
可以发现插入了静态代码块,而且类名也该了。
参考:
https://b1ngz.github.io/java-deserialization-jdk7u21-gadget-note/