X-Cart Skimmer with DOM-based Obfuscation

X-Cart Skimmer with DOM Based Obfuscation

Our lead security analyst Liam Smith recently worked on an infected X-Cart website and found two interesting credit card stealers there — one skimmer located server-side, the other client-side.

X-Cart’s e-commerce platform is not nearly as popular as Magento or WooCommerce and as a result we don’t see as many threat actors targeting it. While we do still regularly find skimmers on X-Cart sites, they are usually more customized and don’t look like typical Magecart malware.

Server-Side Credit Card Stealer

The server-side skimmer found in the compromised environment was very simple.

In the payment/payment_swoosh_cc.php file, hackers had added a single line of code that saved the base64-encoded POST data with payment details into a file on disk.

To make it less suspicious, the file had a .jpg extension and was placed in a directory with image files. To retrieve the stolen information, hackers simply needed to download their fake JPG file from time to time.

Injected line of code that saves payment details into a fake image file
Injected line of code that saves payment details into a fake image file

Client-Side Credit Card Stealer

The client side skimmer turned out to be much more interesting. The following obfuscated script was found in the skin/common_files/check_cc_number_script.tpl file.

Injected JavaScript skimmer
Injected JavaScript skimmer

The first steps of deobfuscation were obvious. We applied the decodeURIComponent function and prettified the resulting JavaScript code.

Prettified code after the first steps of deobfuscation
Prettified code after the first steps of deobfuscation

Anti-Debugging Trap

The resulting code was still obfuscated and didn’t reveal its functionality. It obviously contained functions to decode itself, so we executed the script to reconstruct its meaningful representation. At this step, we encountered the first obstacle. The script returned errors telling us that certain variables were “undefined”.

After the analysis, we figured out that the deobfuscation algorithm relied on the length of the code of one of the wrapper functions. The use of decodeURIComponent along with the prettification of the code to improve readability had significantly changed the length of that function and broke the deobfuscation algorithm.

We regularly come across this “anti-debugging” approach in malware. It can normally be circumnavigated by copying the original script and feeding its content to the function that calculates its length. In this case, because of the additional layer of obfuscation, we used a different approach. We wrote a brute force script that tried all possible numbers unless it found the one that produced meaningful deobfuscation results.

Credit Card Stealer Functionality

After we had successfully deobfuscated the script, all we needed to do was replace the encrypted values with their plain text versions and rename variables and function names to see how exactly the malicious code worked.

As we anticipated, the script contained typical skimmer functionality. It looked for the input and select form elements and sent their values to a third-party server as lightly encoded (encodeURIComponent) GET parameters of an injected script. To make sure that only valid payment details are sent to the attacker, the malware checks the values to verify  that at least one of the “input” elements contains a valid credit card number using a publicly available validation algorithm.

DOM-based Obfuscation of the Exfiltration Domain

At this stage, the only unknown left was the domain name of the exfiltration script that skimmer tried to inject.

After our deobfuscation efforts, the relevant part of the code looked like this:

Code that injects the exfiltration script
Code that injects the exfiltration script

As you can see, the URL can only be determined when you actually run the code on the infected page. The static analysis only reveals that the domain name begins with “meta” and ends with “.com”. The rest depends entirely on the DOM (Document Object Model) structure of the page where the script is injected — namely, on the first two HTML tags on that page.

In our case, the infected site had pretty standard beginning for the HTML code:

HTML code of the infected page
HTML code of the infected page

Not surprising, the first two tags were html and head. To verify that we correctly identified the tags, we injected the URL generating piece of code into the browser’s console:

Evaluating exfiltration URL in the Web Developer Tools console
Evaluating exfiltration URL in the Web Developer Tools console

This simple trick confirmed our assumption and revealed the URL of the injected script: hxxps ://metahtmlhead[.]com/folder/ip/zxc.php (Full disclosure: we already had this URL after the initial analysis of the traffic generated by the infected website).

Magento Credit Card Stealer

When this investigation was over, our researcher Ben Martin found a seemingly unrelated skimmer in a database of a Magento 1.x site.

JavaScript skimmer found on a Magento 1.x site
JavaScript skimmer found on a Magento 1.x site

However, after removing the first layer of obfuscation, we found the very familiar structure with ​​”split,toString,join,length,charCodeAt,fromCharCode” and a decoding function that relies on the length of the initially encoded function.

Using the same brute force approach, we decoded it and found a similar skimmer code. However, this time the domain name obfuscation didn’t include any parts derived from the HTML DOM. The discovered exfiltration URL was: winsiott[.]com/folder/ip/stt.php . The URL structure domain/folder/ip/xxx.php fully matched the one found in the X-Cart skimmer.

PublicWWW shows a few more sites infected with variations of this skimmer (all with the winsiott[.]com/folder/ip/stt.php exfiltration URL). Sucuri SiteCheck detects them as “malware.magento_shoplift?199”.

Malware.magento_shoplift?199 skimmer detected by SiteCheck
Malware.magento_shoplift?199 skimmer detected by SiteCheck

Malicious Domains

The metahtmlhead[.]com domain was registered over three months ago on February 7, 2022 using Registrar.eu (not a typical registrar for skimmers). It is hosted on a server with the IP address 162.241.222 .226 (UNIFIEDLAYER-AS-1, US), which has a history of being used by phishers.

The winsiott[.]com domain was registered on June 7, 2021. It is hosted on a server with the IP 83.242.96 .149 (AHOST-AS, RU).

Conclusion & Mitigation Steps

Every e-commerce site is a potential target for bad actors trying to steal payment details, regardless of whether they’re using an ultra-popular CMS or a custom built solution. Less popular platforms usually attract more targeted attacks where hackers may employ more creative attack vectors and injected malware.

Websites that allow credit card transactions should take security very seriously — PCI compliance is mandatory for anyone who operates an e-commerce website, and the implication of a compromise affects not only the personal information and security of the site’s users but also the website’s ability to accept credit card payments. Site owners may even incur fines or penalties from regulators if customers complain about fraudulent transactions.

One of the most important things you can do to protect your website against credit card stealing malware is to follow the requirements outlined in the PCI-DSS. If you’re looking for a simple solution to meet the first requirement for PCI compliance, you can employ a Web Application Firewall (WAF) like the Sucuri Firewall.

You May Also Like

Sucuri Security Blog

After many suggestions, we decide to setup a blog to better communicate with our users. Expect updates from http://sucuri.net and some security-related posts from us.
Read More