Exploiting UPnP

December 20, 2022

Exploiting UPnP

As a child, I loved playing Minecraft. Since I was a youngster, I was technically gifted and decided to set up my own Minecraft server for my geeky friends and me to enjoy. Problem was, I didn't know what port forwarding was or how to log in to a router. The solution I found was as innovative as it was stupid.

I tried several different things at first. I tried hosting a Minecraft server using a variety of 'free' VPS providers. The lack of RAM caused unplayable lag spikes and took the fun out. It took me some time to realize that there was no free lunch and that nobody was going to host my Java-based server in a way that would benefit me. Gigabytes were expensive.

Next, I tried hosting it locally but kept running into a concept that my young brain didn't understand: port forwarding. My father was rightly concerned that my son would mess around in settings he didn't understand.

Netgear DGL834GT - The router that was provisioned for my family

I was furious and quickly went online to find Hamachi. LogMeIn now owns Hamachi and it is a hosted VPN provider. It allows you to play on a VPN with your friends. Although it worked better than my previous attempts, it still caused a lot of latency and was not ideal. This worked for me for a while, but I knew there was a better way.

Port forwarding was the only time I had ever encountered it was through Bittorrent. Bittorrent wouldn't work properly if there wasn't an open port. I wondered how it could function properly then. My client (Transmission) would inform me that the port I chose was 'open'. Did all ports have to be open? Did my Minecraft server lie to me? Transmission worked perfectly downloading and seeding files. Bittorrent was a great tool for sharing files among my friends and computers.

No matter what Listening Port number, Test Port reported open!

It didn't matter what port I chose, it seemed that when I pressed the "Test Port" button, somehow it was opened! This was unfair! How could Transmission be allowed to talk to anyone it wanted, whenever it wanted, but my poor Minecraft server was not given the same treatment? Was Big Torrent bribing Netgear? This was what kind of nepotism? !

UPNP was not something I understood, and I didn't Google it at that time. However, it was the technology that allowed Transmission the ability to communicate with anyone it wanted.

I discovered a way to do it better than Hamachi almost by chance. It worked! I had to open the Minecraft Server first, then enter the port it was supposed to use into Transmission's Port box, and then hit Test Port. While my friends and I spent hours building things that I accidentally blew up with TNT, it seemed to work!

What I didn't realize was that I was actually taking advantage of a security hole within UPNP. Although I was innocently using Transmission to access Minecraft, I was actually exploiting an extremely serious security flaw in the protocol. UPNP allows any software to hack through your router's firewall. It doesn't verify the software that is using said port. Any code on your computer can do this, even the most frighteningly popular Adobe Flash.

How UPnP works

UPnP is a complex standard whose main goal is to allow devices in a network to find each other without the need for configuration. It seems to be able to abstract from different network configurations to reduce mental burden for users who use a product that supports it. A noble goal. There is far too much to discuss here. Instead, I will concentrate on one aspect of UPnP. This is how it allows devices within your network to punch holes through firewalls (port forward).

UPnP uses Internet Gateway Device Protocol. This protocol maps ports to which NAT (Network Address Translation), is in use. It allows devices on a network, to communicate with a router to route data to a specific port to the system that made the request. IGDP allows applications to find the external IP address of a router without needing to use an external system. It also allows them to see which port mappings are already in place. Crazyly, the standard allows applications on your network the ability to request a router a new public address. However, I have never seen this in practice.

Transmission, an application that maps a port for its own use, makes a request for the RFC to identify the IGD Control Point (in most cases, the router).

If authentication is not enabled or passes, it will be done. In most cases, it is not enabled! - the IGD sends a "AddAnyPortMapping()" request through to the Internet Gateway Device - Port Control Protocol Interworking Function, or the IGD-PCP IWF for short. Aren't RFCs great fun? The IGD-PCP IWF then sends a Port Control Protocol MAP request the PCP server.

The PCP Server is able to do one of the following three broad categories:

It can refuse. It could refuse to open the port because it has been used by someone else. It might refuse to open the port for someone else.
- It can accept and return a PCP MAP response with another external port that the UPnP Controller Point did not request, but it can use if it so wishes.

The application that initiated this flow may then test if the port mapping worked. This is usually done by using an external API to try to GET something to run on the port on the machine that runs the software. Voila! The port is now open. The software can request that the mapping it created be deleted. Anyone else can also request the IGD. The Software effectively holds a lease on this port. The port will remain open until the lease expires or until the software deletes it manually. The IGD can define the maximum lease length, but the maximum time it will last is 429496729696 seconds. This is a ridiculously long limit.

The lease will only be terminated if the IP that generated it is not available. The spec assumes that the port mappings associated to the machine will also be lost if it shuts down or its DHCP lease expires. However, this is not always true.

According to the RFC, "we assume that IGD applies appropriate security policies to determine if a Control Point has rights to delete one or more mappings". This assumption is not unreasonable. After all, routers come as many sizes as the authentication mechanisms that they rely upon. Security is often overlooked in the consumer hardware industry. Akamai reported a very sad security flaw that found that 3.5 million routers scanned had responded to UPnP probe packets. This means that outside parties can send UPnP requests directly to the firewall. Worse, approximately 277,000 routers don't verify that the software requesting port forwarding is actually doing so. This is actually required by the RFC. RFC 6970 would not permit routers to ensure that port mappings requested by a source point to that source.

This means that attackers can now spam routers with UPnP port forward request requests, allowing them to access previously inaccessible hosts. It effectively opens up the firewall's doors to the internet. Terrifying stuff.

It gets worse. Some routers routers don't perform this origin check and don't even verify that the port mapping points at a machine on the local network. This basically means that any router can be hacked and used as a proxy. How? It's as easy as asking.

I therefore now disable UPNP wherever I have the ability. It's one those terrifying, yet convenient technologies that I am not sure I can trust. Sometimes, convenience can be more costly than anyone realizes. Ask the NSA.