I recently bought a new DIR-842 home router, and immediately (as any hacker would) started toying with it - I can’t call it mine until I pop a shell on it.
Rather quickly I found I can enable telnet through the admin web gui, and then connect to telnet with an admin user. But that was too easy, so let’s see if we can find a bug/vulnerability.
I continued looking for a bug in the router’s telnet implementation because it’s an attractive target: it’s remotely accessible, and as learned by previously connecting as system admin, it runs with high privileges. Also, instead of searching for a memory corruption vulnerability, I focused on finding a more easily exploitable logic vulnerability.
CVE-2021-27342 Brute Force Protection Bypass
The router’s telnet authentication is protected with an anti-brute force mechanism that limits an attacker’s password guessing speed by delaying the “access denied” response of failed logins. However, this protection’s implementation opens the door to a timing-based side-channel attack.
Since there is a delayed response for invalid logins only, an attacker can send a telnet login request and then only wait, for example, 0.05(1) seconds to figure out if the password was correct. If the login credentials are valid, a “Welcome” response would be immediately sent back. Otherwise, if the password was incorrect, nothing will be sent back.
So after 0.05 seconds the attacker knows if the password was correct, and if it wasn’t, the attacker can create a new connection to try another password right away. This bypasses the intended 3 second cool-down period between failed login attempts.
Proof of concept code on github
Product page on vendor website with router specs. This vulnerability has been patched and an update is available on the vendor website.
(1) 0.05 seconds worked consistently on my router setup. This number might need tweaking on yours, depending on network latency.
More Detailed Router Telnet Adventures
I found this vulnerability through black-box testing, but was eager to see the vulnerability in the router’s code, too. Well, most likely in this case, its assembly. This is a bit about my research process for readers that want an overview of my research approach.
First, through the telnet shell I looked at the running processes with
ps and found
telnetd is the name of the telnet daemon executable file (pretty standard). Next, I ran a recursive file listing from the root directory with
ls -R / to find
/usr/sbin/telnetd. Finally, I copied the file to my own computer for IDA fun and analysis. The router didn’t have
ftp or other file transfer tools, so I used
hexdump -ve '1/1 "%.2x"' /usr/sbin/telnetd and copy pasted the output to a hex editor and then saved it as a new file - it’s not stupid if it works!
After disassembling the executable with IDA, I looked for xrefs to
sleep. That’s how I would, and I think other programmers would too, naively implement a brute-force delay.
Jackpot! I found a function that lightly wraps sleep - I called this function
sleep_zzz_nap_time pictured below.
sleep_zzz_nap_time is called from the login-handling function right before sending a
“Login incorrect” response:
Further confirming this is the code that is indeed in charge of the delay, the
3 that’s passed to
sleep_zzz_nap_time matches the 3 second wait period after trying to login with an incorrect password.
While exploring the router’s programs and file system, I also copied out it’s web server binary and configuration files, which could be useful in future research on this router.
Until next time!