During a recent investigation into a compromised Magento ecommerce environment, we discovered the presence of five different backdoors that would provide attackers with code execution capabilities. The techniques used by the attackers in these backdoors illustrates the ever-changing landscape of website security and highlights some of the tactics used to avoid traditional backdoor detection.
One such backdoor was appended to the Magento core file /errors/503.php:
This sample takes user input from the “ID” URL parameter and builds a reflection function, where the object stored in the $func variable will now reflect whichever function the attacker passed as input. It then uses the “processor” URL GET parameter’s value to determine what value to pass to the function. A typical payload to abuse this could look like this:
With command execution functions such as system or shell_exec enabled, the attacker would have unhindered access to your site files, including configuration files.
It’s not uncommon for attackers to gain initial access into the site through file upload vulnerabilities, which is often how these backdoors originate on the site. By leveraging these tools, attackers can elevate from a file upload vulnerability to remote code execution capabilities. From there, they can also move into the database – for example, in the above request this would provide attackers with the full contents of the victim site’s local.xml file; a sensitive configuration file for Magento websites. With configuration files containing database connection details, it would be trivial for them to move laterally into the website’s database to add further injections aimed at capturing credit card details or administrator login credentials.
Another backdoor was found in their processor.php file, also allowing remote code execution through user defined functions:
This sample builds a class ‘A’, with a constructor that calls whichever function is named from input “X”, and passes input “_” as an argument. This backdoor could be accessed in a nearly identical manner to the previous one:
The same request can be used to exploit a backdoor located in a file named close.php:
Between register_tick_function, forward_static_call, and reflection functions there’s a handful of different methods used to achieve the same goal: execute remotely inputted code from unauthorized attackers. The variety in functions is used so as to avoid detection; by keeping no one backdoor the same the attackers can thwart attempts to search for other infections based on any previously discovered samples.
This concept is taken a step further when even seemingly benign functions are abused to achieve the same remote code execution goal. In PHP, the function session_set_save_handler() is intended to allow developers to specify how they wish to store user sessions (e.g. in a /tmp folder versus a database). The first argument of the session_set_save_handler() function allows the user to define a function that will be called whenever a session is opened, and that’s exactly what is abused in the following backdoor located in a file named 1.php:
By abusing the save handler function to accept untrusted input, the backdoor then sets a session save path and then immediately starts a session – allowing whichever malicious payload was provided in the “X” input value to be executed immediately.
One disadvantage that attackers will encounter when using GET requests to submit payloads is that if access logging is enabled on a web server or firewall, the intrusion attempts will become immediately clear. This can lead attackers to prefer using POST requests to interact with infections, or in this unusual case: cookies.
This infection first checks if a cookie named “mailto_” is set. Because this isn’t a cookie that would be set in a normal Magento installation, this helps ensure that only the attacker’s payloads are executed by this backdoor. The benign cookie name “mailto_” also helps the infection blend into the surrounding code, and by choosing to use practical variable names over common alternatives such as randomized hashes the chances of the infection being glossed over are higher. The infection then reads the value inside of the cookie named “mailto_” to craft a zip archive, and extracts it to the /tmp temporary folder.
To remain covert and avoid detection the backdoor will execute the contents of the archive (through the include() function) just before deleting the file (through the unlink() function) that was placed in the temporary folder. In the same spirit of remaining discrete, the attacker wrapped the entire backdoor in a try/catch statement to ensure that any errors that might generate through the execution of the code are silently discarded and not logged to a central file.
Prevention & Detection
One of the most effective tools to prevent attackers from utilizing any backdoors they may have uploaded is to add a website application firewall to your website. All of the provided example payloads in this blog article would’ve been detected as malicious and automatically blocked by the Sucuri firewall before they’d have a chance to even reach the website. By employing some form of request filtration and network-level security, you help ensure that even in the event a malicious file is present on your site the attackers won’t be able to utilize it to cause further damage.
The best way to detect these types of infections is through performing integrity checks on your website. These systems will track any modifications to your site files, and can help find malware that would have otherwise gone undetected. The Sucuri server side scanner does an excellent job of highlighting these modifications:
If no integrity checking system is in place, detection can be possible through inspecting access logs. For backdoors that take input directly via the URL, these clearly stick out in any logs and will show the exact file path and parameters the attacker used to access the backdoor. This does rely on the attackers actually visiting the backdoor, which isn’t always the case; it can sometimes take days or weeks after initially placing a backdoor before they return to utilize it. Routinely checking for any modified files on your website is a helpful way to ensure that all recent changes have been authorized, and a one-off core file being modified is a common indicator of compromise.
The use of backdoors in this manner show the necessity of routine integrity checking and core file monitoring. These backdoors are intentionally hidden from public view, rendering any remote or external scanners futile, and the dynamic nature of these backdoors make traditional signature based detection less reliable. With the assistance of a tool such as our server side scanner that is automatically reviewing your website code and files, it becomes much easier to immediately identify the existence of these backdoors and remediate the problem before it spreads.