A recent tweet about Netgear’s inclusion of private keys for trusted HTTPS certificates in their router firmware sparked a discussion about whether this presents a material security risk. Many security experts concluded that, unlike previous uses of this technique, there was no realistic attack scenario in Netgear’s case. But, in this post, I am going to demonstrate that to be incorrect.

Before we plunge into the details of the exploit, we need to understand the context behind this and why Netgear chose to do what they did.

Wireless routers usually offer a convenient web-based setup page but, outside of your network, the IP address or domain name you use to access it means nothing. If you were connected to a different network, this same IP address might take you to a different router’s setup page. For this reason, a certificate authority cannot issue your router an HTTPS certificate to promise that you’re connected to the real 192.168.1.254 or router.lan.

If you use unencrypted HTTP, you’re sending your router’s administration password to whichever device on your Wi-Fi network claims, on the honor system, to be your router. If another device is pretending to be your router — e.g. using ARP spoofing — your browser will happily send it the password.

As an alternative, most routers offer HTTPS with a self-signed certificate. But this comes at a great cost to the user experience: it requires users to bypass the browser security warnings. This is unworkable as it normalizes an action that undermines the entire security of HTTPS.

Since it can only be exploited by users connected to the network, unencrypted HTTP is not a big deal for most home Wi-Fi users. Their biggest threat is probably crafty teenagers sniffing the router password to turn off the parental controls. But Netgear was still unhappy: they wanted their customers to be able to access their router with a secure HTTPS connection without any scary certificate errors or configuration.

Is This the Real Routerlogin.com?

In their crusade for the coveted green padlock, Netgear procured a certificate for routerlogin.com and included the private key in their router firmware. When you visit this domain name on a Netgear Wi-Fi network, the router’s DNS server returns its own IP address and you connect, over HTTPS, to the router’s configuration page. This connection is trusted by the browser, even though the domain points to an internal IP address, because the router has a valid certificate for routerlogin.com.

Wonderful! Except that the private key is in any Netgear router so anyone can extract it and impersonate your router. Or they could obtain it from the firmware downloads available on the Netgear website. Your hypothetical crafty teenager just has to run their own HTTPS server and the browser will still trust it as if it were the router. Therefore, there is no material security improvement.

When details of Netgear’s approach hit Twitter, the certificates were revoked because certificate authorities have a duty to do so when the private key is “compromised” — even if it was deliberate. But did the compromised certificates actually present a security issue, or were the certificate authorities merely acting out of an abundance of caution?

Many security experts on Twitter concluded that there was no realistic attack scenario. Netgear’s setup is not vulnerable to the usual attack scenario — “DNS rebinding” — so it is a reasonable conclusion. But I was not content that DNS rebinding was the only way.

Why Not DNS Rebinding?

If an attacker tricked the user into using a malicious DNS server, they could impersonate routerlogin.com because they have the private key for a valid HTTPS certificate. This is not very useful on its own because the aim is to modify router settings — this means you need to phish the administration password and then connect to the router itself. The latter can be achieved by using a short Time-To-Live (so the browser does not cache the DNS entry for long) then “rebinding” the DNS entry to point to the router’s internal IP address again. Then you can make requests to the router without violating the Same-Origin Policy — the browser believes that it is the same origin because it is the same domain name, even though the underlying IP address changed.

But this is unlikely to work: the usual attack vector for a malicious DNS server would be when the user is using an attacker-controlled network, e.g. public Wi-Fi or an unscrupulous VPN provider. However, in this case, the attacker cannot connect to the router as it is unreachable outside of its own Wi-Fi network. Moreover, you cannot phish the password because the victim has no reason to visit the router management page when not connected to their router!

Thus, it is clear that we cannot attack the router while the user is still connected to our malicious network.

But what if we could install code on the victim’s computer while they are connected to our malicious network, and have that code execute when the user returns to their home Wi-Fi network?

Introducing Service Workers

If you aren’t familiar with Service Workers, here is the “security researcher introduction”: they are JavaScript workers that run in the background and allow you to intercept all HTTP requests made by a website. For example, you could use one to inject JavaScript code into all the HTML pages from a domain. And the cherry on the cake is that, once installed, they persist until the user clears their browser data — with no indicator that they are installed.

For these reasons, they are incredibly dangerous if an attacker can somehow install one on your domain. Luckily, the W3C foresaw this and added a strict requirement: Service Workers must be served over HTTPS from the same domain.

But this requirement is not an obstacle when an attacker can obtain a valid HTTPS certificate for your domain and impersonate you! Thus, if the user’s browser loads routerlogin.com while connected to a malicious Wi-Fi network or VPN, someone could install a Service Worker for the domain. This could be achieved by injecting a hidden iframe for routerlogin.com into a Wi-Fi captive portal or a random HTTP webpage that the victim was browsing. When the user connects to their home Wi-Fi network again and visits routerlogin.com, the Service Worker could inject malicious JavaScript into the router management pages!

Proof of Concept

I am comfortable providing a proof of concept without responsible disclosure because Netgear’s certificates have been revoked so HTTPS connection to https://routerlogin.com are not trusted by browsers anymore.

First, you need to clone the proof of concept.

git clone https://github.com/saleemrashid/evilrouterlogin
cd evilrouterlogin

Then, you need to set some configuration variables. We write them to .env because Docker Compose will automatically read any environment variables from this file.

cat > .env << EOF
CAPTIVEPORTAL_NAME=captiveportal.net
ROUTERLOGIN_NAME=routerlogin.com
PROXY_ADDRESS=192.168.1.254
EOF

The repository contains a Docker Compose configuration with two networks:

  • The evil network — this is the “malicious Wi-Fi network” scenario. It serves a malicious captive portal on http://captiveportal.net and the Service Worker installer on https://routerlogin.com.

  • The secure network — this is the equivalent of your home Wi-Fi network. This serves the router configuration page on https://routerlogin.com. Because I do not have a Netgear router, it emulates the vulnerable setup by mirroring my router’s HTTP configuration page from http://192.168.1.254 to https://routerlogin.com. You will need to change PROXY_ADDRESS if your router has a different IP address.

As I mentioned before, we cannot use Netgear’s certificates because they were revoked and will not be trusted by your browser. You could register a domain name and use Let’s Encrypt to obtain a trusted certificate, replacing routerlogin.com in the above with your own domain name.

But that is needlessly complicated. Instead, we are going to install mkcert — a helpful utility to generate a root certificate authority and install it in your computer’s trust store. Once you have followed the installation instructions, you need to issue a certificate for the router management page.

source .env
mkcert "$ROUTERLOGIN_NAME"

Finally, we start the containers.

docker-compose up

From another terminal, run the command scripts/container_ipaddr unbound-evil. This should give you an IP address like 172.18.0.2. You need to set this as your DNS server and flush your DNS cache. Once you have done this, close and re-open your browser (to ensure the browser’s own DNS cache is also flushed) and visit http://captiveportal.net. You should be redirected to http://captiveportal.net/portal/ and greeted with a beautiful page like the one shown below.

Welcome to Public Wi-Fi Captive Portal

Next, run the command scripts/container_ipaddr unbound-secure and change your DNS server to this IP address. This time, after closing and re-opening your browser, visit https://routerlogin.com. You should see a familiar router configuration page, but with a slight twist.

BT Home Hub configuration page with embedded Techno Chicken YouTube video

What happened is that http://captiveportal.net redirected to https://routerlogin.com which installed the Service Worker — remember, the Service Worker must be installed over HTTPS — and redirected back to http://captiveportal.net/portal/. Although an <iframe> might have worked, many privacy add-ons will prevent them from installing Service Workers; the redirect gave much more reliable results.

Even when you connected to the secure network, the Service Worker installed by the evil network is still running. It injects an embedded YouTube video and a small amount of JavaScript (check the browser console!) into any router management pages you visit.

Even if the user were using DNS-over-TLS or DNS-over-HTTPS, the malicious Wi-Fi network could intercept packets to the IP address behind routerlogin.com and perform the same attack.

An attacker could use this to modify any of your router’s settings, including changing your network’s DNS server or enabling port forwarding to access other devices on your LAN — particularly frightening if you have poorly configured IoT devices connected to the network.

Conclusion

While I could not find any prior literature on abusing Service Workers in this way, this is unlikely to be a novel idea. However, not only does this let you exploit a setup when DNS Rebinding alone cannot, it also allows you to develop more reliable DNS Rebinding attacks.

For example, if the router management page did not require authentication, there would be no need to phish the user and an attacker could instead use the Service Worker’s Background Sync API to perform the attack without any interaction from the user.

While DNS Rebinding attacks are challenging to avoid, Service Worker-based attacks are easy to defeat: Never disclose the private key for your HTTPS certificate!