Exposed admin surfaces: the #1 homelab compromise vector you're not scanning for
CVE scanners catch outdated software. They don't catch the far more common homelab failure mode: a Grafana, phpMyAdmin, Pi-hole, or Plex web UI on a public IP because you forgot the firewall rule when you changed routers six months ago. Here's why this category dominates real-world homelab compromises, what the 70+ services to check are, and how a good scanner finds them without making the situation worse.
The compromise class CVE scanners can't see
Pick a homelab compromise from any community-thread post-mortem in the last five years and read the first-stage attack vector. Overwhelmingly it isn't a novel CVE. It's:
- An admin panel that should have been on the LAN ended up on the public internet because of a UPnP rule, a port-forward the operator forgot about, or a mis-configured Cloudflare Tunnel.
- The admin panel ran the default
admin / admincredentials, or a weak operator-chosen password the attacker brute-forced in minutes. - OR the admin panel had no authentication at all because the operator thought "it's only on my LAN" was sufficient.
- Once authenticated, the attacker used the admin panel's legitimate features (cron-job scheduling, file upload, plugin install, command execution) to drop a payload.
None of these are CVEs. The software wasn't outdated. The Linux kernel wasn't unpatched. The CVE scanner reports a clean host. And yet the host is owned within hours of being indexed by Shodan.
Why this category is so dangerous
Three reasons it dominates real-world compromise stats:
1. The base rate of mistakes is high
Homelabs change constantly. New service installed, port forwarded for "just a quick test," router replaced and firewall rules lost, ISP issued a new public IP and DNS-rebinding protections broke, Cloudflare Tunnel mis-routed. Every change is a chance to leak an admin surface, and most operators have dozens of changes per year.
2. Discovery is automated and fast
Shodan, Censys, and a handful of less-public continuous
port scanners crawl the entire IPv4 space every few hours.
Anything bound to 0.0.0.0:80 or
0.0.0.0:8080 appears in their database within
a day. Attackers don't need to find your IP — they search
Shodan for "Grafana" or "phpMyAdmin" and get a list of every
exposed instance worldwide.
3. Default credentials persist longer than they should
"I'll change it later" is the most common homelab
compromise. Plex's default isn't dangerous (Plex requires
Plex.tv login). But Grafana defaults to
admin / admin; phpMyAdmin defaults to whatever
MySQL root is; Pi-hole's default password is the system
password; *arr suite defaults to no auth at all.
The 70+ services to check
A complete list is impossible (vendors invent new admin panels weekly), but the categories that produce most homelab compromises:
Media servers
- Plex — port 32400, web UI
- Jellyfin — 8096
- Emby — 8096
- The *arr suite: Sonarr (8989), Radarr (7878), Lidarr (8686), Readarr (8787), Prowlarr (9696)
- SABnzbd / NZBGet — 8080 / 6789
- qBittorrent / Transmission — web UI on configurable ports
Smart-home / IoT control
- Home Assistant — 8123
- Node-RED — 1880
- OpenHAB — 8080
- Domoticz — 8080
Network / DNS
- Pi-hole — 80 admin path
- AdGuard Home — 3000 / 80
- UniFi Controller — 8443
- pfSense / OPNsense — typically 443
- Mikrotik RouterOS — 80, 8291
Storage / NAS
- Synology DSM — 5000 / 5001
- QNAP QTS — 8080 / 443
- TrueNAS Core / Scale — 80 / 443
- Unraid — 80
Container + orchestration
- Portainer — 9000 / 9443
- Docker daemon on TCP — 2375 (unencrypted!), 2376 (TLS)
- Kubernetes API — 6443
- Rancher — 8080
Monitoring / dashboards
- Grafana — 3000
- Prometheus — 9090
- Uptime Kuma — 3001
- Netdata — 19999
- Cockpit — 9090
Databases / dev infrastructure
- phpMyAdmin — typically 80 at
/phpmyadmin - Adminer — wherever PHP is hosted
- Redis — 6379 unauth (this is bad — see below)
- MongoDB — 27017 unauth
- Elasticsearch / Kibana — 9200 / 5601 unauth
- Gitea / GitLab / Forgejo — 3000 / 80 / 443
- Jenkins — 8080
Gateways / proxies
- Traefik dashboard — 8080
- Caddy admin API — 2019 (localhost-only by default; check)
- nginx-proxy-manager — 81
Secrets / auth
- HashiCorp Vault — 8200
- Authelia / Authentik — varies
- Keycloak — 8080
Special-case worst offenders
Unauthenticated Redis
Redis defaults to no authentication on
0.0.0.0:6379. Attackers connect, set the
dir to ~/.ssh, the
dbfilename to authorized_keys, and
SET a key whose value is their public key. Redis
writes the key file. Now the attacker has SSH access as
whatever user runs Redis. This attack is fully automated and
runs against every fresh public-facing Redis on the internet
within hours. Don't expose Redis without
auth.
Docker daemon on TCP
dockerd -H 0.0.0.0:2375 exposes the Docker API
with no authentication. Docker has root-level system access
via design (containers run as root, can mount the host
filesystem, etc.). Anyone reaching the API gets immediate
root on the host. Never expose 2375.
Elasticsearch / Mongo / CouchDB without auth
All three default to no authentication and bind to all interfaces in older versions. Found-via-Shodan databases have been the source of repeated mass-exposure-of-PII incidents covering hundreds of millions of records. Authentication is mandatory regardless of network position.
How a scanner detects exposed admin surfaces (without making things worse)
A scanner can do one of two things:
Option A: just probe and fingerprint
Connect to known admin-panel ports, send an unauthenticated
GET / or service banner request, look for
identifying strings in the response (Grafana's
X-Frame-Options header, Pi-hole's pi.hole
title, Redis's +PONG response to PING).
Report the finding and stop. Don't authenticate.
Option B: try default credentials
Some scanners (looking at you, Nessus and various pentest tools) test default credentials. This is the wrong answer for a homelab scanner. Reasons:
- Logged in by your scanner creates audit trail noise that masks real intrusions. If a real attacker also logs in tomorrow with default creds, you'll see two entries in the auth log and assume both are your scanner.
- The scanner's IP is now on the "things that successfully authenticated" list — your fail2ban / WAF / cloud auth logs don't differentiate "your scanner" from "a credential-stuffing bot."
- Default-cred testing implies "I might fix it" — it doesn't. The point is the panel is exposed, not whether the password is weak.
- Some default-cred attempts trigger lockouts.
If your scanner attempts
admin / adminon Grafana, you've now locked out the realadminaccount for the next 30 minutes.
Noxen does only Option A. It fingerprints ~70 services across the categories above, reports each exposed surface with a severity class based on what kind of service it is (databases > admin panels > media servers), and links to the remediation steps for each (firewall, authenticating proxy, or removing the service entirely if nobody uses it).
The remediation order of operations
When the scanner finds an exposed admin surface, the fix is usually NOT "set a strong password." It's:
- Should this be reachable from where it is?
If the answer is "no, this should only be on my LAN,"
firewall it off the public side. Remove the port forward,
bind to
127.0.0.1+ reverse-proxy on the LAN IP only, or move it behind Tailscale / Cloudflare Tunnel. - If yes, is there an authentication layer in front? A bare admin panel on the public internet is wrong even with strong credentials. Put Authelia, Authentik, or Cloudflare Access in front. Single sign-on across all your panels, plus mfa.
- Are the admin-panel credentials themselves strong? Now you can think about default credentials. Use a password manager; use the longest passphrase the panel accepts.
- Is logging on? If the panel gets
compromised despite the above, you want to know. Most
admin panels write to
/var/log/{service}/; ship those logs to a SIEM.
The order matters. Strong credentials on a public Grafana are much weaker than weak credentials on a Tailnet-only Grafana, because the latter requires the attacker to first breach Tailscale.
What Noxen does
Noxen runs the admin-surface probe as part of every scan,
across the ~70 services in AdminSurfaceCatalog.fingerprints.
Each finding is tagged with severity, exposure context (port
+ IP), the specific service detected, and a remediation
pointer. It never authenticates against the panel.
The probe complements the CVE matcher: the CVE matcher catches outdated software, the admin-surface probe catches misconfigured-but-current software. Both are necessary; neither is sufficient. $79 one-time at launch.