DEV Community

Phaedon V
Phaedon V

Posted on

My Router's Hidden Door for Burglars

The port I never opened

While poking at my own home network one evening, I found an open door to the internet that I never created. Not a forward I'd set in the router's admin page, not a rule I'd forgotten about — a permanent hole punched straight through my NAT, pointing at the open internet, reachable by any host on the planet, with no authentication and no expiry. And it was aimed at a device that wasn't even powered on at the time.

The culprit was UPnP (Universal Plug and Play) — a convenience feature switched on by default on almost every consumer router shipped in the last fifteen years.

This is a walk-through of how I found it, how I proved it was genuinely reachable from outside my network (every endpoint mine — the only honest way to test this), and what you can do to check for and close the same door on your own network. There's no exotic exploit here. It's the feature working exactly as designed, which is precisely the problem.

Every public IP, MAC address and hostname in this article has been redacted or replaced with documentation-range values. Ironically, leaking those details is exactly the kind of self-own the article is about.

What UPnP actually does

To see why one stray port forward matters, you need the mental model of why your home network is normally safe at all.

Under the hood, your router does NAT (Network Address Translation). Your devices have private addresses (192.168.x.x) that don't exist on the public internet; the router rewrites their traffic to share one public IP. A useful side effect is that unsolicited inbound traffic from the internet has nowhere to go — the router doesn't know which internal device to hand it to, so it drops it. NAT isn't a firewall, but it behaves like one by accident. That's why a random stranger can't reach the laptop in your bedroom.

UPnP exists to poke holes in exactly that protection — on purpose, on demand. Through its IGD (Internet Gateway Device) service, an application on your LAN can ask the router: "forward external port 9308 to me." The router creates the mapping, and now inbound traffic from the internet to that port lands on that device. This is genuinely useful for things that need unsolicited inbound connections: online games, consoles, VoIP, BitTorrent, some smart-home gear.

Here's the whole problem in one sentence:

The router grants these requests to anything on the LAN that asks — no authentication, no prompt to the user, usually no logging.

There's no "are you sure?". There's no password. The router simply trusts that any device on the local network is allowed to open a door to the outside world. Your games console and a compromised IoT bulb have exactly the same privilege. You, the owner, are never asked and often can't even see what was opened without going looking — which is what this whole exercise was.

UPnP flow: a LAN device opens the door, the internet walks in

The small request on top is the whole cause; the internet-facing inbound path on the bottom is the effect — and the device making the request can be anything on your LAN.

The discovery

It started with an ordinary sweep of my own subnet to see what was on the network:

sudo nmap -sn 192.168.0.0/24
Enter fullscreen mode Exit fullscreen mode

Five hosts: the Arris gateway (.1), an LG smart TV (.3), an iPhone (.8), my laptop (.11), and a second Arris interface (.252). All accounted for. A service scan of the gateway showed its web admin UI on lighttpd, and one more thing on port 5000:

PORT     STATE  SERVICE  VERSION
80/tcp   open   http     lighttpd
443/tcp  open   ssl/http lighttpd
5000/tcp open   upnp     MiniUPnPd 1.9 (UPnP 1.1)
Enter fullscreen mode Exit fullscreen mode

That MiniUPnPd 1.9 is the UPnP daemon — and it's a release from around 2014, well over a decade old, baked into the ISP firmware where I can't update it. An old service that any LAN device can command is worth a closer look. So instead of guessing from the web UI, I asked the daemon directly what port forwards it was holding:

sudo apt install -y miniupnpc
upnpc -l
Enter fullscreen mode Exit fullscreen mode

The relevant line in the output:

 i protocol exPort->inAddr:inPort  description              remoteHost leaseTime
 0 UDP  9308->192.168.0.9:9308  '192.168.0.9:9308 to 9308'  ''         0
Enter fullscreen mode Exit fullscreen mode

Decoded, that single line says a lot:

  • External UDP port 9308 on my public IP is forwarded to 192.168.0.9:9308 on my LAN.
  • The remoteHost field is empty — the forward accepts connections from any host on the internet, not a specific one.
  • The lease time is 0 — meaning permanent. It never expires on its own.
  • The auto-generated description is the format an application produces when it opens its own mapping. Nobody set this by hand; some software on .9 asked for it.

And the kicker: 192.168.0.9 wasn't in my host sweep. The device that opened this hole was offline — but because the lease is permanent, its internet-facing forward outlived it. A classic orphaned mapping, sitting open, pointing at a device that comes and goes (a phone, a console, an IoT gadget), and reachable from the whole internet the entire time.

Proving the door is real

Listing a mapping only tells you the router intends to forward a port. It doesn't prove the outside world can actually reach in — ISP-level filtering or carrier-grade NAT can quietly make an "open" forward a dead end. The only honest test is to open a port to a listener I control and connect to it from a device that is genuinely off my network.

Every endpoint in this test is mine: my router, my laptop, my public IP, my phone. That's what keeps it a legitimate security test rather than an attack. Do not do this against infrastructure you don't own.

First, a listener on my laptop (LAN .11), so an incoming probe hits something instead of a closed port:

nc -lvnp 8099
Enter fullscreen mode Exit fullscreen mode

Then, using the same UPnP mechanism an app would, I opened a forward to it — with a one-hour lease so it auto-expires if I forget it:

upnpc -a 192.168.0.11 8099 8099 TCP 3600
upnpc -l
Enter fullscreen mode Exit fullscreen mode

The mapping now showed up in the list alongside the mystery one:

 1 TCP  8099->192.168.0.11:8099  'libminiupnpc'  ''  3597
Enter fullscreen mode Exit fullscreen mode

Now the real test, from my phone on mobile data with Wi-Fi off — a connection coming from the public internet, nowhere near my LAN:

nc -vn <YOUR-PUBLIC-IP> 8099
Enter fullscreen mode Exit fullscreen mode

And it connected:

Connection to 198.51.100.23 8099 port [tcp/*] succeeded!
Enter fullscreen mode Exit fullscreen mode

That line is the whole proof. A TCP handshake completed from a device out on the internet, through my public IP, through the UPnP forward, to a listener on my laptop. Typing into the phone showed the text arriving live in the listener window back on the laptop — a full, unauthenticated, bidirectional channel from the open internet into my machine, opened by nothing more than a LAN-side request.

Connection from an off-network device succeeding

From a phone on mobile data, off the home network: the connection to the public IP on the forwarded port completes. The IP is redacted.

The listener confirmed the inbound connection from an off-network address:

Ncat: Listening on 0.0.0.0:8099
Ncat: Connection from 198.51.100.200.
Ncat: Connection from 198.51.100.200:56732.
Enter fullscreen mode Exit fullscreen mode

Text typed on the phone appearing on the laptop over the tunnel

Typed on the phone, landing live on the laptop — a two-way channel straight from the open internet into the machine.

The instant the demo was done, I tore the hole down — which is the one step you must never skip:

upnpc -d 8099 TCP
Enter fullscreen mode Exit fullscreen mode

Why this is genuinely dangerous

The demo above is harmless — I opened a door and closed it. But the same mechanism, outside your control, is where the risk lives.

Malware self-exposure. This is the big one. A compromised device — a PC, a phone, an IoT gadget — can open its own inbound forward and hand an attacker a direct line back in, bypassing NAT entirely. NAT would have blocked that unsolicited inbound traffic; UPnP opens the door from the inside, on the malware's request. The victim does nothing and sees nothing.

Exposing a vulnerable service you never meant to publish. A forward leads to a service on the internal device. If that service has a known flaw — an old admin panel, a debug port, a torrent client with an RCE, an IP camera with hardcoded credentials — it's now reachable from anywhere on earth instead of just your living room. The mapping itself is harmless; what sits behind it may not be.

Open to the whole world, forever. Remember that mystery mapping: remoteHost empty (any source IP) and lease 0 (permanent). That combination produces holes that outlive the device that made them — orphaned forwards nobody is tracking, exactly like the one I found pointing at an offline device.

Attacks on the UPnP daemon itself. This is where an old MiniUPnPd matters. Historically, badly configured routers exposed their UPnP control interface to the WAN side, letting remote attackers add mappings from across the internet — research years ago found tens of millions of such devices. There's also CallStranger (CVE-2020-12695), which abuses the UPnP event-subscription mechanism for DDoS reflection, data exfiltration and internal port scanning. A decade-old daemon is more likely to carry that kind of baggage.

A fair word of calibration: UPnP is not inherently a breach. It ships on by default, and millions of people run it for years without incident — a legitimate app opening a legitimate port is the normal case. The real cost is loss of visibility and control. You don't get to approve what opens, so a bad actor or a sloppy device inherits the same power your games console has. Put bluntly: UPnP converts "an attacker must breach the perimeter" into "an attacker must breach any single device on the LAN, and the perimeter opens itself."

The other layer: getting onto the LAN in the first place

Everything above assumes an attacker is already on your network. On this same router, getting there took about a minute.

The gateway had WPS still enabled (WPS 2.0), and WPS is the weak link in most home WiFi. Using an AC1200 USB adapter (Realtek RTL8812AU) with the wifite3 toolkit, the WPS PIN fell in roughly a minute — a Pixie Dust attack recovered it offline, and the PIN handed over the WiFi passphrase directly. No wordlist, no waiting. WPS is sold as convenience; in practice it's a side door that sidesteps even a strong WPA2 password.

wifite3: WPS PIN and WPA2 passphrase recovered, PMF disabled

The run end to end: PMF disabled, WPS 2.0 enabled, the WPS PIN recovered and the WPA2 passphrase with it. Network name, addresses, PIN and password redacted.

Two things made it worse:

  • PMF (Protected Management Frames) was disabled — that's what lets an attacker deauthenticate a client and capture the WPA handshake to begin with.
  • A strong WiFi password is no help while WPS is on, because the PIN is a parallel route straight to the passphrase.

Now connect the two halves. Someone only has to be in WiFi range once — a neighbour, a car parked outside. WiFi gets them onto the LAN; from the inside, UPnP lets them open a permanent internet-facing door to anything that stays online — the router’s own admin page, a NAS, an IP camera, or a backdoor dropped on an always-on device. They then walk away with remote access from anywhere, and the forward survives reboots and outlives their visit. That’s why “nobody’s on my WiFi” isn’t the reassurance it sounds like: a weak wireless door plus UPnP isn’t two small problems — it’s a chain that turns one brief moment of proximity into lasting remote access.

Check and shut it down on your own network

Fifteen minutes on your own gear. All of this is read-and-remediate on hardware you own.

List what UPnP is currently holding open. This is the single most revealing command — it prints your external IP and every active forward:

sudo apt install -y miniupnpc   # or: dnf install miniupnpc
upnpc -l
Enter fullscreen mode Exit fullscreen mode

Read the mappings carefully. For each one, ask: do I recognise the internal device, did I mean to expose it, and why is the lease permanent? A clean list is fine. Anything you can't explain is your finding.

Identify every device on the network, so nothing behind a forward is a mystery. The vendor from the MAC address usually names it instantly:

sudo nmap -sn 192.168.0.0/24
Enter fullscreen mode Exit fullscreen mode

Delete any stale or unwanted mapping. It takes effect immediately:

upnpc -d <externalPort> <TCP|UDP>
Enter fullscreen mode Exit fullscreen mode

Turn UPnP off at the router unless you specifically rely on it. This is the real fix — deleting a mapping without disabling UPnP just lets whatever opened it punch the hole again. It's in the gateway's admin page, usually under Advanced, Firewall, or NAT settings. On an old daemon, disabling UPnP entirely is the cleaner call.

Change the router admin password while you're in there. A weak or default gateway password is still the single most common way home routers get taken over — it outranks UPnP by a wide margin.

Disable WPS. If your router offers WPS — PIN mode especially — turn it off. A WPS PIN can be recovered in minutes (Pixie Dust, or a straight brute force) no matter how strong your WiFi password is. Where the router supports it, switch WiFi to WPA3 and enable PMF, which also closes the handshake-capture path.

Verify from the outside. Everything above is the inside view. What actually matters is what the internet sees, and your LAN can't tell you that. Scan your own public IP from off the network — a phone on mobile data, a cheap VPS, or an external port-check service — to confirm nothing is exposed that shouldn't be. (If your router's WAN IP is in the 100.64.x.x–100.127.x.x range, you're behind carrier-grade NAT and inbound forwards won't work from outside anyway — worth knowing before you test.)

The one rule, and the takeaways

Everything here was done on my own network, against my own devices, from my own phone. That line is not optional. Capturing, scanning or opening ports against networks and devices you don't own is illegal in most places, full stop. The entire value of this exercise is understanding your own exposure — keep it there, or take it to a lab you control end to end.

The things worth carrying away:

  • NAT is not a firewall. It blocks unsolicited inbound traffic as a side effect, and UPnP exists specifically to undo that, on request, with no authentication.
  • UPnP trades control for convenience. You can't approve what gets opened, so every device on your LAN — trusted or compromised — holds the same power to expose you.
  • The perimeter is only as strong as your weakest device. With UPnP on, breaching any single LAN device is enough; the perimeter then opens itself.
  • Visibility beats assumptions. upnpc -l took seconds and showed me a permanent, internet-facing hole I never knew existed. You can't defend what you can't see.

My own loose end from all this: a stale forward to a device that's currently offline, which I'll identify from the router's DHCP list before deciding whether to kill the mapping and switch UPnP off for good. If you run upnpc -l on your own network after reading this, I'd genuinely like to know what you find.

Top comments (0)