<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>

    .NET反序列化漏洞之繞過 SerializationBinder 不安全的類型綁定

    VSole2022-07-05 06:17:35

    概述

    很多 .NET 應用程序在修復 `BinaryFormatter` 、 `SoapFormatter` 、`LosFormatter` 、 `NetDataContractSerializer` 、`ObjectStateFormatter ` 等反序列化漏洞時,喜歡通過自定義 `SerializationBinder` 來限定類型,從而達到緩解反序列化攻擊的目的。歷史上很多 .NET 反序列化漏洞都采用了這種方法,但是我們查看微軟官方的警告說明:

    使用 `SerializationBinder` 無法完全修復反序列化漏洞隱患。最近看到老外發了一篇相關文章,感覺很有價值,自己也深入研究總結了兩種不安全的 `SerializationBinder` 限定方式,下面分享給大家。

    SerializationBinder 綁定限制

    常見修復方式就是對 `BinaryFormatter` 反序列化過程綁定 `Binder` 對象,通過 `SerializationBinder` 來檢查反序列化類型。構建如下 `demo`。

    反序列化操作如下:

    using (var fileStream = new FileStream(file, FileMode.Open)){    BinaryFormatter formatter = new BinaryFormatter();    fileStream.Position = 0;    formatter.Binder=new SafeDeserializationBinder();    formatter.Deserialize(fileStream);}
    

    自定義 `SafeDeserializationBinder` 繼承于 `SerializationBinder` ,通過黑名單機制進行檢查,當發現存在惡意類型時,比如 `System.Data.DataSet` ,將阻斷反序列化過程:

    public class SafeDeserializationBinder : SerializationBinder{    List blackTypeName = new List<string> { };
        private void _AddBlackList()    {        blackTypeName.Add("System.Data.DataSet");    }
        public override Type BindToType(string assemblyName, string typeName)    {        this._AddBlackList();        foreach (var t in blackTypeName)        {            if (typeName.Equals(t))            {                //todo            }        }        return Type.GetType(typeName);    }}
    

    Bypass 1 :無效的 null 返回值

    大家很容易想到,當檢測到反序列化黑名單,直接返回 `null` :

    這樣真的可以阻斷反序列化漏洞嗎?我們可以進行測試。利用 `YSoSerial.Net` 特定生成 `System.Data.DataSet` 的反序列化載荷:

    ysoserial.exe -o raw -f BinaryFormatter -g DataSet -c calc >payload.txt
    

    確實返回了 `null` ,但是發現最終還是執行了反序列化操作并觸發了 RCE:

    為什么呢?下面調試分析一下原因。`BinaryFormatter` 反序列化時將調用 `ObjectReader#Bind` 來獲取 `Type` 類型:

    首先調用自定義的 `SafeDeserializationBinder#BindToType` ,當返回 `null` 時,函數并沒有直接結束,而是繼續調用 `FastBindToType` 來獲取 `Type` 對象:

    首先嘗試從 `typecache` 緩存中提取,程序首次調用獲取不到值,繼續判斷 `bSimpleAssembly` 的取值(默認始終為 `true`),進而嘗試調用 `GetSimplyNamedTypeFromAssembly` :

    通過 `FormatterServices#GetTypeFromAssembly` 最終取到了 `type` 的值:

    所以嘗試在 `SerializationBinder` 加載惡意 `Type` 時通過返回 `null` 是無法阻斷反序列化漏洞的。比如 Exchange CVE-2022-23277 就是由于在遇到黑名單時最終返回 `null` 從而導致被繞過。要想 `SerializationBinder` 有效,正確的做法是拋出異常,修改 `demo` 如下:

    拋出異常將中斷后續處理流程,導致反序列化綁定的 `Type` 最終確定為 `null` ,從而無法觸發反序列化漏洞。

    Bypass 2 :拋出異常真的安全嗎?

    上面通過拋出異常的方式真的能夠完全修復漏洞嗎?答案是否定的。我們思考下既然反序列化操作可以通過 `BindToType` 檢查 `Type` 和 `Assembly` ,那么在生成序列化載荷時,就可能可以自定義 `Type` 和 `Assembly` ,查看 `YSoSerial.Net` 生成 `System.Data.DataSet` 的反序列化載荷的代碼段 ( `/Generators/DataSetGenerator.cs` ):

    我們可以手動去修改 `Type` 的賦值過程,確保讓其不位于黑名單之中,比如:

    重新編譯生成 `YSoSerial.Net` ,并再次生成新的 `DataSet` 反序列化載荷:

    此時 `typeName` 并不在黑名單之中,所以不會拋出異常,但是卻成功返回了正確的 `Type` 類型,從而繞過檢查進而實現了 RCE :

    比如 DevExpress CVE-2022-28684 反序列化漏洞就是通過類似上面這種方式實現 Bypass 的。

    小結

    通過 `SerializationBinder` 綁定 `Type` 類型來緩解反序列化漏洞,無論是直接返回 `null` 還是拋出異常,都存在被繞過的風險,最好的修復方式其實微軟官方已經給出了答案,那就是不要使用 `BinaryFormatter` 這類反序列化類:

    漏洞序列化
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    最近兩個月我一直在做拒絕服務漏洞相關的時間,并收獲了Spring和Weblogic的兩個CVE但DoS漏洞終歸是雞肋洞,并沒有太大的意義,比如之前有人說我只會水垃圾洞而已,所以在以后可能打算做其他方向早上和pyn3rd師傅聊天
    淺談Java反序列化漏洞
    2022-05-17 17:48:01
    Java序列化與反序列化Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節序列,該字節序列包括該對象的數據、有關對象的類型的信息和存儲在對象中數據的類型。反序列化就是打開字節流并重構對象。對象序列化不僅要將基本數據類型轉換成字節表示,有時還要恢復數據。
    序列化漏洞匯總
    2022-01-07 22:17:34
    漏洞出現在WLS Security組件,允許遠程攻擊者執行任意命令。攻擊者通過向TCP端口7001發送T3協議流量,其中包含精心構造的序列化Java對象利用此漏洞。然后將其序列化,提交給未做安全檢測的Java應用。Java應用在進行反序列化操作時,則會觸發TransformedMap的變換函數,執行預設的命令。
    序列化的核心思維旨在,將A變成B,最后再從B還原回A。 總之,在一些條件苛刻或者變化無常的環境與需求中,產生了這種靈活的可逆性的B的中間體。 理解不安全反序列化的最好方法是了解不同的編程語言如何實現序列化和反序列化。這里的序列化與反序列化指的是程序語言中自帶的實施與實現。而非自創或者自定義的序列化與反序列化機制(比如:N進制形式hashmap樹型等其他數據結構里的序列化中間體)。
    漏洞影響版本 Jboss 漏洞搭建 在阿里云端,用docker 搭建測試環境jboos使用的漏洞庫是 vulhub ,進入漏洞庫選擇jboos里面有三個選項選擇第一個cve.輸入 docker-compose up -d 啟動 本地測試,在瀏覽器輸入訪問 /invoker/readonly,若顯示HTTP Status 500,則說有反序列化漏洞。使用工具測試驗證漏洞是否存在,工具下載地址: ... 執行whoami命令
    前置知識分析Transformer接口及其實現類。transform()傳入對象,進行反射調用。構造調用鏈調用鏈構造原則:找調用關系要找不同名的方法,如果找到同名,再通過find usages得到的還是一樣的結果。找到InvokerTransformer類中的transform(),右鍵,點 Find Usages,找函數調用關系,最好找不同名的方法,調用了transform()。因為transform()調用transform()不能換到別的方法里,沒有意義。如果有一個類的readObject()調用了get(),那我們就可能找到了調用鏈。最終選擇TransformedMap這個類,因為TransformedMap類中有好幾處都調用了transform()。
    使用 SerializationBinder 無法完全修復反序列化漏洞隱患。經過深入研究總結了兩種不安全 SerializationBinder 限定的繞過方式,下面分享給大家。
    近日Oracle通報了一個反序列化漏洞CVE-2022-21445,未經身份認證的遠程攻擊者可利用該漏洞實現反序列化操作導致任意代碼執行。任何基于ADF Faces框架開發的程序都受到此漏洞的影響,包括Oracle的多個產品。
    Fastjson Develop Team發布安全公告,修復了一個存在于Fastjson1.2.80 及之前版本中的反序列化漏洞漏洞編號:暫無,漏洞威脅等級:高危。
    JDK7u21的核心點是我們在cc1中也出現過的AnnotationInvocationHandler,在cc1中我們用到了他會觸發this.memberValues.get(var4);這個點,而在JDK7u21中利用到了他里面的equalsImpl。先來看一下equalsImpl。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类