# Smart Contract C2: Skimmers That Rotate Without Being Touched

Skimmers that read their next-stage host out of a blockchain contract, so the operator can move infrastructure without ever going back into the sites they compromised.

Provenance: Corroborated by external research.
Published: 2026-07-28. Updated: 2026-08-24.

Blocking a skimmer's C2 host used to stick. The address was baked into the injected script, so if
you took the host down the attacker had to get back into every site they'd compromised to point the
code somewhere new.

This gets rid of that cost. The injected code carries a contract address instead of a hostname,
queries the chain when it runs, and gets back wherever the attacker currently wants the next stage
fetched from. Moving infrastructure is one transaction, and every compromised site follows along.

## Two chains, two campaigns

One Magecart dropper we track queries a Polygon contract to resolve the hosts serving its skimmer
JavaScript. The compromised sites in that campaign are largely WordPress and WooCommerce, and the
resolved hosts are named to read like plugin or payment infrastructure so they survive a glance at
a script list.

A separate ClickFix chain reads its next stage out of a BNB Chain testnet contract. Testnet is a
deliberate choice: it carries no real transaction value, so it attracts none of the monitoring that
mainnet activity does, while working identically as a key-value store the operator controls.

## Why file monitoring goes quiet

That ClickFix chain rotated to a third staging host four days into the campaign. The compromised
site was not touched. Anything watching the site's own files for change saw one injection and then
a flat line, while the host actually serving the payload moved twice.

That's where integrity monitoring falls down here. It answers "has this file changed", and the
answer stays no the whole time the attack is developing. The thing that's moving is the
destination, and the only place you can see that is the browser.

## Why takedown loses its edge

The usual response to a C2 host is to get it taken down. You report it to the registrar or the
host, the domain stops resolving, and every deployment of that skimmer breaks at the same time.
It's slow, but it works, and the maths is on your side: one action, every victim.

A contract-resolved chain breaks that. You can still take the domain down and it's still worth
doing, but recovering from it costs the attacker one transaction instead of breaking back into
every site they hold. The imbalance that made takedowns worthwhile has gone.

The contract isn't something you can take down the way you can a domain. No registrar or host can
withdraw public chain state, and there's no company behind a testnet contract to lean on. Reading it
costs the attacker nothing and needs no infrastructure of their own that anyone could seize.

So you're left with the two things that were always the real work: block the destinations it
resolves to, so the current stage fails, and find the injection point, so the page stops asking the
question at all.

## What this means for your allowlist

When a policy blocks something, the instinct is to look at what got blocked and decide whether it
belongs. That works fine when the destination stays put. Here it gives you a policy that grows a new
entry every time the attacker rotates, each one added by somebody looking at a single host on its
own.

It's better the other way round. Work out what your payment page legitimately needs to talk to,
allow exactly that, and refuse everything else whether or not it looks reasonable. Then rotating
gains the attacker nothing: the second host gets refused like the first, and so does the third,
without anybody having to recognise either of them.

It's also what stops the reports turning into noise. A violation stops being a question about one
host and becomes a signal that something on your page is trying to reach outside what you allowed.

## What to look for

Watch for a script or connection to an unfamiliar host appearing without any corresponding change
to your own pages. That combination — your files identical, the reported destination different from
last week — is close to diagnostic for a contract-resolved chain, and it is only observable from
telemetry the browser sends you.

The rotation is the strongest signal you'll get. One unfamiliar host could be anything. Several of
them, arriving over days, on the same page, with your own files unchanged the whole time, is not
ambiguous at all. If your reporting lets you watch one host appear and another drop away across a
week, that sequence tells you more than any single violation in it.

## Indicators

- *.cloudfrontenterprise.com
- *.dntds.shop
- *.sdntds.shop
- *.woocompay.com
- *.wpguarding.com

## Questions

### How does a smart contract help an attacker hide?

The injected code holds a contract address instead of a hostname, and asks the contract at runtime where to fetch the next stage. The attacker can point it at new infrastructure whenever they want, and every compromised site follows without any of them being touched again.

### Why does this defeat file integrity monitoring?

Because the file on the compromised site never changes. Monitoring that alerts when a script is modified sees one change, at injection time, and nothing after that while the payload host moves around underneath it.

### Can the contract be taken down?

Not the way a domain can. No registrar or host can remove public chain state, so what you're left with is blocking the destinations it resolves to and finding the injection point.

### What does this look like in CSP reports?

A connection or script load to a host you never allowed, turning up without any matching change on your own pages. If the reported host keeps changing while your files stay identical, that pattern is the signal.
