Evan Grant, a researcher at network security scanning company Tenable, recently decided to have a go at hacking a home router.
The idea, it seems, was more to learn about the general techniques, tools and procedures available to router hackers than to conduct a security assessment of any particular product.
Understandably, therefore, Grant picked a router model using two non-technical criteria: was it popular, and was it available in Canada (Grant’s home country)?
After opening up the router casing to get access to the circuit board, Grant made good progress, by quickly:
- Finding likely pins on the circuit board where a debugging device could be connected.
- Identifying the correct wiring for the debugging circuity to permit a serial connection.
- Getting a root shell via a serial line and accessing the files on the device.
Grant’s first stop was to download a binary file (executable program) called
httpd, which is the name under which you typically find a home or small business router’s web server, used for managing the device from a browser.
httpd stands for HTTP daemon, where HTTP means that the program handles web traffic, and daemon is the Unix/Linux name for what Windows users know as a service: software that runs in the background whether anyone is logged in or not. (The word daemon is properly pronounced “die-moan” or “day-moan”, but many sysadmins just call them “demons”, and you may need to follow suit to avoid causing confusion.)
Disassembling the web server binary revealed critical bugs, caused by programming errors, that Grant was able to chain together to take over the router via its web interface without needing a password.
Firstly, the router had a list of built-in web server subdirectories where authentication was not required, so that “harmless” files such as as
http://[router]/images/logo.png would work for everyone.
(A company logo isn’t a secret, so why not let anyone access it, whether they’ve logged in already or are still stuck on the login page?)
But once the router had matched the name of the “harmless” subdirectory, it didn’t bother applying any other security checks such as looking for risky characters in the filename.
This means that Grant could use a filename such as
/images/../login.htm in the URL as an unauthenticated equivalent to web pages that would otherwise prompt for a password or block access entirely, such as
This sort of bug dates back decades, and is known as a directory traversal vulnerability, because the special directory name
.. (two dots) is shorthand for “go up one directory”.
Thanks to the “go up one” component, the file named
/images/../login.htm actually refers to a file that sits above the
/images subdirectory, not in the directory tree underneath it.
Directory traversal bugs that rely on the “go up one” trick often show up in logs with filenames such as
../../../../Windows/System32. The trick here is that if you “go up” by more subdirectories than your current depth in the directory tree, you don’t get an error. Once you get to the root directory, every subsequent
../ simply gets ignored, because “one up” from the root directory is just the root directory again. So, a filename preceded by sufficiently many apparently innocent relative pathnames of
../ is equivalent to a dangerous and suspicious absolute filename such as
/etc/password (the list of Unix usernames) or
C:WindowsSystem32 (the all-important Windows directory where system software lives).
Secondly, the router set an authentication cookie, valid for any other password-protected page, as soon as a page was accessed for which authentication was supposed to have taken place.
In other words, the authentication token wasn’t generated as a side-effect of a correct password being entered, but merely as a side-effect of a protected page being accessed, even if that page itself was reached via an authentication bypass.
Simply put, a bypass in one place, using the abovementioned directory traversal bug, led reliably to bypasses elsewhere.
(Curiously, the authentication token used by the router wasn’t supplied as a web cookie, but embedded in an inline image object called
Reporting the bug
This directory traveral bug was duly reported to the relevant router vendor, Buffalo, and received the vulnerability identifier CVE-2021–20090.
However, the story didn’t end there, because Grant (who did his original research with a Buffalo WSR-2533DHPL2 router) eventually realised that this wasn’t so much a router vendor’s bug as a firmware vendor’s bug.
In other words, it wasn’t just Buffalo routers that were at risk.
Tenable ultimately identified and listed 37 widely-used products that all shared code from router and firmware vendor Arcadyan, including several products from Arcadyan itself.
The bug itself, it seems, has been present in Arcadyan’s code, unnoticed until now, since 2008.
Affected products include routers shipped by well-known ISPs around the world, including BT, Deutsche Telecom, KPN, O2, Orange, Telecom Argentina, TelMex, Telstra, Telus, Verizon and Vodafone.
All of these products ought to have updates available by now, but we don’t know how many products currently in use have actually downloaded and installed those updates yet.
Unfortunately, according to follow-up reports from researcher at Juniper, cybercriminals are already probing the internet for vulnerable devices.
So, if you’re affected by this bug, or think you might be, we urge you to check for updates as soon as you can.
What to do?
- Check Tenable’s list to see if your router is affected. Some routers reveal details such as model and serial numbers in their management console, so try logging in and consulting the relevant router information pages. Unfortunately, many ISP-supplied routers don’t list the original manufacturer’s name or model number on the outside of the router itself. If in doubt, consult your ISP. (Our home internet provider is on the list, but were able to infer, simply from the format of our router’s firmware version number in the console, that it was almost certainly not one of the affected models.)
- Make sure you have your router’s latest firmware. Even if you aren’t on the danger list this time, use this as a good reason to check that you are up-to-date anyway. Some ISPs, such as ours, set up their routers to update automatically, but it’s still worth making regular checks to ensure that those updates are being installed and applied as expected.
- Avoid turning on remote access to your router’s management console. Most modern routers restrict access to the web console to the internal network only by default, but include an option to enable remove access if you want. Make sure this option is turned off unless you are absolutely certain you need it. There is no point in exposing your router’s web server directly to the internet unnecessarily.
- Never enable remote access to your router on the say-so of someone you don’t know. Crooks often contact you via email or phone claiming that they are “there to help”, and then demand remote access to your router or your computer to “fix” an imaginary “problem”. These technical support scammers often brashly claim to be from Microsoft, Google, your ISP or even from the police. They may become threatening and aggressive when challenged. Don’t be intimidated. You didn’t ask for help, so you do not need to accept it – just hang up or ignore their emails, and consult someone you know and trust instead.
- If you are a programmer, verify all your input. Any software that accepts data supplied across the network must assume that any input that it receives might be booby-trapped to probe for vulnerabilities. System commands, directories and filenames need special care because there are many characters and character sequences that have a special meaning when used in those contexts, like the infamous “dot-dot” sequence mentioned above.
HOW TO PROBE FOR THE BUG ON YOUR OWN NETWORK
According to Tenable’s report, you can perform a basic test on your own router by finding the URL for a page that you know exists, such as
http://[router]/home.htm, and verifying that it comes up if you visit it.
Then you try to visit the same page via the “go up one” trick described above, and verify that the page does not come up, which is evidence that the directory traversal bug CVE-2021-20090 either doesn’t exist or has already been patched on your device.
From the command line, you could use the
curl program, available on Windows, Mac or Linux, as shown here.
You need to replace the text
[router] with the name or IP number of your own router – if you aren’t sure what that is, try
You also need to find a web page such as
login.html that exists on your device, and that produces some content whether you are logged in or not:
$ curl -D - http://[router]/home.htm <-- "-D -" says to dump the headers as well as the body HTTP/1.0 200 OK <-- Here comes the HTTP response Server: httpd <-- Followed by the headers Date: Tue, 10 Aug 2021 14:05:01 GMT Content-Type: text/html [. . .] <-- Followed by a blank line <!DOCTYPE html> <-- Followed by the HTML data <html lang="en" <head> <title>Home</title> [. . .]
If your router is vulnerable, then trying to access the same page via the filename
/images/../home.htm should give the same result as above, because that implies your router will accept the “dot-dot” directory traversal trick.
If your router is not vulnerable to CVE-2021-20090, then the directory traversal will fail and the “dot-dot” trick will not work, which should result in a “404 Not Found” error.
Note that you can’t just write
/images/../home.htm in the URL, because
curl, or your browser, will automatically simplify it before making the request.
You need to represent the third slash character in the URL with its hexadecimal URL “escape code”
%2F (the ASCII encoding of
/), like this:
$ curl -D - http://[router]/images/..%2Fhome.htm <-- Try to exploit a directory traversal "go up" trick HTTP/1.0 404 Not Found <-- A 404 error suggests that the exploit *failed* Server: httpd Date: Tue, 10 Aug 2021 14:13:32 GMT Content-Type: text/html [. . .] <HTML> <-- Followed by some kind of message to say so <HEAD><TITLE>404 Not Found</TITLE></HEAD> <BODY<H4>404 Not Found</H4> [. . .]