November 20, 2018
Anomali Threat Research

Is Magecart Checking Out Your Secure Online Transactions?

<h2>With Online Holiday Sales Projected at $123B: How Secure are Your Transactions? </h2><p>There is a projected $123B in online purchases this holiday season, according to commerce site Millions of online transactions will occur between now and December 25th. How secure do you feel entering your credit or debit cards into the payment portals? We all get a sense of security with the HTTPS and the “secure transaction” wording in the check out carts, but does that offer 100% protection to the consumer.</p><p>Anomali Labs researchers have discovered web stores that have been compromised by an unknown threat actor, possibly Magecart, where the website has been modified to include JavaScript code that steals credit card information. The JavaScript code shows up in two forms, one that beacons out to and the other to The threat actor is using a form of typosquatting to camouflage the command and control (C2) domains by using domains similar to well-known domains such as google-analytics[.]com and The code has been present on the sites for approximately five months and has silently been siphoning off stolen credit card details. At the time of this writing, this campaign is currently ongoing. The compromised sites are small but high-end stores offering goods at a premium price.</p><p>The Magecart threat groups have been highly active in 2018, and they have been attributed to multiple data breaches and information-theft incidents. Some of these breaches affected large and well-known companies. In late June 2018, the ticket sales company Ticketmaster stated publicly that it had been compromised by threat actors. The threat actors turned out to be Magecart, according to RiskIQ researchers. Magecart targeted a Ticketmaster subdomain (hosted by third-party supplier Inbenta) and injected it with a JavaScript module, among other actions, to conduct payment skimming activity.<sup>1</sup> On September 6, 2018, British Airways confirmed that it had suffered a data breach in which a threat group (Magecart) stole payment information from the company’s main website and mobile application by using a modified “Modernizr JavaScript” library (version 2.6.2).<sup>2</sup> Another company attacked by Magecart was Newegg, who had its website compromised with a skimmer, similar to the one found in the British Airways incident, and sent the stolen data to an actor-registered domain (neweggstats[.]com, later changed to; the skimmer was located on Newegg’s payment processing page.<sup>3</sup> These campaigns offer some insight as to how Magecart operates, and it is with these tactics in mind that Anomali Labs researchers believe with medium confidence that this campaign is being conducted by a Magecart group.</p><p>Threat actors are consistently looking for ways to steal valuable information that can be sold for a profit or used illicitly to steal funds. One way an actor can accomplish this kind of malicious activity is via an SQL injection attack to gain unauthorized access to information stored in a database, however, this approach has some limitations. Foremost, it is only possible to steal the data from customers that have selected the option to store their payment information. Secondly, as per the Payment Card Industry Data Security Standard (PCI DSS), standard CVV values are not allowed to be stored. This standard makes it difficult for a threat actor to use the stolen credit card data because some merchants require the CVV to make a purchase. A way for a threat actor to get card data with an associated CVV number is by compromising the webstore and adding code to the checkout page to steal the information and send it off to the threat actor just before it is submitted to the server. For example, the threat actor can inject some HTML code to the page that loads malicious JavaScript from another server. The JavaScript waits for a particular request to occur, and once the correct event has fired, the code grabs the data that is about to be submitted to the store and sends it off to a server controlled by the threat actor. This type of compromise can be challenging to detect because it all occurs in the customer’s browser and not on computers controlled by the compromised company. Therefore, it is possible that the site stays compromised for months without detection.</p><h3>Compromised websites</h3><p>According to an internet-wide survey, Anomali Labs have detected at least 31 websites that have been compromised and served the malicious JavaScript as far as back as the 23rd of June, 2018. The sites were compromised to load JavaScript hosted on the domain “g-analytics[.]com”. The code injected looks very similar to legitimate Google Analytics code that is used to evade detection if a developer audits the code. Figure 1 shows the legitimate Google Analytics code on a compromised host and Figure 2 shows the injected malicious code.</p><p><img alt="Code snippet of legitimate Google Analytics on a compromised machine." src=""/></p><p><strong>Figure 1: Code snippet of legitimate Google Analytics on a compromised machine.</strong></p><p><img alt="Malicious code snippet impersonating Google Analytics on compromised machine." src=""/></p><p><strong>Figure 2: Malicious code snippet impersonating Google Analytics on the compromised machine.</strong></p><h3></h3><p>The domain “g-analytics[.]com” was registered at NameCheap on the 31st of May, 2018. The domain tries to impersonate the domain used by Google for serving Google Analytics (google-analytics[.]com). If a visitor navigates to the g-analytics[.]com site, he/she is redirected to the real Google Analytics site, making the domain appear more legitimate. The response header from the server is shown below:</p><p>HTTP/1.1 302 Moved Temporarily<br/> Server: nginx/1.6.2<br/> Date: Mon, 19 Nov 2018 10:55:59 GMT<br/> Content-Type: text/html; charset=UTF-8<br/> Connection: keep-alive<br/> Location:</p><p>The server is used to host JavaScript, “analytics.js”, that is served to visitors of the compromised sites. The threat actor has actively been updating the script file since June 2018 with new versions. The versions of the script and the last modified timestamp given by the server are shown in Table 1 below.</p><table class="table table-striped"><tbody><tr><td><strong>Version</strong></td><td><strong>Last Modified Timestamp</strong></td></tr><tr><td>1.0.1</td><td>Sat, 23 Jun 2018 02:47:00 GMT</td></tr><tr><td>1.0.3</td><td>Wed, 27 Jun 2018 04:25:33 GMT</td></tr><tr><td>1.0.4</td><td>Wed, 27 Jun 2018 11:06:48 GMT</td></tr><tr><td>1.0.5</td><td>Thu, 28 Jun 2018 17:25:25 GMT</td></tr><tr><td>1.0.6</td><td>Thu, 28 Jun 2018 15:11:47 GMT</td></tr><tr><td>1.0.7</td><td>Thu, 28 Jun 2018 16:03:46 GMT</td></tr><tr><td>1.0.8</td><td>Tue, 02 Oct 2018 13:59:59 GMT</td></tr><tr><td>1.0.9</td><td>Mon, 02 Jul 2018 06:51:07 GMT</td></tr><tr><td>1.0.10</td><td>Thu, 05 Jul 2018 05:29:44 GMT</td></tr><tr><td>1.0.11</td><td>Wed, 04 Jul 2018 15:41:58 GMT</td></tr><tr><td>1.0.12</td><td>Thu, 05 Jul 2018 07:43:21 GMT</td></tr><tr><td>1.0.13</td><td>Sat, 07 Jul 2018 12:27:40 GMT</td></tr><tr><td>1.0.14</td><td>Sat, 07 Jul 2018 03:58:37 GMT</td></tr><tr><td>1.0.15</td><td>Tue, 10 Jul 2018 09:44:23 GMT</td></tr><tr><td>1.0.16</td><td>Sat, 03 Nov 2018 16:00:19 GMT</td></tr><tr><td>1.0.17</td><td>Mon, 05 Nov 2018 11:02:11 GMT</td></tr><tr><td>1.0.18</td><td>Tue, 06 Nov 2018 14:30:54 GMT</td></tr><tr><td>1.0.19</td><td>Wed, 07 Nov 2018 13:02:37 GMT</td></tr><tr><td>1.0.20</td><td>Thu, 08 Nov 2018 04:23:06 GMT</td></tr><tr><td>1.0.21</td><td>Tue, 13 Nov 2018 14:14:21 GMT</td></tr><tr><td>1.0.22</td><td>Tue, 13 Nov 2018 14:05:59 GMT</td></tr><tr><td>1.0.23</td><td>Tue, 13 Nov 2018 14:04:30 GMT</td></tr><tr><td>1.0.24</td><td>Tue, 13 Nov 2018 13:35:32 GM</td></tr></tbody></table><p><strong>Table 1: Versions of analytic.js and their last modified timestamp is given by the server.</strong></p><h3>analytics.js</h3><p>“Analytics.js” is an obfuscated Javascript file that exfiltrates payment details from compromised websites with payment portals. The file pretends to be a “Google Analytics” file named “analytics.js”. Multiple different versions of this file have been observed.</p><p>Technical breakdown</p><p>The file is obfuscated by taking out all strings, and some function names and placing them inside an obfuscated string. The string is copied into a character array and subject to a number of decoding operations which dumps out a string array, as shown in Figure 3.</p><p><img alt="String array deobfuscation." src=""/></p><p><strong>Figure 3: String array deobfuscation.</strong></p><p>A number of helper functions are initialized and returned in an associative array to a variable named “GoogleAnalytics”. Another round of decoding on a large string is performed, which creates another string array for the obfuscated code. The file uses the popular JavaScript library “jQuery” to wait for a user to click a button that is under the element, class, or ID of the following:</p><ul><li>button</li><li>.form-button</li><li>.onestepcheckout-button</li><li>.btn</li><li>#onestepcheckout-place-order</li><li>.onestepcheckout-place-order</li><li>.onestepcheckout-place-order-wrapper</li></ul><p>The script grabs the URL and uses a regular expression test to ensure the page is either a login page or purchase related page by matching the pattern below. Figure 4 shows the check in the code.</p><p><img alt="Regular expression check." src=""/></p><p><strong>Figure 4: Regular expression check.</strong></p><p>If this test returns true, it uses the function “document.querySelectorAll()” in a loop to grab all the elements that are under the following selectors: input, select, textarea, checkbox.</p><p>It checks to see if there is any value input into the field. If a value is there, it grabs the “name” HTML attribute of the element. If there is no name attribute, the script will retrieve the count number of the loop that it is currently in to use as the name. This name is used to append to the end of a string in the following format:<br/> param_string += [element_name] + ‘=‘ + [element_value] + “&amp;”</p><p>The script will also save the value using HTML5 local storage, as shown in Figure 5.</p><p><img alt="Storing the value of all completed fields." src=""/></p><p><strong>Figure 5: Storing the value of all completed fields.</strong></p><p>It checks the local storage to see if it was able to obtain a field named “gaudid”. This is a unique identifier for the client that is shopping on the compromised website. If there is no ID number it will generate a unique ID for the victim, as shown in Figure 6.</p><p><strong><img alt="Unique ID check and generation." src=""/></strong></p><p><strong>Figure 6: Unique ID check and generation.</strong></p><p>The script then specifically looks for a local storage variable called “infoResult”. If found it will be prepended to the start of the exfiltrated data. The script begins to create its asynchronous HTTP POST request. It creates a regular expression with the following pattern to test for card numbers:<br/> [0-9]{13,16}</p><p>If the test returns true, it sets a flag in the exfiltrated data. The data is then encrypted and encoded with Base64. It is placed in the post data after the field “track”, as shown in Figure 7.</p><p><strong><img alt="Exfiltration of collected data to the C2." src=""/></strong></p><p><strong>Figure 7: Exfiltration of collected data to the C2.</strong></p><p>An example of scraped data before encryption is shown in Figure 8.</p><p><strong><img alt="Fetched fields before encryption." src=""/></strong></p><p><strong>Figure 8: Fetched fields before encryption.</strong></p><p>The POST request attempts to mimic the style of legitimate Google Analytics’s URL query parameters and request path. The similar request path can be seen in Figure 9. Also shown is the legitimate Google Analytics request. Note the difference in the method used and the protocol.</p><p><strong><img alt="Network requests showing both legitimate and fake Google Analytics requests." src=""/></strong></p><p><strong>Figure 9: Network requests showing both legitimate and fake Google Analytics requests.</strong></p><h3></h3><p>The domain “jquery-js[.]com” was registered on NameCheap on the 2nd of January, 2017. It similar to g-analytics[.]com in the way that it is impersonating a legitimate site. Users browsing to the site are redirected to the legitimate site for jquery as can be seen below.</p><p>HTTP/1.1 302 Moved Temporarily<br/> Server: nginx/1.6.2<br/> Date: Tue, 20 Nov 2018 09:57:45 GMT<br/> Content-Type: text/html; charset=UTF-8<br/> Connection: keep-alive<br/> Location:</p><p>The domain is used to host the JavaScript file “jquery.min.js”. According to data provided by the web server, the file was last modified on the 7th of January, 2017.</p><h3>jquery-min.js</h3><p>“jquery-min.js” is an obfuscated Javascript file that operates in a similar way to “analytics.js”. Skimming payment details from compromised websites with payment portals. The file pretends to be a “jQuery” file.</p><h3>Technical breakdown</h3><p>The file is heavily obfuscated JavaScript that pretends to be a minified jQuery file. The script has a large comment block at the start of the file that is code from the legitimate version of jQuery. This is intended to hide the malicious code appended below it, as shown in Figure 10.</p><p><strong><img alt="Malicious file with comment block mimicking jQuery." src=""/></strong></p><p><strong>Figure 10: Malicious file with comment block mimicking jQuery.</strong></p><p>The script decodes and evaluates a large string that contains more JavaScript code. After the first round of decoding the following script is evaluated, Figure 11.</p><p><strong><img alt="Second decoding script." src=""/></strong></p><p><strong>Figure 11: Second decoding script.</strong></p><p>This script decodes and evaluates another string, which is the final malicious script, that performs skimming of shopper details. The malicious script and its deobfuscated version are shown in Figures 12 &amp; 13.</p><p><strong><img alt="Malicious skimming script." src=""/></strong></p><p><strong>Figure 12: Malicious skimming script.</strong></p><p><strong><img alt="Deobfuscated version of the script." src=""/></strong></p><p><strong>Figure 13: Deobfuscated version of the script.</strong></p><p>The script acts much in the same way as “analytics.js”. It will check that the user is on a payment page and scrape all values filled into input elements in the form. The data is sent to the C2 server over asynchronous HTTP POST in plaintext.</p><h3>Recommendations</h3><p>If you have bought something from these sites, consider canceling your credit or bank card and request a new issued from your credit card company and carefully monitor your transactions list for potentially malicious activity. Paying via a trusted third-party application, such as Apple/Google Pay, PayPal, Visa Checkout, can reduce the likelihood of your banking and payment information being stolen with this malicious script. Making payments through a third-party portal reduces the likelihood of inputted card details being scraped from the form of the compromised site.</p><h3>Indicators of Compromise</h3><p><strong>File </strong><strong>hashes</strong></p><table class="table table-striped"><tbody><tr><td><strong>File</strong></td><td><strong>SHA1</strong></td><td><strong>SHA256</strong></td><td><strong>MD5</strong></td></tr><tr><td>analytics-1.0.1.js</td><td style="word-break: break-all">d79aae3a361af9811c46a2cfdf64d59d3126de7d</td><td style="word-break: break-all">69fd11ffde20274f419b1126136ab001744600ef67f77c31750826077115ce33</td><td style="word-break: break-all">434a1c9e65d68138666f86fbe2c630ff</td></tr><tr><td>analytics-1.0.3.js</td><td style="word-break: break-all">4b348d4e99f921212aa37194020d2f4679c94755</td><td style="word-break: break-all">fc0fce7dfa5e5ead859be43469c2a8719f5c737df0d10dba94dfe5291fe04b4c</td><td style="word-break: break-all">967f7722009eae576a7af1626eb43955</td></tr><tr><td>analytics-1.0.4.js</td><td style="word-break: break-all">e4b58187282f2ae83a6f5f35f865d67163ff8bc5</td><td style="word-break: break-all">e54f23482b47bfc7f8dc7097b556e32644edc72996ea987dbe916eade48dccdf</td><td style="word-break: break-all">46e0ac454f6dfb8c6436139c076df774</td></tr><tr><td>analytics-1.0.5.js</td><td style="word-break: break-all">b7aa002e664e2a3ed76d2fe15c87bb43b9cbfa34</td><td style="word-break: break-all">bd1a1f2239eae87734d5eb8ffbea3bc343aca69373c860de1e46fe9689cfd70a</td><td style="word-break: break-all">50321d8f0d0d9a44465995251bef98a1</td></tr><tr><td>analytics-1.0.6.js</td><td style="word-break: break-all">0cc414e41fa0094c722f80010a3d413d05a5b42f</td><td style="word-break: break-all">c64adf966f5ebf7600ee6593ee391f02bfd14aec12e541357461b8bb1e156775</td><td style="word-break: break-all">ad60c1ccb84e81e2f77b503054261920</td></tr><tr><td>analytics-1.0.7.js</td><td style="word-break: break-all">86a0562d82c05460dc62898e9888b73eee4eb05f</td><td style="word-break: break-all">4de6c8209ba6e643ad1b773c2c12e910005b4dad9c09f6ed76a238ce089d8efb</td><td style="word-break: break-all">180d903f47e3c7baa65825f65e09bca0</td></tr><tr><td>analytics-1.0.8.js</td><td style="word-break: break-all">06ee6c14eb7fe625ae543a93f4ad86e7794f23fa</td><td style="word-break: break-all">02f1dc790c68ace0cf1fa5cfba6a72d9b84ea60d19196bef686d47b53bf42d80</td><td style="word-break: break-all">0a4db14c632a6dfb66bd53c2c3efbf0b</td></tr><tr><td>analytics-1.0.9.js</td><td style="word-break: break-all">f64d79c1ed4b7a96d763d0a19a7508bbbda25a5c</td><td style="word-break: break-all">be5c2e3a9fb3c605e7f4a2d80bb295bc6f1f7520a601014998ecbb4ac8d25da7</td><td style="word-break: break-all">57a65a522efbc2d339de3c6fd89bdaa7</td></tr><tr><td>analytics-1.0.10.js</td><td style="word-break: break-all">4c0576e7592c879a0a79c1e0df174572726a0c62</td><td style="word-break: break-all">957b45bf311166cd5730886f1b64028f23c758d700bb2be09aea57c293f84398</td><td style="word-break: break-all">2ae7c73badcffa20d7ff999a809a9e5c</td></tr><tr><td>analytics-1.0.11.js</td><td style="word-break: break-all">445f2ddab06bdf74b28585e810ae1a8ad439bc63</td><td style="word-break: break-all">a119c43f4bf93333959a33f6f5b731fd9040e277299e269a3d60c45d66df2112</td><td style="word-break: break-all">db0cb908da4723a290478160d3b855d4</td></tr><tr><td>analytics-1.0.12.js</td><td style="word-break: break-all">d7e870968fb87b4028c508d70ea0d2dd0d074aa9</td><td style="word-break: break-all">dd36d5d47ae45ea94123e447a95c9cba442b1bb43f84074e23549b29413cada8</td><td style="word-break: break-all">5f56c50b6d537fef6762ef8899ecff51</td></tr><tr><td>analytics-1.0.13.js</td><td style="word-break: break-all">f9da3210b6d7736fe5f7268c69ca8f60fda9c59d</td><td style="word-break: break-all">7da0cadd9477cf94f419a81c767c5d4b889139b870e63534e95d1593592bcd0f</td><td style="word-break: break-all">5889b1826a45e10010e68cfe70eacdd4</td></tr><tr><td>analytics-1.0.14.js</td><td style="word-break: break-all">355cb0ad31ed0d915250681e97a8b60f245fd7e3</td><td style="word-break: break-all">1eb0b4d0e7e0be23ae1184dc5f5fdb0db64a97f4f350d7e5efe7d5aebace015a</td><td style="word-break: break-all">f884178d47d05be4abfa8ff81895dfcc</td></tr><tr><td>analytics-1.0.15.js</td><td style="word-break: break-all">a6fd0f6a631c5089dfc97ce0558774cdec3c5416</td><td style="word-break: break-all">ba4909955cf17789e53580ad189725cf02771d0575d899eb436c3973647ff271</td><td style="word-break: break-all">9cb61c81cd71d33a84e33f8ee3b81fc9</td></tr><tr><td>analytics-1.0.16.js</td><td style="word-break: break-all">d28466d9be30a068035371b2e2a6cc0a2db33b92</td><td style="word-break: break-all">ff0079df61707bc5184c7c299e00695e7ca0e973b708c2affa0f6a28a5b4a866</td><td style="word-break: break-all">4c1526a9d34b3e89ca238d6dbaacee81</td></tr><tr><td>analytics-1.0.17.js</td><td style="word-break: break-all">059f9ed9041795956a9a17ef38842c8dd9279339</td><td style="word-break: break-all">b2b20a983a9d9cfa017d0766139eca1e524137e60db9d431ecbee0a237d54aca</td><td style="word-break: break-all">fe59f6f0d088e07177361c773cd807ba</td></tr><tr><td>analytics-1.0.18.js</td><td style="word-break: break-all">25ecc3fdfe0e9914217ad284b8d49a2c61420bbf</td><td style="word-break: break-all">f65e22f893e08cada99f31be5dcce2deb6685df5ba929ce5558df2a28a8333e4</td><td style="word-break: break-all">787d1d1733a70e5107f414f9b1e7868d</td></tr><tr><td>analytics-1.0.19.js</td><td style="word-break: break-all">848d3b1b78d0a69f329fd86a7895f0d1c83f5a5e</td><td style="word-break: break-all">f88d99661dde2aaed0221d3684d6c6fa50f8b91413568e290ea71d3f8012cb28</td><td style="word-break: break-all">568edce319520bf9fac7151fc4f0138b</td></tr><tr><td>analytics-1.0.20.js</td><td style="word-break: break-all">051459e1f8f14beed79ad297edc79afc2dcb0fab</td><td style="word-break: break-all">52ecec641a9a0f157f181b2a6bc7b62c2fbafb95f97e9096130312cd9858cc28</td><td style="word-break: break-all">52f1ab47408c523e91ffe4aae2f1b9ea</td></tr><tr><td>analytics-1.0.21.js</td><td style="word-break: break-all">dbc75abb41f4112a716ffef9520e3f454e3d4d5b</td><td style="word-break: break-all">aff54f029566038581f65dcde5940fce96e6b98665071ea49b3cd803d3441d93</td><td style="word-break: break-all">f40ed59e2a32393a75f05766973c507d</td></tr><tr><td>analytics-1.0.22.js</td><td style="word-break: break-all">dbc75abb41f4112a716ffef9520e3f454e3d4d5b</td><td style="word-break: break-all">aff54f029566038581f65dcde5940fce96e6b98665071ea49b3cd803d3441d93</td><td style="word-break: break-all">f40ed59e2a32393a75f05766973c507d</td></tr><tr><td>analytics-1.0.24.js</td><td style="word-break: break-all">dbc75abb41f4112a716ffef9520e3f454e3d4d5b</td><td style="word-break: break-all">02f1dc790c68ace0cf1fa5cfba6a72d9b84ea60d19196bef686d47b53bf42d80</td><td style="word-break: break-all">f40ed59e2a32393a75f05766973c507d</td></tr><tr><td>jquery-min.js</td><td style="word-break: break-all">e4f118c3f4c44129c50f2e5889447b5618b88604</td><td style="word-break: break-all">7809510b73475f418a95a4633b4b6b71a7bafba2322d5a5756537e02fe1518e5</td><td style="word-break: break-all">98ceaced3fa4c06ad48c8eb52352d528</td></tr></tbody></table><p><strong>URLS</strong><br/> jquery-js[.]com/latest/jquery.min.js</p><p>g-analytics[.]com/__utm.gif?v=1&amp;_v=j68&amp;a=98811130&amp;t=pageview&amp;_s=1&amp;sd=24-bit&amp;sr=2560x1440&amp;vp=2145x371&amp;je=0&amp;_u=AACAAEAB~&amp;jid=1841704724&amp;gjid=877686936&amp;cid=1283183910.1527732071</p><p><strong>Domains</strong><br/> jquery-js[.]com<br/> g-analytics[.]com</p><p><strong>IP</strong><br/> 185.82.200[.]87</p><p>__________________________________</p><p><sup>1</sup>Yonothan Klijnsma and Jordan Herman, “Inside and Beyond Ticketmaster: The Many Breaches of Magecart,” RiskIQ, accessed November 19, 2018, published July 9, 2018,<br/> <sup>2</sup>Yonathan Klijnsma, “Inside the Magecart Breach of British Airways: How 22 Lines of Code Claimed 380,000 Victims,” RiskIQ, accessed November 19, 2018, published September 11, 2018,<br/> <sup>3</sup>Yonathan Klijnsma, “Another Victim of the Magecart Assault Emerges, Newegg,” RiskIQ, accessed November 19, 2018, published September 19, 2018,</p>

Get the Latest Anomali Updates and Cybersecurity News – Straight To Your Inbox

Become a subscriber to the Anomali Newsletter
Receive a monthly summary of our latest threat intelligence content, research, news, events, and more.