Java反序列化/反射/动态生成字节码

参考:

  • 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/

你可能感兴趣的:(java)