首頁  >  文章  >  運維  >  如何進行NetDataContractSerializer反序列化漏洞分析

如何進行NetDataContractSerializer反序列化漏洞分析

PHPz
PHPz轉載
2023-05-13 21:37:04749瀏覽

一、前言

NetDataContractSerializer和DataContractSerializer一樣用於序列化和反序列化Windows Communication Foundation (WCF) 訊息中發送的資料。兩者之間存在一個重要區別:NetDataContractSerializer 包含了CLR,透過CLR類型添加額外資訊並保存引用來支援類型精確,而DataContractSerializer 則不包含。因此,只有在序列化和反序列化端使用相同的 CLR 類型時,才能使用 NetDataContractSerializer。若要序列化物件使用 WriteObject或Serialize方法, 若要反序列化 XML流使用 ReadObject或Deserialize方法。在某些場景下讀取了惡意的XML流就會造成反序列化漏洞,從而實現遠端RCE攻擊,本文筆者從原理和程式碼審計的視角做了相關介紹和復現。

二、NetDataContractSerializer序列化

#使用WriteObject或Serialize可以非常方便的實作.NET物件與XML資料之間的轉化,注意NetDataContractSerializer包含了程序集的名字和被序列化類型的類型。這些額外資訊可以用來將XML反序列化成特殊類型,允許相同類型可以在客戶端和服務端同時使用。另外的資訊是z:Id屬性在不同的元素上意義是不同的。這個用來處理引用類型以及當XML被反序列化時是否引用可以保留,最後的結論是這個輸出相比DataContractSerializer的輸出包含了更多資訊。下面透過一個實例來說明問題,先定義TestClass物件

如何進行NetDataContractSerializer反序列化漏洞分析

TestClass物件定義了三個成員,並實作了一個靜態方法ClassMethod啟動程序。序列化透過建立物件實例分別給成員賦值   

如何進行NetDataContractSerializer反序列化漏洞分析

筆者使用Serialize得到序列化TestClass類別後的xml資料

<testclass><age>18</age><classname>360</classname><name>Ivan1ee</name></testclass>

三、NetDataContractSerializer反序列

3.1 反序列化原理與用法

NetDataContractSerializer類別反序列過程是將XML流轉換為對象,透過建立一個新物件的方式呼叫ReadObject多個重載方法或Serialize方法實現的,檢視定義得知繼承自XmlObjectSerializer抽象類別、IFormatter接口,

如何進行NetDataContractSerializer反序列化漏洞分析

NetDataContractSerializer類別實作了XmlObjectSerializer抽象類別中的WriteObject、ReadObject方法,也實作了IFormatter中定義的方法。筆者透過建立新物件的方式呼叫Deserialize方法實現的具體實作程式碼可參考以下

如何進行NetDataContractSerializer反序列化漏洞分析

#其實在Deserialize方法內也是呼叫了ReadObject方法反序列化的

如何進行NetDataContractSerializer反序列化漏洞分析

反序列化過程中使用ReadObject方法呼叫了ReadObjectHandleExceptions方法,省略一些非核心程式碼,進入InternalReadObject方法體內反序列化後得到物件的屬性,列印輸出成員Name的值。

如何進行NetDataContractSerializer反序列化漏洞分析

3.2 攻擊向量—MulticastDelegate

多路廣播委託(MulticastDelegate)繼承自Delegate,其呼叫清單中可以擁有多個元素的委託,實際上所有委託類型都衍生自MulticastDelegate。 MulticastDelegate類別的_invocationList欄位在建構委託鏈時會引用委託數組,但為了取得對委託鏈更多的控制就得使用GetInvocationList方法,它是具有一個帶有鏈接的委託列表,在對委託實例進行調用的時候,將按列表中的委託順序進行同步調用,那麼如何將calc.exe新增至GetInvocationList列表方法?首先先看Comparison類,它用於位於命令空間System.Collections.Generic,定義如下

如何進行NetDataContractSerializer反序列化漏洞分析

Comparison類別回傳委託,再使用Delegate或MulticastDelegate類別的公共靜態方法Combine將委託加入鏈中作為Comparison的類型比較器   

#

如何進行NetDataContractSerializer反序列化漏洞分析使用Comparer的静态方法Create创建比较器,比较器对象在.NET集合类中使用的频率较多,也具备了定制的反序列化功能,这里选择SortedSet类,在反序列化的时内部Comparer对象重构了集合的排序。    

如何進行NetDataContractSerializer反序列化漏洞分析多路广播委托的调用列表GetInvocationList方法在内部构造并初始化一个数组,让它的每个元素都引用链中的一个委托,然后返回对该数组的引用,下面代码修改了私有字段_InvocationList并用泛型委托Func返回Process类。    

如何進行NetDataContractSerializer反序列化漏洞分析最后传入攻击载荷后得到完整序列化后的poc,如下    

如何進行NetDataContractSerializer反序列化漏洞分析

四、代码审计

4.1 Deserialize

从代码审计的角度只需找到可控的Path路径就可以被反序列化,例如以下场景:

如何進行NetDataContractSerializer反序列化漏洞分析

4.2 ReadObject

如何進行NetDataContractSerializer反序列化漏洞分析上面两种方式都是很常见的,需要重点关注。

五、复盘

1.  代码中实现读取本地文件内容    

如何進行NetDataContractSerializer反序列化漏洞分析2.  传递poc xml,弹出计算器网页返回200

1.  <arrayofstring><count>2</count> ><comparer><_comparison><delegate><assembly>mscorlib, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089</assembly> ><delegateentry><assemblyz:ref></assemblyz:ref><methodname>Compare</methodname> ><target></target><targettypename>System.String a:targetTypeName >System.Comparison`1[[System.String,mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089]] a:type > a:delegateEntry >Start a:methodName >System, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089 >System.Diagnostics.Process a:targetTypeName >System.Func`3[[System.String,mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Diagnostics.Process,System, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089]] a:type > Delegate >System.Diagnostics.Process Start(System.String,System.String) Signature >System.Diagnostics.ProcessStart(System.String, System.String) Signature2 >8 MemberType ><genericarguments></genericarguments> method0 >Int32 Compare(System.String, System.String) Signature >System.Int32 Compare(System.String,System.String) >8 MemberType > method1 > _comparison > Comparer >2 Version >/c calc.exe string >cmd string > Items > ArrayOfstring ></targettypename></delegateentry></delegate></_comparison></comparer></arrayofstring>

最后附上动态效果图

如何進行NetDataContractSerializer反序列化漏洞分析

以上是如何進行NetDataContractSerializer反序列化漏洞分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除