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
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
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
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
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
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
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
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
because Docker Compose will automatically read any environment variables from
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:
securenetwork — 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_ADDRESSif 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
routerlogin.com in the above with your own domain
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.
From another terminal, run the command
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.
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.
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
evil network is still running. It injects an embedded YouTube
video and a small amount of
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
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.
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!