Anatomy of a WooCommerce Skimmer: A Technical Deep-Dive

speckx1 pts0 comments

Anatomy of a WooCommerce Skimmer: A Technical Deep-Dive

Sponsored by: Report URI - Detect JavaScript tampering with our new CSP Integrity feature. Get started for free!

One malicious change to a trusted JavaScript file can turn your checkout page into a silent credit-card skimmer, siphoning customer data off to criminals while the website looks secure and continues to work as normal. That creates serious organisational risk: PCI exposure, regulatory consequences, reputational damage, and a breach that remains invisible until long after the damage is done.<br>We recently became aware of exactly this kind of compromise, where an attacker modified a JavaScript file on disk and injected malware into it. At first glance, that might seem like an unusual choice. If an attacker has enough access to modify files on the server, why settle for injecting JavaScript into an existing library?<br>In this case, there’s a very good reason: the data they wanted to steal only existed in the browser, so that's where their malicious code needed to run.

An unusual choice<br>If I'd found a way to compromise a host to the point where I could modify files on disk, I'm not sure that injecting JavaScript malware into an existing file would be my first choice when it came to deciding my course of action. Yet, here we are!<br>Looking at the website in question, my best guess would be a vulnerable WordPress plugin has allowed some level of remote access to the attackers and they've leveraged that to modify an existing JS file. The compromised file was an existing and legitimate JS library, and the malware was injected at the start of the file, leaving the original library code intact later in the file. This is a common tactic aimed at reducing the disruption the injection causes as all original functionality remains, reducing the likelihood of being discovered.

Given that their goal was clearly to skim payment card data, it also explains why their chosen course of action was to modify an existing JS asset rather than leverage much more powerful server-side access: The payment card data doesn't exist on the server, only on the client, so that's where they have to target it!

Evasion and Anti-Detection Techniques<br>Rather than add their own file to the page and load the malware in that way, the attackers inserted their code in an existing file, and did so in a way that would not interrupt how it worked. The injected code uses a rotating string array with RC4 encryption and per-call decryption keys (the same technique used by<br>professional JavaScript obfuscation products!), and a reversed, base64-encoded C2 URL:<br>c3cvbW9jLm5kYy10c2V1cWVyLy86c3N3<br>sw/moc.ndc-tseuqer//:ssw<br>wss://request-cdn.com/ws<br>On top of this, after the malicious code establishes its WebSocket connection, it then removes itself to avoid detection.

Data Theft<br>Looking at the code and the fields on the page that it targets, it's pretty clear it's specifically designed for WooCommerce checkouts. The CSS selectors include every standard checkout field like #billing_, #shipping_, etc... Not only is it targeting specific fields, the skimmer isn't just blindly exfiltrating data, it's doing validation on the data before it exfiltrates it. For the card number, it's using the Luhn Algorithm to check that it's a valid card number, and it's also validating that the expiry date is a date in the future too!<br>On top of the desirable card data, it's also capturing other identity data that is present alongside the card data. This potentially includes your email address, phone number, full address including street/city/postcode/country, your browser UA and the hostname of the site. The code polls these fields in a loop every 500ms, presumably to catch autofill, paste, or JS-set values that don't trigger input or change events, but also progressively captures the data as you're typing, meaning it doesn't rely on an action like form submission for the exfiltration of complete data to happen. If you type in all of your card details and then have second thoughts about your purchase, it's already too late!<br>The final point that stood out to me is that the skimmer keeps a local record of card data that's already been stolen in localStorage, so if you were to return to the site and make another purchase using the same payment card, the skimmer wouldn't steal it a second time. How nice of them.

Data Exfiltration Mechanism<br>Once the skimmer has identified some data that passes local validation and it wants to exfiltrate that data, it does so via a WebSocket over TLS. The data is sent to wss://request-cdn.com/ws in real-time using a simple JSON payload.

"method": "data",<br>"host": "victim-site.com",<br>"data": "*card data here*"<br>Although TLS protects the transmission itself, any security tool terminating and inspecting outbound TLS could still spot payment card data leaving the browser. To avoid this, the malware hides the card data by encrypting it with AES-256-GCM using a PBKDF2-derived key (100,000 iterations,...

data card file skimmer code javascript

Related Articles