. net advanced code audit (lesson 4) javascript serializer deserialization vulnerability

Posted by tzul at 2020-02-27

Author: ivan1ee @ 360 cloud studio

0X00 Preface

Process in. Net When AJAX is applied, the serialization function is usually provided by the JavaScript serializer class. It is an internal serialization function class implemented after. Net 2.0. It is located in the namespace system.web.script.serialization and referenced by system.web.extensions. It makes it easy for developers to realize the conversion between all types of. Net and JSON data. However, in some scenarios, developers use deserialize Or deserializeobject method will cause deserialization attack when dealing with insecure JSON data, so as to realize remote rce vulnerability. In this paper, the author introduces and repeats the relevant issues from the perspective of principle and code audit.

0x01 JavaScript serializer serialization

Let's take a look at the classic code in this series:

The testclass class defines three members and implements a static method classmethod to start the process. Serialization assigns values to members individually by creating an object instance

It is very convenient to use the serialize method in JavaScript serializer class to realize the conversion between. Net object and JSON data. The author defines testclass object, and generally uses serialize to get the serialized JSON


From the previous introduction to the principle of deserialization vulnerability of other components, we know that we need to __Type is the key value. To get the value, you must get the full identity of the assembly (including the assembly name, version, language culture and public key). In JavaScript serializer, you can instantiate the simpletypleresolver class to provide a type resolver for managed types. You can customize the metadata assembly qualified name of the type in the serialization string. The author will rewrite the code and add a type resolver

JavaScriptSerializer jss = new JavaScriptSerializer(new SimpleTypeResolver());

The complete identity of the serialized output assembly is as follows

{"__type":"WpfApp1.TestClass, WpfApp1, Version=, Culture=neutral, PublicKeyToken=null","Classname":"360","Name":"Ivan1ee","Age":18}

0x02 JavaScript serializer deserialization

2.1 deserialization usage

The anti serialization process is to transform Json data into objects, create objects in the JavaScriptSerializer class, and then call DeserializeObject or Deserialize methods to implement them.

The deserializeobject method only encapsulates a layer of functions on the deserialize method, focusing on the deserialize method. In the code, the object object is returned through the JavaScript object deserializer.basicdeserialize method

The deserializeinternal method is called inside basicdeserialize. When it needs to be converted to an object, it will determine whether the dictionary collection contains the key of the servertypefieldname constant,

The value of the servertypefieldname constant defined in the javascriptserializer class is "\,

The non core method blocks convertobjecttotype, convertobjecttotypemain and convertobjecttotypeinternal are ignored during cocooning and spinning. Finally, they are located in the convertdictionarytoobject method

This code first determines that the value of servertypefieldname exists, and then outputs and assigns the value to the object S. in the second step, it forces the object s to the string variable servertypename. In the third step, it obtains the actual type in the parser, and constructs an instance of the type through createinstance of system.activator

The activator class provides several overloaded versions of the static createinstance method. When calling a method, you can pass either a type object reference or a string identifying the type. The method returns a reference to the new object. The following demo shows the effect before and after serialization and deserialization:

After deserialization, the property of the object is obtained, and the value of the current member name is printed out

2.2 creating POC

By default, JavaScript serializer does not use a type parser, so it is a safe serialization processing class. The trigger point of the vulnerability lies in whether the simpletypleresolver class is created when initializing the instance of JavaScript serializer class. If it is created, and the deserialized JSON data is under control, the deserialization vulnerability can be triggered. Borrow the figure Explain the call chain procedure

I still choose objectdataprovider class to call methods in any referenced class. For specific usage of this class, please refer to. Net advanced code audit (Lesson 1) XmlSerializer deserialization vulnerability, because the process.start method needs to configure the properties related to processstartinfo class to start a thread, such as specifying the file name and startup parameters, so we must first consider serializing processstartinfo, which can refer to

. net advanced code audit (lesson 3) fastjson deserialization vulnerability,

Then subtract the generated data, remove the irrelevant system.runtimetype and system.intptr data, and finally get the deserialized POC

{ '__type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35', 'MethodName':'Start', 'ObjectInstance':{ '__type':'System.Diagnostics.Process, System, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'StartInfo': { '__type':'System.Diagnostics.ProcessStartInfo, System, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089', 'FileName':'cmd', 'Arguments':'/c calc.exe' } } }

The trigger code is written and the calculator is successfully popped up by deserialize < Object > deserializing JSON.

0x03 code audit Perspective


From the point of view of code audit, it's easy to find the pollution point of the vulnerability. Through the knowledge in the previous sections, we can find that a key condition needs to be met, new simpletypleresolver(), and then pass in JSON data, which can be deserialized. For example, the following jsonhelper class

An attacker only needs to control the input of the incoming string parameter to easily implement the deserialization vulnerability attack. There are also a lot of unsafe case code on GitHub


JavaScript serializer also has a deserializeobject deserializeobject, which can also trigger a vulnerability. The specific pollution code is as follows

0x04 case resumption

Finally, the following case is used to replay the whole process, and the whole process is shown in vs debugging through deserialization vulnerability pop-up calculator.

Finally, the dynamic effect diagram is attached

0x05 summary

JavaScript serializer, with the advantages provided by Microsoft itself, has a relatively high utilization rate in actual development. As long as no type resolver is used or the type resolver is configured as an effective type in the white list, it can prevent deserialization attacks (the default is the safe serializer). For attackers, the estimated utilization probability in the actual scenario is not high, after all, it is very high Multiple developers do not use the simpletypleresolver class to process data. Finally, the.NET anti serialization series will be synchronized to and The following author will introduce a high quality.NET anti serialization vulnerability article. Welcome everyone's constant attention and communication, and more.NET security and skills can be concerned about the laboratory official account.