Hacking Book | Free Online Hacking Learning


. net advanced code audit (lesson 1) xmlserializer anti sequence vulnerability

Posted by truschel at 2020-03-24

Author: ivan1ee @ 360 cloud studio

作者: [email protected]云影实验室

The XmlSerializer class in the. Net framework is a great tool for mapping highly structured XML data to. Net objects. The XmlSerializer class performs the conversion between XML documents and objects through a single API call in the program. The mapping rules of the transformation are represented by metadata attributes in the. Net class. If the program developer uses the static method of the type class to obtain the external data and calls deserialize to deserialize the XML data, the deserialization vulnerability attack (such as DotNetNuke arbitrary code execution vulnerability) will be triggered Cve-2017-9822), from the perspective of principle and code audit, the author introduces and repeats relevant brain maps.

The XmlSerializer class under the system.xml.serialization namespace in the. Net framework can bind XML documents to instances of. Net classes. It should be noted that it can only convert public attributes and fields of objects into XML elements or attributes, and it consists of two methods: serialize() for generating XML from object instances; deserialize() for XML The document is analyzed into an object graph, and the serialized data can be data, fields, arrays, and embedded XML in the format of xmlelement and xmlattribute objects. See demo below for details

Xmlelement specifies that the attribute should be serialized as an element, xmlattribute specifies that the attribute should be serialized as an attribute, and xmlroot specifies that the class should be serialized as a root element; the attribute, name, namespace and type to be generated are affected by the attribute type. Create an instance of testclass to fill in its attributes and serialize it into a file. Xmlserializer.serialize method overload can accept stream, textwrite and xmlwrite classes. The final XML file generated lists testclass elements, classname attributes and other attributes stored as elements:

Deserialization: the conversion of XML file to object is realized by calling xmlserializer.deserialize method in the way of creating a new object. New is the key link in serialization The parameter passed in the XmlSerializer construction method comes from the system.type class, through which you can access information about any data type. There are three ways to point to a type reference of any given type.

2.1, typeof

The type of (testclass) passed in by instantiating XmlSerializer means to get the type of testclass. Typeof is the operator in C #, and the parameter passed can only be the name of the type, not the instantiated object, as shown in demo below

After you get the type through typeof, you can get all the methods, members and other information in the class. The following figure shows the value of the current member name when running debug.


In. Net, all classes are ultimately derived from system.object. Many public and protected member methods are defined in the object class. These methods can be used in all other classes defined by themselves. The GetType method is one of them. This method returns an instance of the class derived from system.type, because it can provide information about the class to which the object member belongs, including the basic type Methods, properties, etc. instantiate testclass in the above case, and then obtain the type of the current instance, as shown in demo below


The third method is the static method GetType of the type class. This method allows the external to pass in strings, which is a great advantage. Only passing in the fully qualified name can call the methods and properties in this class

The parameters passed in by type.gettype are also the vulnerability pollution points generated by deserialization. Next, we need to find the classes that can be used to attack.

First, put on the attack chain to create a complete demo. This demo can be reused anywhere (here. Net core and MVC are not involved), as shown in the following figure

As long as there is a deserialization vulnerability in XmlSerializer, you can use the content in the following demo, which involves three main technical points. The principles are described below.


Objectdataprovider class, which is located in the system.windows.data namespace, can call any method in the referenced class, providing member objectinstance to call the name of the method of the specified type with similar instantiation class and member methodname, and member methodparameters to represent the parameters passed to the method. Refer to the following figure

Then define a classmethod method method for testclass class. The code implementation calls system.diagnostics.process.start to start a new process pop-up calculator. If the XmlSerializer is used to serialize directly, an exception will be thrown, because the member type of objectinstance is unknown during the serialization process. However, you can use the expandedwrapper extension class to preload queries of related entities in the system to avoid exception errors and overwrite demo

The content of data.xml generated is as follows:

The first step of the attack chain is completed, but the disadvantage is that the new testclass class created by the author in the test environment has a vulnerability, but it is very complex in the production situation. It is necessary to find vulnerable attack points in the web program. In order to reduce the attack cost, the system class must be called to achieve command execution, so the following knowledge needs to be introduced.


Resourcedictionary, also known as resource dictionary, is usually used in WPF or uwp applications to share static resources among multiple assemblies. Since it is a WPF program, it must be designed to the front-end UI design language XAML. Xaml full name extensible application markup language is based on XML, and XAML takes a tree structure as a whole. If you understand XML, you can quickly master it. For example, see demo below

The first label, resourcedictionary, xmlns: runtime, indicates that the name of the read system.diagnostics command space starts with an alias of runtime; the second label, objectdataprovider, specifies three attributes, X: key, which is convenient for conditional retrieval and has little significance but must be defined; objectType It is used to get or set the type of the object whose instance is to be created, and uses the XAML extension; X: type is equivalent to the typeof operator function in C ා, where the value passed is system.diagnostics.process; methodname, which is used to get or set the name of the method to be called, and the value passed is system.diagnostics.process.start, which is used to start a process. The third tag objectdataprovider.methodparameters embeds two method parameter tags. Through system: string, it specifies the startup file and parameters to be used by the start method. After introducing the resourcedictionary in the attack chain, the payload principal of the attack has been completed. Next, the attack is implemented through the XML parser provided by the system class xamlreader.


Xamlreader is located in the space of system.windows.markup. As the name implies, it is used to read XAML files. It is the default XAML reader. It reads XAML data in stream stream through load and returns it as root object. Another parse method reads XAML input in specified string and also returns it as root object. Natural parse method is what we care about and seek.

Just use objectinstance method of objectdataprovider to instantiate xamlreader, specify methodname as parse, and pass serialized resource dictionary data to methodparameters, so as to complete the construction of XmlSerializer deserialization attack chain.

From the perspective of code audit, it is easy to find the pollution point of the vulnerability. Based on the knowledge in the previous sections, it can be found that serialization needs to meet a key condition, type.gettype. The program must pass the static method GetType of type class, such as the following demo

First, the XmlDocument object is created and loaded into XML. The variable typeName gets the value of the type attribute of the Item node through Xpath and passes it to Type.GetType. Then, all the Xml data in the Item node is read and finally handed to the Deserialize method for deserialization. This is a near perfect utilization point. Let's look at the XmlSerializer deserialization class I collected on GitHub: xmlserializeutil.cs

The type of the value parameter here is type. There is no problem with the code itself. The problem is that the program developer may define a string variable to accept the passed type value, return the type object through type.gettype (string), and then pass it to deserializexml. In the process of code audit, you also need to pay attention to the source of the type here. 0x05 case re disk finally through the following case to re disk the whole process, the whole process is shown in vs debugging through deserialization vulnerability pop-up calculator.

Finally, attach the dynamic diagram

Because XmlSerializer is the default anti sequence class of the system, the utilization rate is relatively high in the actual development. When the attacker finds that the pollution point is controllable, he can find the utilization point from two dimensions. The first is to find the class and method that can execute commands or write webshell from the web application; the second is to use objectdataprovider and resourcedicti in this paper The attack chain composed of nary and xamlreader is used to execute commands or bounce shells. Finally, the author of the. Net deserialization series courses will synchronize to https://github.com/ivan1ee/, https://ivan1ee.gitbook.io/. Later, the author will successively launch high-quality. Net deserialization vulnerability articles. The general course outline is shown in the following figure

You are welcome to continue to pay attention and exchange.