Wipe Out! Hanging (More Than) Ten On Your Old Belkin SURF Router

August 01, 2019 | Vincent Lee

In June 2019, we released a blog post on setting up hardware debugging on the Belkin SURF N300 router. In this blog, we are going to examine more than 10 vulnerabilities reported by Josep Pi Rodriguez and Pedro Guillén Núñez on this platform. Belkin has acknowledged our bug reports, but Belkin stated that the product is end-of-life and is no longer supported. The vulnerabilities affect the Belkin SuperTask! RTOS, specifically the UPnP functionality. It includes multiple stack-based buffer overflows in AddPortMapping, GetSpecificPortMappingEntry, and DeletePortMapping SOAP actions along with buffer overflows in upgrade.exe, dnsproxy, and dhcpd.

These bugs were originally discovered by the submitters through analyzing the firmware of the Belkin N150 (Model F9K1001) and Belkin N300 (Model F9K1002). We verified the reports on the Belkin N300 (Model F7D2301v1) router.

Universal Plug and Play

Universal Plug and Play (UPnP) is designed to simplify network configuration for general consumers and aims to for everything to “just work”. This is done by allowing local clients to configure the router. However, this assumes all local clients are trustworthy. Malware can easily take advantage of this feature to punch holes through the firewall of UPnP enabled routers. UPnP is generally agreed to be unsafe and many, including the FBI, have recommended consumers to disable and discontinue the use of this feature.

The researchers discovered the UPnP WANPPPConnection:1Service [PDF] is vulnerable to multiple stack buffer overflow vulnerabilities. When the router processes the AddPortMapping SOAP action, the router calls strcpy() to copy the attacker-controlled NewRemoteHost argument into a stack buffer with a fixed size of 0x20 bytes without verifying the size of the argument.

Figure 1: A malicious UPnP request that triggers the vulnerability

When the router processes the request in Figure 1, the overly long NewRemoteHost argument is blindly copied to the undersized stack buffer by strcpy(). As a result, strcpy() writes past the end of the stack buffer and overwrites the return address of the function with attacker-controlled data. When the vulnerable function returns, it attempts to return to the overwritten return address 0x41414141. The crash will then be logged in the serial terminal and the router will reboot.

Figure 2: Serial terminal crash log

In the following diagram, we can see the vulnerable strcpy() function call. At 0x80178C90, the fixed-sized stack buffer pointer is stored in register $a0. At 0x80178C98, the attacker-controlled buffer pointer is stored in the $a1 register. Even though this instruction comes after the jal strcpy instruction, this delay slot instruction is executed after the branch due the MIPS CPU architecture of our target.

Figure 3: Diagram showing the vulnerable `strcpy()` function calls

There are 13 bugs residing in this UPnP service handler and all have similar root cause. In fact, in the above diagram, we can see another vulnerable strcpy() call at 0x80178CCC. More strcpy() calls can be found by following the cascading if-else blocks. In Figure 4 (below), each vulnerable strcpy() call has been colored in red:

Figure 4: Control flow diagram that highlights all vulnerable `strcpy()` calls within the function

Stack-buffer overflow exploitation mitigations such as ASLR and stack canary were not observed. Exploiting these vulnerabilities is straight forward. An exploiter writer may simply overwrite the program counter address with the shellcode address to execute arbitrary code.  

Back door accounts

In addition to buffer overflow vulnerabilities, the researchers have also discovered hardcoded backdoor account credentials embedded within the firmware.

Figure 5: Shows the hardcoded backdoors within in the firmware

There are three backdoor accounts in total: “engineer”, “wlan_config”, and “wlan_power”. These accounts are not exposed to the web interface, and the end users have no means to remove or modify them. When the attacker makes the following request, the attacker IP will be marked as “logged in”. The attacker may then access privileged pages from the authenticated IP.

Figure 6: Shows an authentication HTTP request using the hardcoded “wlan_config” credentials

Once the authentication is bypassed, the attacker may exploit other post-authentication vulnerabilities, a buffer overflow in the privileged upgrade.exe CGI script. This buffer overflow vulnerability is caused by copying the attacker-controlled multi-part HTTP POST request boundary header value into a global variable using strcpy().

Figure 7: A malicious HTTP POST request with an overly long boundary value

Figure 8: Disassembly showing the code around the vulnerable `strcpy()` call

In the above diagram, the attacker-controlled data is stored in $a1 and the vulnerable global buffer is at address 0x802965CA. When the malicious request is sent, the router logs the following crash to the serial terminal and reboots.

Figure 9: Serial terminal crash log

Specially crafted DNS packets

This stack buffer overflow vulnerability affects the DNS Proxy of the router. When processing a specially crafted DNS packet, the router copies attacker-controlled data into a stack buffer of size 80 bytes using memcpy(). The buffer overflow occurs due to a mismatch in destination buffer size and the number of bytes parameter passed to memcpy().

Figure 10: A malicious DNS request

When the above DNS message is sent to the vulnerable router, the following exception log will be outputted to the serial terminal and the device will reboot:

Figure 11: Serial terminal crash log

Again, we can see the program counter has been overwritten by an attacker-controlled address (0x42424242). We can see the vulnerable memcpy() call in the diagram below:

Figure 12: Disassembly showing the code around the vulnerable memcpy() call

At 0x80119D48, the number of bytes parameter passed to memcpy() is being calculated by subtracting two pointers. The resultant value is larger than the size of the destination buffer, as a result, memcpy() blindly copies past the end of the destination buffer and results in an overflow.

Conclusion 

The presence of a large number of vulnerabilities with similar root causes residing in different components of the firmware shows a lack of secure software development lifecycle practices during product development. This strongly suggests even more vulnerabilities exist within the firmware. In fact, our conjecture was proved to be true.  During the disclosure phase of these vulnerabilities, the researchers submitted additional bugs concerning this product. However, we have declined to offer on the submissions as we learned that the product is no longer supported and the vendor is no longer providing patches.  That said, they are interesting case studies for researchers looking to learn to vulnerability research in embedded systems.

We recommend end users to upgrade their vulnerable router to one that is currently under active support by its vendor.

I hope to see your hardware-related submissions in the future. Until then, you can find me on Twitter @TrendyTofu, and follow the team for the latest in exploit techniques and security patches.