What Happens When You Expose a Service to the Internet
This blog has been live for 4 days. It’s a FastAPI application behind NGINX and Cloudflare, serving static HTML pages about security research. No PHP. No WordPress. No database exposed to the web. Just a Python app returning Jinja2 templates.
In those 4 days, we received 1,941 requests from 226 unique IPs. Only 34% were legitimate page views. The other 66%? Automated exploitation attempts, credential harvesters, and vulnerability scanners — the background radiation of the modern internet.
You don’t need to be a target. You just need to have a public IP.
Traffic breakdown
| Category | Requests | % of total |
|---|---|---|
| Legitimate page views | 662 | 34% |
| Scanner/attack probes (404s) | 1,129 | 58% |
| Bad requests / malformed | 107 | 6% |
| Sensor advisory posts (201) | 8 | 0.4% |
The attacks we observed
Every attack below was captured from real NGINX access logs on this blog. None succeeded — FastAPI doesn’t serve PHP, ASP, or WordPress. But these are the same attacks hitting your servers right now.
1. PHPUnit eval-stdin.php (CVE-2017-9841) — 240 requests
/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php /zend/vendor/phpunit/... /laravel/vendor/phpunit/... /blog/vendor/phpunit/...
30+ path variations. The scanner tries every common PHP framework directory hoping to find an exposed PHPUnit installation. This CVE is from 2017 — 9 years old, still being mass-exploited.
2. Environment file harvesting — 50+ requests
/.env, /.env.production, /.env.local, /.env.bak, /.env.backup, /.env.save, /.env.old, /.env.swp, /api/.env, /app/.env, /admin/.env ...
.env files contain database passwords, API keys, cloud credentials.
One exposed file can compromise an entire infrastructure. Attackers check 40+ variations
including editor swap files (.env.swp, .env~).
3. Git repository exposure — 15 requests
/.git/config /.git/index /www/.git/config /public/.git/config
If accessible, an attacker can reconstruct the entire repository — source code,
credentials in old commits, deployment secrets. Tools like git-dumper
automate the full extraction.
4. PHP webshell spray — 100+ unique filenames
/shell.php, /alfa.php, /gptsh.php, /0xD.php, /666.php, /admin.php, /ms-edit.php, /ioxi-o.php, /f35.php ...
Not trying to exploit us — checking if someone already compromised us and left a webshell behind. If any path returns 200, the attacker gets a pre-planted backdoor for free.
5. ThinkPHP RCE (CVE-2018-20062)
/index.php?s=/index/\think\app/invokefunction &function=call_user_func_array&vars[0]=md5&vars[1][]=Hello
Calls md5("Hello") as a test. If the response contains the hash,
the attacker has code execution and will follow up with a real payload.
6. Apache path traversal (CVE-2021-41773)
/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh
URL-encoded ../ to escape web root and reach /bin/sh.
Targets Apache 2.4.49/2.4.50 where path normalization was broken.
7. PHP pearcmd LFI (CVE-2022-31625)
# Step 1: Write PHP shell via pearcmd
/index.php?lang=../../../usr/local/lib/php/pearcmd
&+config-create+/&/<?echo(md5("hi"));?>+/tmp/index1.php
# Step 2: Include the shell
/index.php?lang=../../../../../../../../tmp/index1
Two-stage attack: first request writes a PHP file to /tmp,
second request includes it via path traversal.
8. Non-HTTP protocol probes
SSH-2.0-Go (SSH handshake on HTTPS port) mstshash=Administr (RDP cookie) \x05\x01\x00 (SOCKS5 proxy check) \x03\x00\x00/*\xE0...Cookie: (RDP/TLS hybrid)
Raw SSH, RDP, and SOCKS5 handshakes sent to our HTTPS port. Scanners checking if the server speaks multiple protocols — common technique for finding misconfigured reverse proxies.
9. VPN & Exchange probes
/remote/login?lang=en (FortiGate SSL VPN) /global-protect/login.esp (Palo Alto GlobalProtect) /owa/auth/logon.aspx (Exchange OWA) /autodiscover/autodiscover.json?@zdi/Powershell (Exchange ProxyShell)
Enterprise infrastructure fingerprinting. The Exchange ProxyShell probe (CVE-2021-34473) chains three vulnerabilities for unauthenticated RCE.
The message
We didn’t advertise this blog. We didn’t submit it to any search engine. We just put a service on a public IP behind Cloudflare. Within hours, the scanners found it.
This is not targeted. Nobody is “hacking” our blog specifically. These are automated botnets scanning the entire IPv4 space, hitting every IP on every common port with every known exploit. Your home NAS, your forgotten test server, your IoT camera — they’re all getting the same traffic right now.
The internet is not a safe neighbourhood. Exposing a service is not a question of if you get scanned, but when. For us it took less than a day.
Why none of this worked
- No PHP runtime — FastAPI/Python, all PHP exploits return 404
- No WordPress — all wp-* paths are meaningless
- No .env in web root — config is a Python module, not a dotfile
- No .git exposed — deployment copies files, doesn’t clone the repo
- Cloudflare — filters the worst before it reaches NGINX
- TLS 1.3 only — no downgrade attacks