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.
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.
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:
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:
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:
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.
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”.
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.