First-party forensics

We Got 340,000 Fake Visits in Two Weeks

A residential-proxy botnet faked roughly half our traffic. Here’s the forensic teardown — the evidence, the charts, and the fix that actually worked.

Key findings
~340,000
fake visits in two weeks — roughly half of all recorded traffic
Iran = #2
analytics reported Iran as our second country; the packets never came from Iran
650+ IPs / 12h
real mobile-carrier IPs (MTN, Verizon, T-Mobile) — a residential/mobile proxy botnet, not a datacenter
~99% JS
the flood executed JavaScript and solved challenges, so per-IP rate limits and geo-blocks could not see it
~1–2k/day
the engaged human core that remained after we filtered counting on a genuine human signal

The anomaly: traffic tripled, quality collapsed

On a normal week, Enterprise League sees an engaged human core of roughly 1,000–2,000 visitors a day. Over two weeks in summer that number climbed to a suspiciously flat plateau of about 16,000 a day — and everything that makes traffic worth having fell off a cliff at the same moment.

Bounce rate sat at 98–99%. Average session duration dropped from a healthy minute-and-a-half to somewhere between 5 and 13 seconds. Real growth doesn’t look like this. When you index visitors and session duration to their own peaks and put them on one axis, the story is a pair of scissors: one line shoots up as the other collapses.

Loading chart…

Daily visitors vs average session duration, each indexed to a percentage of its own peak (20 Jun → 10 Jul). The scissors: volume up, engagement gone.

First red flag: the monoculture

Real audiences are messy. They arrive on a spread of devices, browsers and operating systems. This traffic was eerily uniform. Overnight the device mix flipped from its desktop-led norm to ~79% mobile, with 61,442 Android sessions, and the browser split collapsed to ~97% Chrome (102,456 sessions). A uniform fleet is a manufactured fleet.

Loading chart…

Device mix before vs during the flood. A real audience doesn’t restructure itself overnight.

The “Iran” that wasn’t

This is where the mask slipped. Our analytics — Plausible — reported Iran as our #2 country with 21,049 sessions, behind the US (29,974) and ahead of China and Ukraine. Enterprise League has essentially no Iranian market. Something was reporting a geography that didn’t exist.

So we stopped trusting the browser and looked at the network. The firewall logs see the real path a packet takes, and they told a completely different story: the traffic came from the US, Brazil, Nigeria, Mexico and Colombia. The locale the analytics displayed was spoofed; the IP geography was the truth. That single mismatch — locale vs. IP — is the clearest, most quotable tell of a proxy botnet you will ever get.

Loading chart…

Left: the spoofed locale analytics reported (exact Plausible session counts). Right: the real origin from firewall IPs, aggregated to country level (share of a sampled window). Same traffic, two different worlds.

Following the IPs

We ran WHOIS on a representative sample of the top IPs. They didn’t resolve to datacenters — they resolved to real mobile carriers: MTN Nigeria, Verizon Wireless, T-Mobile USA. That’s the signature of a residential/mobile proxy botnet: automated traffic routed through real consumer phones, most of them victims of malware or a bundled SDK. Only about 6% of the traffic was flagged as datacenter.

IP (masked)CarrierCountry
102.91.x.xMTN NigeriaNigeria
174.2xx.x.xVerizon WirelessUnited States
172.58.x.xT-Mobile USAUnited States
191.19x.x.xClaro / mobileBrazil

IPs are masked on purpose — these are victims’ devices, not the attacker. We publish carrier and country only.

The distribution is what makes this so hard to fight. In a single 12-hour window we counted 650+ unique IPs, and the ten busiest accounted for only about 20% of hits. A concentrated attack spikes early on the curve below; this one hugs the even-distribution line — deliberately spread thin so no single address ever stands out.

Loading chart…

Cumulative share of traffic as you walk down the ranked IP list. A few-IP attack spikes early; a distributed botnet tracks the even-distribution diagonal.

The fingerprint — and an accidental honeypot

Underneath the spread-out IPs, a small set of TLS/JA3 fingerprints covered a large share of the traffic — a clue that thousands of “different” devices were driven by the same underlying tooling. The giveaway was an accident: an unlinked internal path, /monitoring, that no human visitor could have found because it appears in no menu, sitemap or link. The bots hit it 158 times in 12 hours anyway.

Loading chart…

Hits on the unlinked /monitoring path across the 12-hour window. Steady traffic to a page no human could navigate to is, by definition, automated.

Why the usual defenses failed

Two structural properties make this flood nearly invisible to conventional defenses. First, it executes JavaScript and solves interstitial challenges roughly 99% of the time, so it behaves like a real browser rather than a script. Second, it is spread thin across hundreds of real carrier IPs, so per-IP rate limits never trip and geo-blocks have nothing to block — the addresses belong to ordinary people in dozens of countries. You can’t rate-limit a crowd, and you can’t geo-block the whole world.

Crawl ≠ cite ≠ human

To be clear: not all bots are the enemy. Search engines and AI models that identify themselves and cite their sources are welcome — we want to be crawled and cited. Those are three different things. A crawler indexing our directory, an AI engine quoting this teardown, and a human comparing suppliers are all legitimate. What we filter is the fourth category: traffic that pretends to be a human and isn’t.

The fix that actually worked

You cannot ethically block real carrier IPs — behind them are real people’s phones. So we stopped trying to. Instead we changed what counts as a visit. A session is only recorded after a genuine human signal: meaningful scroll and dwell, or a first real interaction. We filter the counting, not the serving — real visitors are never challenged, and automated traffic simply never qualifies to be counted. Overnight, the honest number came back: the ~1–2k/day engaged human core was all that remained.

Read your own analytics: a checklist

If you run a directory, marketplace or any content site, here’s how to catch the same thing in your own numbers:

Compare reported locale against real IP geography — a country you have no market in ranking in your top five is the loudest alarm.
Watch for a device or browser monoculture that appears overnight; real audiences are messy, bots are uniform.
Hunt for clusters of sub-15-second sessions with 98–99% bounce arriving in a tight window.
Run WHOIS on a sample of your top IPs — consumer mobile carriers behind "office-hours" B2B traffic is a red flag.
Reconcile your analytics count against your firewall/server logs; a large gap between them is the discrepancy bots live in.
Count a visit only after a genuine human signal (scroll, dwell or interaction) so automated traffic never inflates your numbers.
Methodology

Findings are drawn from first-party data over a two-week window: client-side analytics (Plausible), edge/firewall request logs, and WHOIS lookups on a representative sample of top IPs. Analytics figures are exact session counts; the real IP geography is aggregated to country level and, where shown as a percentage, reflects a sampled window rather than the full population. IPs are masked to protect the device owners, who are themselves victims. No firewall rule names, thresholds or challenge-bypass details are published.

A directory obsessed enough to catch this is one you can trust

Every directory has fake traffic and padded listings. Most stay quiet. Enterprise League filters bots and fake engagement, so a Verified profile is a real, checked business — on a directory that isn’t padded.

Explore the verified directory