Hiding Through a Maze of IoT Devices?
In March 2018, Symantec reported about the Inception Framework abusing vulnerable UPnP services to hide themselves.
What is UPnP?
UPnP stands for Universal Plug and Play and is basically just a set of networking protocols to allow devices to discover each other in the LAN and use some network features (such as data sharing or entertainment) without any configuration (hence “plug and play”). It’s a pretty old architecture that was designed in the late 90’s and finished in the early 2000’s. The most implemented revision of the protocol is probably the 1.1 that was published in 2008 and the most recent one (UPnP Device Architecture 2.0) in 2015.
According to the UPnP specifications there are 6 layers of protocols, and among them the three important for this research:
- Discovery: also known as Simple Service Discovery Protocol (SSDP), used by UPnP-enabled devices to discover each other;
- Description: Device Description is expressed in XML via a remote URL, this is how the device will describe its capabilities;
- Control: Control messages are also expressed in XML using the SOAP protocol, it really looks like RPC (but without any authentication);
Here is a diagram to understand how these layers come together:
There is more than one way to abuse UPnP, and I’m not even talking about the numerous CVEs affecting UPnP implementations. Several vulnerabilities in the UPnP design have been reported in the last decade, most of them are due to misconfiguration of the service or poor implementations. My post will describe one of them: the Open Forward attack, but more on that later.
Normally UPnP is supposed to work on a local network, like so:
SSDP uses UDP on the 1900 port, it will send a
M-SEARCH HTTPU packet (yes, it’s HTTP over UDP) to the
126.96.36.199 IPv4 address (Local Scope multicast from RFC2365) or
ff0X::c in IPv6.
Now, if you do send a M-SEARCH packet over the Internet to some vulnerable UPnP-enabled device, it will actually reply back, even though the protocol is supposed to be local-only! That’s the first step towards our goal: using the router as a proxy.
This is the first vulnerability here, the discovery service shouldn’t listen on the WAN interface. Now what can get an attacker sending the M-SEARCH packet?
Example misconfigured device actually replying back:
The M-SEARCH server’s response contains a
Location HTTP header pointing to the XML Device Description.
Here you can notice the named private IP address in the URL, but then again you can (in most cases) actually access the web server through the WAN on its public IP address. You’ll get served the SCPD (Service Control Protocol Document), this is an XML document which defines the set of Actions and State Variables that a Service implements. Yay UPnP standards…
This is basically where you’ll find what capabilities the device is offering. The XML will also show you the
ControlURL variables for each service, this is the SOAP endpoint to talk to that particular service (in substance a GET/POST to that URL will trigger actions).
One of the most interesting service for our research is the WANIPConnection, this is the one being abused. The true evil shines through the skin of UPnP in the later stages.
The WANIPConnection service
According to the UPnP standard:
This service-type enables a UPnP control point to configure and control IP connections on the WAN interface of a UPnP compliant InternetGatewayDevice . Any type of WAN interface (e.g., DSL or cable) that can support an IP connection can use this service.
An instance of a WANIPConnection service is activated (refer to the state variable table) for each actual Internet connection instance on a WANConnectionDevice. WANIPConnection service provides IP-level connectivity with an ISP for networked clients on the LAN.
More simply put, this is the NAT traversal toolbox of the UPnP standard. In the documentation you’ll find a function called
AddPortMapping() that is used to ask the router (IGD) to redirect TCP/IP traffic to a specific host/port in the LAN. Very useful for peer-to-peer or games that require to open a port behind a “NATing” device.
Now let’s abuse this UPnP function, shall we?
The Open Forward Attack
As you can guess, it’s possible to invoke UPnP SOAP functions from the WAN interface and without any kind of authentication. If you send an
AddPortMapping request for malicious intent you can either:
- Access a local computer behind a NAT
- Access a remote computer through the router
The first option has been recently dubbed by Akamai as UPnProxy: EternalSilence, an other threat actor used this trick to access Windows’ SMB ports behind routers to exploit the infamous EternalBlue vulnerability.
In my research (inspired by the Symantec discovery) I was more intrigued about the second option. So how does it work?
The attack is actually really clean, you simply have to ask — just as if you were on the LAN — the router to gently add a port mapping with the right parameters. Instead of redirecting the traffic to a local client, you can specify any public IP address. In most implementations the UPnP daemon will just spawn an
iptables process with your specified parameters… without any check!
This way you can use the router as a dumb proxy and masquerade your IP address. This is what have been doing this Inception group with 3 layers of routers.
Inception Framework: putting it all together
According to Shodan there are 2.2 Millions (as of November 2018) UPnP-enabled devices responding to a M-SEARCH discovery request… this is huge but hang on.
Through active scanning, I found that 13% of exposed UPnP devices were vulnerable to the Open Forward attack I mentioned earlier. This is about 290k vulnerable devices across 80 countries.
290,000 vulnerable devices across 80 countries
The four most impacted operators:
- FPT Telecom (Vietnam)
- Korea Telecom
- Chunghwa Telecom (Taiwan)
- ChinaNet Shanghai Province Network