Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
Last updated
Last updated
This post is dedicated to understand how the gadget ObjectDataProvider is exploited to obtain RCE and how the Serialization libraries Json.Net and xmlSerializer can be abused with that gadget.
From the documentation: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source. Yeah, it's a weird explanation, so lets see what does this class have that is so interesting: This class allows to wrap an arbitrary object, use MethodParameters to set arbitrary parameters, and then use MethodName to call an arbitrary function of the arbitrary object declared using the arbitrary parameters. Therefore, the arbitrary object will execute a function with parameters while being deserialized.
The ObjectDataProvider is defined and implemented in the System.Windows.Data namespace, which is located in the PresentationFramework.dll (C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF).
Using dnSpy you can inspect the code of the class we are interested in. In the image below we are seeing the code of PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name
As you can observe when MethodName
is set base.Refresh()
is called, lets take a look to what does it do:
Ok, lets continue seeing what does this.BeginQuery()
does. BeginQuery
is overridden by ObjectDataProvider
and this is what it does:
Note that at the end of the code it's calling this.QueryWorke(null)
. Let's see what does that execute:
Note that this isn't the complete code of the function QueryWorker
but it shows the interesting part of it: The code calls this.InvokeMethodOnInstance(out ex);
this is the line where the method set is invoked.
If you want to check that just setting the MethodName it will be executed, you can run this code:
Note that you need to add as reference C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll **in order to load System.Windows.Data
Using the previous exploit there will be cases where the object is going to be deserialized as an ObjectDataProvider instance (for example in DotNetNuke vuln, using XmlSerializer, the object was deserialized using GetType
). Then, will have no knowledge of the object type that is wrapped in the ObjectDataProvider instance (Process
for example). You can find more information about the DotNetNuke vuln here.
This class allows to specify the object types of the objects that are encapsulated in a given instance. So, this class can be used to encapsulate a source object (ObjectDataProvider) into a new object type and provide the properties we need (ObjectDataProvider.MethodName and ObjectDataProvider.MethodParameters). This is very useful for cases as the one presented before, because we will be able to wrap ObjectDataProvider inside an ExpandedWrapper instance and when deserialized this class will create the OjectDataProvider object that will execute the function indicated in MethodName.
You can check this wrapper with the following code:
In the official web page it is indicated that this library allows to Serialize and deserialize any .NET object with Json.NET's powerful JSON serializer. So, if we could deserialize the ObjectDataProvider gadget, we could cause a RCE just deserializing an object.
First of all lets see an example on how to serialize/deserialize an object using this library:
Using ysoserial.net I crated the exploit:
In this code you can test the exploit, just run it and you will see that a calc is executed: