X-PHP
phpggc
Library of pre-built PHP unserialize() gadget chains and a CLI to generate ready-to-use deserialization payloads for common frameworks and libraries.
OVERVIEW
phpggc (github.com/ambionics/phpggc), from Ambionics Security, does not find PHP deserialization vulnerabilities — it assumes one is already confirmed and solves the next problem: building the serialized object graph, or 'gadget chain', that actually turns an unserialize() call into remote code execution, a file write, or another impact. A gadget chain strings together magic methods (__wakeup, __destruct, __toString, and similar) already present in a target's own dependencies so that reconstructing the object graph makes them fire in sequence toward an attacker-chosen outcome.
It ships pre-built chains for dozens of widely used PHP libraries and frameworks (Laravel, Symfony, Monolog, Guzzle, SwiftMailer, WordPress plugins, and more), so a tester who's confirmed an unserialize() sink and fingerprinted the app's dependencies can generate a working payload with a single command instead of reverse-engineering a chain from scratch — which is also why the library needs updating as target frameworks patch or remove the vulnerable magic methods a given chain relies on.
USE CASES
Practical use cases
- 01
Generating a working RCE or file-write payload for a confirmed unserialize() sink in a fingerprinted framework.
- 02
Listing and filtering available gadget chains (phpggc -l) to match a target's specific dependency versions.
- 03
Encoding a generated payload (base64, URL-encode) to fit the delivery mechanism a specific sink requires.
- 04
Cross-checking GadgetProbe classpath/library fingerprinting results against phpggc's supported chains to pick the right one.
QUICK START
Once a PHP application is confirmed to unserialize() attacker-controlled input, to generate a working exploitation payload instead of writing a gadget chain by hand.
- Confirm the unserialize() sink is real and fingerprint which PHP libraries/frameworks and versions the target actually loads.
- Clone phpggc and list the gadget chains available for that fingerprint (phpggc -l <keyword>).
- Generate the payload for the matching chain with the command you want executed.
- Apply the encoding the delivery point needs (-b for base64, -u for URL-encode).
- Deliver the payload to the confirmed sink and verify impact through an out-of-band or blind-write check.
./phpggc Laravel/RCE1 system id -bBEFORE YOU RUN IT
What to check before running it
A generated payload is working exploit code the moment it's created — store and transmit it per the engagement's evidence-handling rules, not in a shared scratch directory.
A chain matching the fingerprinted library does not guarantee it fires — patched magic methods, disabled functions, or a different autoloading order can silently break it.
Only run generated payloads against the confirmed sink and hosts explicitly in scope; a working RCE chain is as destructive as any other exploit once it lands.