原文來自安全客,作者:Ivan1ee@360云影實驗室
原文鏈接:https://www.anquanke.com/post/id/176519

相關閱讀:

0x00 前言

BinaryFormatter和SoapFormatter兩個類之間的區別在于數據流的格式不同,其他的功能上兩者差不多,BinaryFormatter位于命名空間 System.Runtime.Serialization.Formatters.Binary它是直接用二進制方式把對象進行序列化,優點是速度較快,在不同版本的.NET平臺里都可以兼容。但是使用反序列化不受信任的二進制文件會導致反序列化漏洞從而實現遠程RCE攻擊,本文筆者從原理和代碼審計的視角做了相關介紹和復現。

0x01 BinaryFormatter序列化

使用BinaryFormatter類序列化的過程中,用[Serializable]聲明這個類是可以被序列化的,當然有些不想被序列化的元素可以用[NoSerialized]屬性來規避。下面通過一個實例來說明問題,首先定義TestClass對象

img

定義了三個成員,并實現了一個靜態方法ClassMethod啟動進程。 序列化通過創建對象實例分別給成員賦值

img

常規下使用Serialize得到序列化后的二進制文件內容打開后顯示的數據格式如下

img

0x02 BinaryFormatter反序列化

2.1、反序列化用法

反序列過程是將二進制數據轉換為對象,通過創建一個新對象的方式調用Deserialize多個重載方法實現的,查看定義可以看出和SoapFormatter格式化器一樣實現了IRemotingFormatter、IFormatter接口

img

我們得到系統提供的四個不同的反序列方法,分別是Deserialize、DeserializeMethodResponse、UnsafeDeserialize、UnsafeDeserializeMethodResponse。筆者通過創建新對象的方式調用Deserialize方法實現的具體實現代碼可參考以下

img

反序列化后得到TestClass類的成員Name的值。

img

2.2、攻擊向量—ActivitySurrogateSelector

由于上一篇中已經介紹了漏洞的原理,所以本篇就不再冗余的敘述,沒有看的朋友請參考《.NET高級代碼審計(第八課) SoapFormatter反序列化漏洞》,兩者之間唯一的區別是用了BinaryFormatter類序列化數據,同樣也是通過重寫ISerializationSurrogate 調用自定義代碼,筆者這里依舊用計算器做演示,生成的二進制文件打開后如下圖

img

按照慣例用BinaryFormatter類的Deserialize方法反序列化

img

計算器彈出,但同時也拋出了異常,這在WEB服務情況下會返回500錯誤。

img

2.3、攻擊向量—WindowsIdentity

有關WindowsIdentity原理沒有看的朋友請參考《.NET高級代碼審計(第二課) Json.Net反序列化漏洞》,因為WindowsIdentity最終是解析Base64編碼后的數據,所以這里將Serializer后的二進制文件反序列化后彈出計算器

img

img

0x03 代碼審計視角

3.1、UnsafeDeserialize

從代碼審計的角度找到漏洞的EntryPoint,相比Deserialize,UnsafeDeserialize提供了更好的性能,這個方法需要傳入兩個必選參數,第二個參數可以為null,這種方式不算很常見的,需要了解一下,下面是不安全的代碼:

img

攻擊者只需要控制傳入字符串參數path便可輕松實現反序列化漏洞攻擊。

3.2、UnsafeDeserializeMethodResponse

相比DeserializeMethodResponse,UnsafeDeserializeMethodResponse性能上更加出色,這個方法需要傳入三個必選參數,第二和第三個參數都可為null,這種方式也不算很常見,只需要了解一下,下面是不安全的代碼:

img

3.3、Deserialize

Deserialize方法很常見,開發者通常用這個方法反序列化,此方法有兩個重載,下面是不安全的代碼

img

3.4、DeserializeMethodResponse

相比Deserialize,DeserializeMethodResponse可對遠程方法響應提供的Stream流進行反序列化,這個方法需要傳入三個必選參數,第二和第三個參數都可為null,這種方式也不算很常見,只需要了解一下,下面是不安全的代碼:

img

最后用這個方法彈出計算器,附上動圖

img

0x04 總結

實際開發中BinaryFormatter 類從.NET Framework 2.0開始,官方推薦使用BinaryFormatter來替代SoapFormatter,特點是BinaryFormatter能更好的支持泛型等數據,而在反序列化二進制文件時要注意數據本身的安全性,否則就會產生反序列化漏洞。最后.NET反序列化系列課程筆者會同步到 https://github.com/Ivan1ee/https://ivan1ee.gitbook.io/ ,后續筆者將陸續推出高質量的.NET反序列化漏洞文章,歡迎大伙持續關注,交流,更多的.NET安全和技巧可關注實驗室公眾號。


本文經安全客授權發布,轉載請聯系安全客平臺。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/901/