TI-2026-046A โ The .env Harvesters โ Google Cloud Credential Scanning Fleet
๐ Series: The Web Siege
Letter A of The Web Siege โ a forensic series documenting the multi-vector attacks observed at our Traefik ingress layer during June 2026.
Unlike our previous honeypot dossiers โ which captured SSH brute-force operators, Outlaw botnets, and IRC-controlled cryptominers โ this series shifts the lens to the HTTP attack surface. The layer where every web application lives. The layer where a single misconfigured deployment can expose database credentials, API keys, payment tokens, and the keys to entire cloud infrastructures.
What we found was not random noise. It was an economy.
Data source: 87,883 requests from 4,446 unique IPs captured by our Traefik reverse proxy โ Loki log aggregation โ web_threats PostgreSQL pipeline over 25 days. Cross-referenced with SSH honeypot (threat_intel DB, 8,000+ IPs), CrowdSec threat intelligence, MikroTik address lists, and entity crosslinks (Qdrant vector store, 15,392 relationship edges).
โ ๏ธ Why This Matters: The .env File Problem
Before we show you the attack, you need to understand the target.
A .env file is the standard way modern web applications store their secrets. Every Laravel app, every Node.js API, every React frontend that talks to a backend โ they all use .env files to hold the credentials that make everything work. Database passwords. AWS keys. Stripe payment tokens. JWT signing secrets.
The security model is simple: the .env file should never be accessible via the web. Your .gitignore excludes it from version control. Your web server should refuse to serve it. In theory.
In practice? Developers make mistakes. A misconfigured Nginx. A Docker build that copies the entire project root into the public directory. A .env.bak file created during debugging and forgotten. A staging server with directory listing enabled.
The attackers in this dossier know this. They don't need to exploit a vulnerability. They don't need a zero-day. They just need one misconfigured server out of the millions they scan. And when they find it, they get everything.
๐ฏ The Signal
Beginning June 8, 2026, our automated campaign detection algorithm flagged something unusual.
It wasn't a single scanner. It wasn't the background radiation of the internet. It was coordinated: 5-12 Google Cloud Platform IPs appearing within minutes of each other, all requesting the same exhaustive list of .env path variants, then vanishing. Forever. The next day, entirely new IPs. Same behavior. Same paths. Same ASN.
Jun 08 14:23:17 traefik GET /.env 34.129.126.223 โ 404 [AS396982] Jun 08 14:23:17 traefik GET /.env.local 34.118.27.145 โ 404 [AS396982] Jun 08 14:23:18 traefik GET /.env.production 34.176.151.233 โ 404 [AS396982] Jun 08 14:23:18 traefik GET /laravel/.env 34.125.48.170 โ 404 [AS396982] Jun 08 14:23:18 traefik GET /app/.env 34.151.74.196 โ 404 [AS396982] Jun 08 14:23:19 traefik GET /.env.backup 34.104.178.132 โ 404 [AS396982] Jun 08 14:23:19 traefik GET /backend/.env 136.110.87.228 โ 404 [AS396982] Jun 08 14:23:19 traefik GET /.env.bak 136.110.77.61 โ 404 [AS396982]
All 404s. Our infrastructure returned nothing. But the pattern told us everything about the attacker.
7 campaigns. 54 unique IPs. Zero reuse. Someone was burning through Google Cloud instances like matchsticks โ and they'd been doing it for three weeks before we even noticed.
๐ Campaign Timeline: 19 Days of Daily Deployments
Each row represents a single day's operation. The operator spins up fresh infrastructure, runs the scan, and destroys the evidence. By the time any blacklist updates, the IPs are already gone.
| Date | IPs Deployed | Total Requests | Detection Method | Avg Requests/IP |
|---|---|---|---|---|
| June 8 | 8 | 1,203 | temporal_burst | 150 |
| June 9 | 9 | 1,634 | temporal_burst | 182 |
| June 10 | 6 | 722 | temporal_burst | 120 |
| June 11 | 12 | 1,054 | temporal_burst | 88 |
| June 13 | 7 | 647 | temporal_burst | 92 |
| June 15 | 7 | 592 | temporal_burst | 85 |
| June 26 | 5 | 461 | temporal_burst | 92 |
| TOTAL | 54 | 6,313 | All AS396982 (Google Cloud Platform) | |
Detection method: temporal_burst โ our algorithm flags when โฅ5 IPs from the same ASN appear targeting identical path patterns within a 1-hour window. Each of these 7 campaigns triggered the detector independently. Note the gap: June 12, 14, 16-25 show no activity โ either the operator took weekends off, or they were scanning other targets during those periods.
๐ The Enumeration Wordlist: A Professional's Toolkit
This is not a script-kiddie's wordlist downloaded from GitHub. This is compiled operational intelligence โ a carefully curated enumeration covering every major web framework's .env convention, plus the backup patterns that lazy developers create:
| Path | Unique IPs | Total Hits | What It Targets |
|---|---|---|---|
/.env | 270 | 533 | Universal โ every framework uses this |
/.env.local | 168 | 265 | Local overrides (React, Vue, Laravel) |
/.env.production | 163 | 262 | ๐ฏ Production credentials โ the jackpot |
/.env.development | 151 | 240 | Dev credentials (often less secured) |
/.env.bak | 150 | 258 | Backup made during "quick fix" |
/api/.env | 148 | 221 | API subdirectory deployment |
/.env.backup | 147 | 237 | Explicit backup file |
/backend/.env | 145 | 215 | Monorepo: frontend/backend split |
/app/.env | 138 | 210 | Node.js / Express.js convention |
/.env.old | 134 | 206 | Renamed during migration, never deleted |
/.env.test | 130 | 204 | Test env (often has real DB creds) |
/.env.save | 129 | 208 | Editor auto-save backup |
/.env.staging | 121 | 192 | Staging environment credentials |
/src/.env | 104 | 160 | Create React App / Next.js source dir |
/laravel/.env | 102 | 160 | Laravel PHP (most common PHP framework) |
/.env~ | 95 | 137 | Vim swap / Emacs backup file |
/.env.example | 78 | 102 | Template โ sometimes devs fill with real values |
/admin/.env | 62 | 84 | Admin panel credentials |
/.env.dist | 65 | 87 | Symfony distribution template |
/api/v1/.env | 59 | 63 | Versioned API path |
What this wordlist tells us about the operator:
- They know Laravel, Express, React, Vue, Django, Symfony, Rails, and Docker directory conventions
- They target backup artifacts (.bak, .old, .save, ~) โ demonstrating awareness that developers rename files instead of deleting them
- They check environment-specific variants (.production, .staging, .development) โ knowing these often contain the most sensitive credentials
- They probe monorepo structures (/backend/, /api/, /server/, /src/) โ modern architecture awareness
- This wordlist is the product of operational experience, not theoretical knowledge. Someone built this by analyzing which paths actually return results across thousands of targets.
๐ The Rotation Pattern: Burn After Use
This is the operational signature that elevates this from "noisy scanner" to "professional operation":
Every single IP was used for exactly one day. Not approximately one day. Exactly.
| IP Address | First Seen | Last Seen | Requests | Days Active |
|---|---|---|---|---|
34.129.126.223 | Jun 8 | Jun 8 | 148 | 1 |
34.118.27.145 | Jun 8 | Jun 8 | 151 | 1 |
34.176.151.233 | Jun 8 | Jun 8 | 149 | 1 |
34.64.101.40 | Jun 9 | Jun 9 | 141 | 1 |
34.18.106.202 | Jun 9 | Jun 9 | 257 | 1 |
34.17.89.110 | Jun 9 | Jun 9 | 233 | 1 |
34.80.185.229 | Jun 10 | Jun 10 | 147 | 1 |
35.199.99.193 | Jun 10 | Jun 10 | 150 | 1 |
34.72.49.107 | Jun 11 | Jun 11 | 91 | 1 |
136.110.87.228 | Jun 8 | Jun 8 | 151 | 1 |
54 IPs. 54 single-day lifespans. Zero reuse across the entire 19-day observation window.
Think about what this means operationally:
- The operator has a reliable pipeline for creating and destroying cloud instances daily
- By the time any threat feed or blacklist adds the IP, it's already been destroyed
- Traditional IP-based blocking is completely useless against this operator
- The only effective detection is behavioral: catching the pattern, not the specific IP
At an average of 7.7 IPs per campaign day and ~117 requests per IP, each instance lives for approximately 4-6 hours before termination. The infrastructure cost is negligible: at $0.01/hour for GCP e2-micro instances, the entire 3-week operation cost less than $15.
๐ญ The Disguise Kit: User-Agent Rotation in Real-Time
While analyzing individual IP behavior, we caught one of the broader .env scanning network (a DigitalOcean IP, not the Google Cloud fleet) demonstrating the user-agent rotation toolkit in a single burst. IP 104.248.56.87 sent 21 requests in 0.63 seconds:
| User-Agent Presented | Hits | Time Window |
|---|---|---|
Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 Chrome/135.0.6422.113 Mobile | 6 | 0.52s |
Mozilla/5.0 AppleWebKit/537.36 (compatible; ChatGPT-User/1.0; +https://openai.com/bot) | 6 | 0.46s |
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/135.0.0.0 | 3 | 0.09s |
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0 | 3 | 0.41s |
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) | 1 | โ |
Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 Safari/605.1.15 | 1 | โ |
21 requests. 7 identities. Under 1 second. The same machine pretending to be an Android phone, then ChatGPT, then Chrome on Windows, then Firefox, then Googlebot, then Safari on Mac.
The choice of ChatGPT-User and Googlebot is particularly revealing:
- Googlebot is whitelisted by virtually every WAF and bot-detection system โ nobody wants to accidentally block Google's crawler
- ChatGPT-User is a newer UA that many systems have whitelisted to allow AI crawling โ a fresh trust vector being exploited
- This tells us the scanning tool is actively maintained and adapts to current trust relationships in the security ecosystem
๐๏ธ The Discovery: Three Separate Economies Operating in Parallel
The 361 unique IPs we observed scanning for .env files are not a single operation. When we decomposed them by behavior, infrastructure, and cross-referenced with our SSH honeypot, three entirely distinct operational tiers emerged:
| Tier | ASN / Provider | IPs | Behavior | SSH Honeypot Overlap |
|---|---|---|---|---|
| 1. Professional | AS396982 (Google Cloud) | 54 | Temporal burst campaigns, daily rotation, framework-aware wordlist, zero reuse | 0% โ HTTP only |
| 2. Research / Commercial | AS14061 (DigitalOcean) | 51 | Mix of LeakIX (identifiable l9scan UA) and unidentified scanners | ~30% overlap |
| 3. Criminal Multi-Vector | AS22295 (Advin Services) | 44 | Budget VPS, no coordination, brute-force every protocol | 100% โ also SSH |
| Scattered | AS16509 (Amazon) + 50+ other ASNs | 212 | Individual scanners, low volume, opportunistic | Variable |
Why the SSH overlap matters:
Our Cowrie SSH honeypot captures brute-force attackers separately from the web layer. When an IP appears in both datasets, it means the same machine is running both HTTP .env scanning AND SSH password guessing โ a "multi-vector" attacker that throws everything at every target.
The Google Cloud fleet has zero such overlap. The Advin fleet has 100%. This single datapoint proves they cannot be the same operator. They represent entirely different business models in the underground economy:
- Tier 1 (Google): A specialized credential theft service. They only do HTTP. They only target .env. They invest in OPSEC. They sell credentials.
- Tier 3 (Advin): A general-purpose botnet. They attack everything โ SSH, HTTP, whatever ports are open. They sell access, not specific data.
๐ฌ The Honeypot Gap: Mathematical Proof of Specialization
We cross-referenced all 54 Google Cloud campaign IPs against our Cowrie SSH honeypot โ a dataset containing 8,000+ unique attacker IPs accumulated over 5 months of continuous operation:
Zero. Not one. Out of 54 IPs that scanned our web layer, not a single one ever attempted SSH login.
Now compare with Advin Services (AS22295) โ the "criminal multi-vector" tier:
This is not coincidence. This is operational doctrine. The Google Cloud operator understands something that the Advin botnet does not: SSH scanning gets you blacklisted fast. CrowdSec, fail2ban, and every security tool on Earth watches SSH. By avoiding SSH entirely, the Google operator stays below the radar of most automated defenses.
They sacrifice the additional attack surface in exchange for longevity and stealth. That's a trade-off only a professional makes.
๐ฐ The Economics: Why $15/Month Buys an Empire
How does one acquire 54 disposable Google Cloud IPs over three weeks?
| Method | Cost Per IP | Difficulty | Our Assessment |
|---|---|---|---|
| Free tier abuse (new GCP accounts) | ~$0.10 (phone verification) | Medium โ requires phone numbers | MOST LIKELY |
| Stolen GCP credentials (from other .env harvests) | $0 | Easy โ self-reinforcing cycle | POSSIBLE |
| Compromised billing accounts | $0 | Hard โ requires billing access | UNLIKELY |
| Legitimate purchase | ~$0.01/hr per instance | None โ but creates paper trail | UNLIKELY |
The most elegant possibility is a self-reinforcing loop: harvest .env files โ steal GCP credentials from them โ use those credentials to spin up scanning infrastructure โ harvest more .env files. The operation feeds itself.
But even without that loop, the economics are staggering:
| Cost Side | Revenue Side |
|---|---|
| 54 phone numbers: ~$5.40 | One .env with AWS keys: $50-500 |
| Compute time (e2-micro): ~$10 | One Stripe live key: $1,000+ |
| Total monthly cost: ~$15 | One RDS database dump: $500-5,000 |
| Estimated monthly yield: $10,000-50,000+ |
The success rate doesn't need to be high. If even 0.1% of targeted servers return a valid .env file, and the operation scans thousands of targets per day (we only see our own single server), the revenue dwarfs the cost by orders of magnitude.
Google has not terminated this operation despite 3+ weeks of daily abuse from their infrastructure. Whether this reflects poor abuse detection, deprioritization of "low-volume" scanning, or deliberate tolerance of paying customers remains an open question.
๐ฏ The Prize: What a Single Successful Hit Yields
When this operation finds a server that actually serves its .env file โ and across thousands of daily targets, some inevitably do โ here's what they harvest:
DB_HOST=production-rds.us-east-1.rds.amazonaws.com DB_USERNAME=app_prod DB_PASSWORD=s3cr3t_pr0d_p4ss! AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY STRIPE_SECRET_KEY=sk_live_4eC39HqLyjWDarjtT1zdp7dc MAIL_PASSWORD=smtp_prod_password REDIS_PASSWORD=redis_cluster_pass JWT_SECRET=your-256-bit-secret GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx SENTRY_DSN=https://key@sentry.io/1234567
From a single file, the attacker gains:
- ๐๏ธ Full database access โ customer data, PII, financial records
- โ๏ธ Cloud infrastructure control โ spin up resources, access S3 buckets, pivot to other services
- ๐ณ Payment processing โ refund fraud, test charges, or dump card data
- ๐ง Email system โ phishing from legitimate accounts, password resets
- ๐ Session hijacking โ JWT secrets allow forging any user's authentication
- ๐ฆ Supply chain access โ GitHub tokens can inject backdoors into dependencies
This is not a "scan." This is a key to everything. One exposed .env file can compromise an entire organization's infrastructure, customer data, and financial systems. The attackers know this. That's why 361 IPs are hitting our single server. Imagine the scale across the entire internet.
๐ Methodology & Data Sources
Primary Source: Traefik reverse proxy access logs โ Loki log aggregation โ web_threats PostgreSQL database (automated pipeline, ingesting since June 3, 2026)
Campaign Detection: Automated temporal_burst algorithm โ flags โฅ5 IPs from same ASN hitting same path patterns within 1-hour window. All 7 campaigns triggered independently.
Cross-Reference Sources:
- SSH Honeypot (Cowrie โ threat_intel PostgreSQL, 8,000+ IPs, 5 months)
- CrowdSec threat intelligence (84 decisions against AS396982)
- MikroTik blocklists (router-level IP blocking)
- Entity crosslinks (Qdrant vector store, 15,392 relationship edges linking web_threats โ honeypot โ dossier infrastructure)
Observation Period: June 3 โ June 27, 2026 (25 days continuous capture)
Confidence Level: HIGH โ direct first-party observation of attack traffic against our own infrastructure, automated detection corroborated by manual analysis, multi-source cross-correlation confirming behavioral patterns
๐ Conclusions
- This is a professional, dedicated credential harvesting service โ not a hobbyist, not a researcher, not background noise. The operational security (daily rotation, zero SSH contamination, framework-aware tooling) indicates a mature criminal operation.
- The .env scanning ecosystem is a multi-tier market with distinct professional (Google Cloud), commercial/research (LeakIX/DigitalOcean), and criminal (Advin Services) participants โ each with different methods, infrastructure choices, and business models.
- Google Cloud Platform is enabling this operation through insufficient abuse detection. Three weeks of daily IP rotation, 54 instances, zero intervention. The asymmetry between Google's security marketing and their actual abuse response is notable.
- Specialization proves market maturity. When criminal operations specialize to this degree โ avoiding SSH entirely, investing in OPSEC, maintaining framework-specific wordlists โ it means the market for stolen credentials is large enough to support dedicated specialists.
- Traditional defenses are irrelevant. IP blacklists, rate limiting, even WAF rules โ none work against an operator who uses each IP once and rotates user agents per-request. The only effective defense is not exposing .env files in the first place.
- The economic asymmetry is extreme. ~$15/month operational cost versus potentially $50,000+ monthly revenue from harvested credentials. This is one of the highest-ROI operations in cybercrime โ which guarantees it will continue and intensify.
๐ก๏ธ Practical Implications
If you run a web application:
- Verify your web server explicitly denies requests to
.*env*paths (don't rely on default behavior) - Check for backup files:
.env.bak,.env.old,.env~,.env.savein your document root - Audit your Docker builds โ does
COPY . .include your .env file? - Use secret managers (Vault, AWS Secrets Manager) instead of .env files in production
- Rotate credentials immediately if you find evidence of .env exposure in your access logs
The attackers documented in this dossier scanned us 6,313 times and found nothing. But they only need to succeed once, somewhere, to make the entire operation profitable.
๐ The Web Siege โ Series Navigation
๐ You are here: Letter A โ The .env Harvesters
- ๐ธ๏ธ A: The .env Harvesters โ Google Cloud credential scanning fleet (this article)
- ๐ป B: The WordPress Ghosts โ Azure fleet systematically checking for pre-planted backdoors
- ๐ญ C: The Reconnaissance Industrial Complex โ Palo Alto, LeakIX, DeepSeek scanning at scale
- โ๏ธ D: The Multi-Vector Operators โ 1,751 IPs attacking both SSH and HTTP simultaneously
- โ๏ธ E: The Cloud Mercenaries โ When cloud providers become attack platforms