[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

BT Home Flub: Pwnin the BT Home Hub (5) - exploiting IGDs remotely via UPnP


It's known that UPnP [1] is inherently insecure for a very simple
reason: administrative tasks can be performed on a Internet Gateway
Device (IGD) without needing to know the admin password whatsoever!
This on its own is quite scary and I personally feel that although
there is some research in the public domain, there is much more
attention that needs to be paid to UPnP.

UPnP allows you to perform administrative functions. Some functions
are very standardized and supported by most devices. Examples include
obtaining network settings, and enabling port forwarding rules. Other
functions are make/model specific. Some very scary functions such as
obtaining administrative username and password pairs have been
reported [2] in the past. As a reminder, this works without submitting
any administrative password whatsoever since UPnP is a
authenticationless protocol. On top of this, most IGDs support UPnP by

After having read several UPnP security research materials I realized
that all the described attacks assume that the attacker (be it human
or malware) comes from inside the network. This post describes how to
exploit IGDs remotely via UPnP even when no services are publicly
available (WAN interface).

** Preauth XSS + SOAP payload = remote UPnP exploitation **

If you sniff yourself while running software that uses UPnP in the
background to help you configure your router, you'll see that UPnP is
nothing more than SOAP. Our AJAX knowledge tells us about a feature
that allows us to craft arbitrary XML requests: the XMLHttpRequest [3]
object. Trouble is, such object can only be used within the context of
the site that the requests are submitted to. So if we host the
malicious scripting code on a third-party site, and a victim user
located in the same LAN as the target IGD visits such page, the
request wouldn't go through due to XMLHttpRequest same-origin policy
restricition. Or put in a different way: you aren't allowed to make
XMLHttpRequests to any server except the server where your web page
came from.

However, if you find a pre-auth XSS vulnerability [4] on the target
device you can bypass such restriction. For instance, many devices
such as the BT Home Hub and Speedtouch routers offer certain pages
before authenticating. Some of these pages are cgi scripts which are
vulnerable to XSS. Although offering certain "useless" functionalities
before logging into the router might not seem like a big deal, it can
actually lead to UPnP being exploited remotely, even if the web admin
console is not visible from the Internet!

The following is a non-malicious proof-of-concept exploit which sets
up a port-forwarding rule from port 1337 on the WAN interface to port
445 on the internal IP address Such IP address is the
first usable IP address reserved for clients connected to Speedtouch
and BT Home Hub routers. The exploit has been tested on BT Home Hub -
Firmware version 6.2.6.B. Just to make things clear, UPnP is enabled
by default on the BT Home Hub, just like most IGDs. If your Internet
gateway is a BT Home Hub, clicking on the following link should add a
new forward rule called EVILFORWARDRULE: ATTACK

In order to check if the port-forwarding rule was added successfully
you can use UPnP Port Forwarding Utility [5] and simply click on
"Update list now" after the device has been discovered (device name
should show on the top-left corner a few seconds later after launching
the tool). You could of course use the technique and code explained in
this post on any Internet gateway that supports UPnP and is a
vulnerable to a preauth XSS vulnerability. If you manage to
successfully test this attack on the BT Home Hub or any other device
please let us know!

** Zombie routers and the unvalidated NewInternalClient bug **

A bit of more UPnP hacking lead me to realize that the BT Home Hub is
vulnerable to the (in)famous unvalidated NewInternalClient bug. This
bug allows you to choose external IP addresses instead of a LAN IP
addresses as intended when setting up port-forwarding rules via UPnP.
In this case, I reused the previous code and changed the internal IP
address ( in the NewInternalClient tag with the IP
address of a random Internet web server and the value of the
NewInternalPort tag to 80. This effectively allows an attacker to use
the vulnerable BT Home Hub router as a proxy - aka onion router. In
other words, when probing the router's NATed IP address on port 1337,
the attacker is effectively probing the IP address and port number
specified by the port-forwarding rule - except the routers IP address
would be shown in logs of the target web server, as opposed to the
attacker's real IP address. I thought this is a nice real example of
how a vulnerable router can be used as a zombie by simply having a
user visit a page with malicious scripting (XSS + UPnP SOAP request).
Imagine running your favourite vulnerability scanner against a target
site, while using the victim user's router as a proxy - sweet!

There are other UPnP functionalities besides port forwarding rules
that look potentially interesting from a hacking point of view. For
instance, SetDNSServer [6] allows you to guess what, set the gateway's
DNS server. Imagine someone changing your router's DNS server setting
by simply visiting a webpage. After that you visit
yourfavoritebank.com and guess what, you're actually visiting a
malicious server that is harvesting all your banking login details!
I'll leave the exercise of writing a remote UPnP exploit that changes
the DNS server setting on the BT Home Hub (or any other vulnerable
router) to the reader.

** About GNUCITIZEN **

GNUCITIZEN is a Cutting Edge, Ethical Hacker Outfit, Information Think
Tank, which primarily deals with all aspects of the art of hacking.
Our work has been featured in established magazines and information
portals, such as Wired, Eweek, The Register, PC Week, IDG, BBC and
many others. The members of the GNUCITIZEN group are well known and
well established experts in the Information Security, Black Public
Relations (PR) Industries and Hacker Circles with widely recognized
experience in the government and corporate sectors and the open source

GNUCITIZEN is an ethical, white-hat organization that doesn't hide
anything. We strongly believe that knowledge belongs to everyone and
we make everything to ensure that our readers have access to the
latest cutting-edge research and get alerted of the newest security
threats when they come. Our experience shows that the best way of
protection is the mass information. And we mean that literally!!! It
is in the public's best interest to make our findings accessible to
vast majority of people, simply because it is proven that the more
people know about a certain problem, the better.

[1] http://www.upnp.org/resources/whitepapers.asp
[2] http://www.securityfocus.com/bid/7267/discuss
[3] http://www.w3.org/TR/XMLHttpRequest/
[4] http://www.gnucitizen.org/blog/bt-home-flub-pwnin-the-bt-home-hub-4
[5] http://www.codeproject.com/KB/IP/PortForward.aspx
[6] http://www-adele.imag.fr/users/Didier.Donsez/dev/osgi/upnpgendevice/api/fr/imag/adele/bundle/upnp/igd/model/LANHostConfigManagementModel.html#setDNSServer(java.lang.String)

// http://www.gnucitizen.org/projects/bt-home-flub-pwnin-the-bt-home-hub-5/payload.xss
var req;
var url="/upnp/control/igd/wanpppcInternet";

function loadXMLDoc(url) {
	req = false;
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest && !(window.ActiveXObject)) {
    	try {
			req = new XMLHttpRequest();
        } catch(e) {
			req = false;
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
       	try {
        	req = new ActiveXObject("Msxml2.XMLHTTP");
      	} catch(e) {
        	try {
          		req = new ActiveXObject("Microsoft.XMLHTTP");
        	} catch(e) {
          		req = false;
	if(req) {
		req.onreadystatechange = processReqChange;
		req.open("POST", url, true);

		req.send('<?xml version="1.0"?><SOAP-ENV:Envelope

function processReqChange() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
        } else {
            alert("There was a problem retrieving the XML data:\n" +


gnucitizen.org, ikwt.com