Buffer Overflow Vulnerability in TP-Link Routers Can Allow Remote Attackers to Take Control

Internet routers are among the most ubiquitous devices home and business users depend on every day to carry out communications, banking, shopping and commercial transactions. IBM Security researcher Grzegorz Wypych (aka h0rac) took a closer look at one of the most widespread internet routers in use by consumers nowadays, the TP-Link WR-940, and found that a zero-day buffer overflow vulnerability in the router could allow malicious third parties to take control of the device from a remote location.

Let’s dive into more details about this vulnerability, which has been responsibly disclosed to TP-Link by IBM Security and was subsequently issued patches that appear in the closing words of the article.

TP-Link WR940

Figure 1: TP-Link WR940 (Source: TP-Link)

Authenticate and Control

Looking into commonly used routers, our team of ethical hackers examined some of the models that many consumers use in their homes. The reason behind examining router security is their omnipresent status and the potential for attackers to use them against internet users and businesses alike, while mostly relying on automated attacks.

This is the first part in a series of router vulnerability reports. Here, we’ll focus on the TP-Link WR940 device and touch on the software that runs the router — more specifically, TL-WR940N hardware version 3 and TL-WR941ND hardware version 6, both running firmware version 150312.

In the case of these routers, we found a zero-day buffer overflow vulnerability, one that was not previously reported and that worked for authenticated users, allowing them to take unrestricted remote control of the router.

Looking at the software security of the device, it appears that most of the effort to apply controls was put into the web-based interface that users can access to configure the router. However, controls that were placed on the owner’s interface cannot protect the actual router and could allow an attacker to take advantage of that fact.

For example, in the System Tools/Diagnostic tab of the control panel, users have the option to send Internet Control Message Protocol (ICMP) echo requests/response packets via ping. They can send packets either to an IPv4 address or to a hostname. The panel’s security controls may limit character type and number, but nothing stops the user from intercepting requests with a Burp Suite (a graphical tool for testing web application security) proxy and malforming them.

Bug by Bug

We started by looking for some common application vulnerabilities. First we examined command injections because operations such as ping are mostly executed using a Bash shell (Bash is a Unix shell and command language). This was not the case, and we had to rule out the injection attack scenario because we did not find any reference to a system call during static analysis.

What we did find was another interesting activity: When a user sends ping requests, a message is displayed on the device’s console referring to native code compiled to the firmware’s binary.

Ping requests invoke message on router's console

Figure 2: Ping requests invoke a message on the router’s console

Next, we looked at outgoing GET requests to the ping service by running a Burp Suite proxy to examine them. In the following image, we can see the request’s parameters. The same parameters also appeared in the console message shown in Figure 2.

GET request to

Figure 3: GET request to ping service

To zoom into the details, we launched the IDA disassembler and looked at some string references. More specifically, we were looking for the “Here is a new ping” reference.

GET request to ping service on IDA Pro

Figure 4: GET request to ping service on IDA Pro

From here, we jumped directly to the referenced function’s address:

# DATA XREF: sub_44C610+5E0↑o

And here, we can see a notable message block:

Message block shown in IDA Pro

Figure 5: Message block shown in IDA Pro

The syntax is written in the Microprocessor without Interlocked Pipeline Stages (MIPS) Assembly language, which is designed to work with the MIPS microprocessor paradigm created by J. L. Hennessy in 1981. It is typically used in embedded systems, such as gateways and routers.

Before we look more closely at this message block, here’s a quick crash course on MIPS central processing units (CPUs):

  • Function parameters are passed in registers $a0-$a3. If a function requires more than four parameters, it is pushed onto the stack.
  • Register $t9 is often used as a holder for the jump address. We usually load the memory address and jump to it using jalr instruction.
  • The called function must save any $s0-$sX registers, where X is the max number of available registers of type $s.
  • The return value is saved in the $v0 or $v1 registers.

Classic Buffer Overflow

Armed with these basics, we can move to the next step of the analysis. In the following image, we can see that the printf function receives a pointer to a string that appears in the console log we looked at earlier (Figure 2). The parameter in this case is being loaded to the $a0 register.

Next, we will invoke the ipAddrDispose function. This one gets loaded to the $a2 register value of 564 in decimal, which could be a parameter in the function. Let’s jump to that function and see what’s inside.

ipAddrDispose' function exposing buffer overflow issue

Figure 6: ipAddrDispose’ function exposing buffer overflow issue

We won’t go through a line-by-line analysis here; this is only a fragment of the entire function. What’s interesting about it is the strcpy function call, which is the start of the TP-Link httpd process control, the vulnerable binary. What we have here is a classic buffer overflow issue.

The function copies the input it receives byte by byte and stores it in a buffer of a size that is not properly being handled. The data therefore exceeds the buffer’s boundaries.

We have our bug, but can it truly be exploited? We can find out whether this zero-day is critical by creating a proof-of-concept of an attack scenario.

Status: Exploitable

The first action to attempt when looking at a buffer overflow is to check what happens when the data size exceeds the available space. We will therefore change the ping_addr parameter to hold number of 0x41(A)s, exceeding the buffer’s size. In the following image, the ipAddrDispose function reserves 224 bytes (hexadecimal 0xE0) for its stack frame.

ipAddrDispose reserves 224 bytes for its stack frame

Figure 7: ipAddrDispose reserves 224 bytes for its stack frame

Since the stack can take 224 byes, we elected to send through 300 bytes of A’s instead and see what happens. To do that, we modified the ping_addr parameter in the HTTP request after intercepting it with a Burp suite instance.

Sending 300 bytes of A's to limited stack

Figure 8: Sending 300 bytes of A’s to limited stack

By the following message on the console, we can see that, indeed, it is possible to override the return address $ra and begin controlling program execution.

Router console message shows that address override is possible

Figure 9: Router console message shows that address override is possible

Some Pre-Exploit Recon

Before writing an exploit, it is wise to check what is being overwritten here when the oversized payload is sent through. Let’s take a closer look at the core memory dump, which is typically dumped to the /tmp folder.

What we are looking for is information that will help craft the exploit down the line. More specifically, we want to see what registers we can control if we exploit this bug.

To analyze the core memory dump, we downloaded it to our host and placed it in the folder where the extracted file system is found (the httpd binary).

Figure 10: Analyzing TP-Link router core memory dump

Figure 10: Analyzing TP-Link router core memory dump

Remember, this is MIPS architecture. The next step here will be to open the core dump using gdb-multiarch, which is a GNU Debugger (GDB) with support for multiple architectures. GDB is a source-level debugger that is capable of breaking programs at any specific line, displaying variable values and determining where errors occurred.

Using gdb-multiarch to open core memory dump

Figure 11: Using gdb-multiarch to open core memory dump

We can now control three registers:

  1. $s0;
  2. $s1; and
  3. $ra.

The $a0 register was only partially under our control because it only refers to an address on the stack. Also, keep in mind that the exploitation is taking place on MIPS architecture, which is very different than an exploit written for web application buffer overflow bugs. With this information, we started writing a working exploit code.

Routers: A Modern-Day Essential in Dire Need of Better Security

The American Consumer Institute (ACI) looked into router security and found that no less than 83 percent of routers harbor high-risk vulnerabilities, many of which are open-source flaws. This staggering ratio accounts for both home and office routers and includes major name brands sold around the world.

Routers are not just a relay switch; they have their own operating systems, their own software and, inevitably, their own vulnerabilities. Router vulnerabilities are rather common and can be attributed to various factors. It starts with internet service providers (ISPs) issuing the same router to millions of customers and inadvertently allowing vulnerability aggregation when zero-days arise, but it has more to do with the software that runs routers.

Most manufacturers outsource firmware that gets developed with costs in mind. As such, it is rarely elaborate and, judging by the amount of router vulnerabilities out there, also rarely tested or secure. Making matters worse is the patch and update process: When was the last time you got a message prompting you to update your router’s firmware? Likely almost never. This means that even when patches are dealt with and become available to the public, most users will never know of them or know to take action.

We won’t delve into open networking ports and unsecured protocols that run home routers — think Universal Plug and Play (UPnP), Home Network Administration Protocol (HNAP) and the Wi-Fi Protected Setup (WPS) password — but those interested in further reading should look them up.

How much do these vulnerabilities matter? A lot. At the very least, router vulnerabilities can lead to consumer data being compromised and used by attackers. The same issue can allow criminal/nation-state third parties to spy on users, send them to phishing and malware-hosting websites, or alter data the user sends out when browsing the internet. Routers can also be infected by malware and enslaved by a malicious internet of things (IoT) botnet such as VPNFilter, which can eavesdrop on traffic passing through the router, or the Mirai botnet, which disrupted internet connections as well as telephony and television services in Germany for days before it was possible to stop the mayhem.

Vulnerabilities on routers used by businesses can have similar impacts at scale and likely touch on even more valuable information that could interest cybercriminals and nation-state threat actors alike.

Secure Development, Testing and Better Controls

Limiting the vulnerability of any software to attacks is a task that calls for security in the early stages of the development cycle. The sooner security professionals are introduced to the project, the better the chances are that the end result will be more secure; as a bonus, it is also likely to be much less costly. If that is not a possibility, not all is lost: Scanning code after it is written can also help fix issues and make it more resilient to attacks.

Another way to find and fix issues after devices have been released to the marketplace is by testing them. Penetration testing should look at both code-related security gaps and hardware-related exploitation possibilities. When these are found, they should be prioritized for remediation and addressed promptly to secure the user base from potential attacks.

Router vendors can better enable users with additional security controls: longer password standards, two-factor authentication (2FA) options, more warning prompts when remote access can be attained by unauthorized parties, and the ability to separate modem and router functions, to name a few. Routers are an essential part of almost every home’s communication consumption, and security has become equally essential to keep those homes and their residents’ data and privacy safe.

TP-Link Patches for Users of These Models

After disclosure, TP-Link’s security team released a patch and indicated that both devices in these hardware versions are no longer being manufactured (product end of life).

The new firmware has been published on the website for both devices in their affected hardware revisions (firmware is labeled 190218).

Support/Download Page Links


Grzegorz Wypych

Software Developer – IBM

Grzegorz Wypych loves to work with MIPS/ARM assembly code and hunt for 0-days in IoT devices. He may have started his...