大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 Java反序列化工具:Gadgetinspector First Glimpse

Java反序列化工具:Gadgetinspector First Glimpse

更新時間:2021-11-04 10:08:12 來源:動力節點 瀏覽1617次

關于Gadgetinspector First Glimpse這個工具

此工具不用于查找漏洞。相反,它使用已知的 source->…->sink 技巧或其類似的特性來發現分支利用鏈或新的利用鏈。

這個工具在整個應用程序的類路徑中尋找一個鏈。

該工具執行一些合理的風險估計(污點判斷、污點轉移等)。

這個工具會產生誤報而不是漏報(其實還是會漏掉的,這是由作者使用的策略決定的,可以在下面的分析中看到)。

該工具基于字節碼分析。對于Java應用,很多時候我們沒有源代碼,只有War包、Jar包或者class文件。

此工具不會生成可直接使用的 Payload。具體的利用結構也需要人工參與。

序列化和反序列化

Java學習中,序列化是將對象的狀態信息轉換為可以存儲或傳輸的形式的過程。轉換后的信息可以存儲在磁盤上。在網絡傳輸過程中,可以是字節、XML、JSON等形式,將字節、XML、JSON等形式的信息還原為對象的逆過程稱為反序列化。

在Java中,對象序列化和反序列化廣泛應用于RMI(遠程方法調用)和網絡傳輸。

Java 中的序列化和反序列化庫

JDK(對象輸入流)

XStream(XML,JSON)

杰克遜(XML,JSON)

根森(JSON)

JSON-IO(JSON)

FlexSON(JSON)

Fastjson(JSON)

不同的反序列化庫在反序列化不同的類時有不同的行為。不同的“魔法方法”會被自動調用,這些自動調用的方法可以作為反序列化的入口點(源碼)。如果這些自動調用的方法調用了其他的子方法,那么調用鏈中的一個子方法也可以作為源,相當于知道了調用鏈的前端,從一個子方法開始尋找不同的分支。一些危險的方法(sink)可以通過方法的層調用來達到。

對象輸入流

比如一個類實現了Serializable接口,那么ObjectInputStream.readobject在反序列化的時候會自動找到該類的readObject、readResolve等方法。

比如一個類實現了Externalizable接口,那么ObjectInputStream.readobject在反序列化的時候會自動找到這個類的readExternal等方法。

杰克遜

ObjectMapper.readValue反序列化一個類時,會自動查找反序列化類的無參構造函數、包含基類型參數的構造函數、屬性的setter、屬性的getter等。

在接下來的分析中,以JDK自帶的ObjectInputStream為例。

控制數據類型 => 控制代碼

在反序列化漏洞中,如果我們控制了數據類型,我們就控制了代碼。這是什么意思?根據理解,寫了下面的例子:

public class TestDeserialization {
    interface Animal {
        public void eat();
    }
    public static class Cat implements Animal,Serializable {
        @Override
        public void eat() {
            System.out.println("cat eat fish");
        }
    }
    public static class Dog implements Animal,Serializable {
        @Override
        public void eat() {
            try {
                Runtime.getRuntime().exec("calc");
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("dog eat bone");
        }
    }
    public static class Person implements Serializable {
        private Animal pet;
        public Person(Animal pet){
            this.pet = pet;
        }
        private void readObject(java.io.ObjectInputStream stream)
                throws IOException, ClassNotFoundException {
            pet = (Animal) stream.readObject();
            pet.eat();
        }
    }
    public static void GeneratePayload(Object instance, String file)
            throws Exception {
        //Serialize the constructed payload and write it to the file
        File f = new File(file);
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
        out.writeObject(instance);
        out.flush();
        out.close();
    }
    public static void payloadTest(String file) throws Exception {
        //Read the written payload and deserialize it
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
        Object obj = in.readObject();
        System.out.println(obj);
        in.close();
    }
    public static void main(String[] args) throws Exception {
        Animal animal = new Dog();
        Person person = new Person(animal);
        GeneratePayload(person,"test.ser");
        payloadTest("test.ser");
//        Animal animal = new Cat();
//        Person person = new Person(animal);
//        GeneratePayload(person,"test.ser");
//        payloadTest("test.ser");
    }
}

為方便起見,將所有類都寫在一個類中進行測試。在Person類中有Animal類的屬性pet,它是Cat和Dog的接口。在序列化中,我們可以控制Per的pet是Cat對象還是Dog對象,所以在反序列化中,pet.eat()inreadObject的具體方向是不同的。如果pet是Cat類對象,就不會去執行有害代碼Runtime.getRuntime().exec("calc");,但是如果pet是Dog類對象,它就會去執行有害代碼。

即使有時在聲明時為類屬性分配了特定對象,它仍然可以通過 Java 中的反射進行修改。如下:

public class TestDeserialization {
    interface Animal {
        public void eat();
    }
    public static class Cat implements Animal, Serializable {
        @Override
        public void eat() {
            System.out.println("cat eat fish");
        }                           
    }
    public static class Dog implements Animal, Serializable {
        @Override
        public void eat() {
            try {
                Runtime.getRuntime().exec("calc");
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("dog eat bone");
        }
    }
    public static class Person implements Serializable {
        private Animal pet = new Cat();
        private void readObject(java.io.ObjectInputStream stream)
                throws IOException, ClassNotFoundException {
            pet = (Animal) stream.readObject();
            pet.eat();
        }
    }
    public static void GeneratePayload(Object instance, String file)
            throws Exception {
        //Serialize the constructed payload and write it to the file
        File f = new File(file);
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
        out.writeObject(instance);
        out.flush();
        out.close();
    }
    public static void payloadTest(String file) throws Exception {
        //Read the written payload and deserialize it
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
        Object obj = in.readObject();
        System.out.println(obj);
        in.close();
    }
    public static void main(String[] args) throws Exception {
        Animal animal = new Dog();
        Person person = new Person();
        //Modify private properties by reflection
        Field field = person.getClass().getDeclaredField("pet");
        field.setAccessible(true);
        field.set(person, animal);
        GeneratePayload(person, "test.ser");
        payloadTest("test.ser");
    }
}

在Person 類中,您不能通過構造函數或setter 方法或其他方法為pet 賦值。該屬性在聲明時就已經定義為Cat類的對象,但是使用反射可以將pet修改為Dog類的對象,所以反序列化的時候還是會跑到有害代碼中去。

這只是我個人對作者的看法:“控制數據類型,你控制代碼”。在Java反序列化漏洞中,很多時候是利用Java的多態特性來控制代碼的方向,最終達到作惡的目的。

魔法方法

在上面的例子中,我們可以看到Person的readobject方法在反序列化的時候并沒有被手動調用。當 ObjectInputStream 反序列化對象時會自動調用它。作者將自動調用的方法調用為“魔術方法”。

使用 ObjectInputStream 反序列化時的幾種常見魔術方法:

Object.readObject()

Object.readResolve()

Object.finalize()

一些可序列化的 JDK 類實現了上述方法,并且還會自動調用其他方法(可以用作已知的入口點):

哈希表

Object.hashCode()

Object.equals()

優先隊列

Comparator.compare()

Comparable.CompareTo()

一些水槽:

Runtime.exec(),在目標環境中直接執行命令的最簡單直接的方式

Method.invoke(),需要正確選擇方法和參數,并通過反射執行Java方法

RMI/JNDI/JRMP等,通過引用遠程對象間接實現任意代碼執行的效果

以上就是關于“Java反序列化工具:Gadgetinspector First Glimpse”的介紹,大家如果想了解更多相關知識,不妨來關注一下動力節點的Java開發工具,里面對于工具的介紹有很多,大家可以多去學習一下。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 视频在线观看91 | 在线播放精品一区二区啪视频 | 国产小网站 | 欧美成人hd | 国产午夜亚洲精品不卡福利 | 久久www免费人成_看片美女图 | 亚洲综合五月 | 伊人色综合久久天天 | 最新亚洲精品国自产在线 | 日韩精品一区二区三区在线观看l | 97在线观看成人免费视频 | 欧美精品亚洲二区 | 天天艹天天操 | 大乳妇女bd视频在线观看 | 日韩一级精品视频在线观看 | 久久婷婷色一区二区三区 | 999精品免费视频 | 国产一级精品高清一级毛片 | 色婷婷在线播放 | 美女久久久久久久久久久 | 久久艹伊人 | 久久亚洲国产成人精品性色 | aaa大片 | 天天爱天天舔 | 在线成人精品国产区免费 | 亚洲综合色区图片区 | 亚洲日本va| 久草在线免费播放 | 天天干天天爱天天操 | 国产亚洲精品视频中文字幕 | 日本午夜色 | 久操免费在线 | 五月综合色 | 久在线视频 | 免费在线一区二区三区 | 国内精品免费一区二区观看 | 99re热视频精品首页 | 国产成人精品久久一区二区小说 | 国产日产欧美a级毛片 | 蜜桃久久久 | 日韩精品一区二区三区在线观看l |