Seamlessly Discovering Netgear Universal Plug-and-Pwn (UPnP) 0-days

Introduction

A Vulnerability Researcher’s Favorite Stress Relief

Continuing in our series of research findings involving Netgear1 products,2 this blog post describes a pre-authentication vulnerability in Netgear SOHO Devices that can lead to Remote Code Execution (RCE) as root. While our previous research investigated the Netgear web server and update daemons, the issues described in this blog revolve around the device’s UPnP daemon. Anyone with Small Offices/Home Offices (SOHO) device vulnerability research experience will be familiar with UPnP. UPnP servers allow any unauthenticated device on the network to connect to the server and reconfigure the network to support its operations. For instance, the Xbox One uses UPnP to configure port forwarding necessary for gameplay. However, this service provides a large attack surface for the device, as it must allow unauthenticated requests and parse complex input to handle those requests. Further, the UPnP service on SOHO devices has previously been exploited in the wild.3

In addition to detailing the vulnerability and exploitation process, this blog post also describes how an incorrect patch in a few of Netgear’s devices actually prevents exploitation. As always, the write-up and code for the vulnerability described in this blog post can be found in our NotQuite0DayFriday repository. While this research was conducted internally at GRIMM, the bug was not initially disclosed by us to Netgear. Prior to our planned disclosure date, Netgear released a patch that fixed the underlying bug in one of the affected devices.

Bug identification

Netgear SOHO Devices upnpd Service Pre-Authentication Stack Overflow

  • Vulnerability Type: Pre-Authentication Stack Overflow

  • Location: gena_response_unsubscribe function in the upnpd daemon

  • Affected devices and versions listed in Table 1

  • Fixed versions: see Netgear security bulletin

  • Impact: RCE as root on the device by an unauthenticated attacker on the device’s LAN.

These devices are vulnerable, but the vulnerable feature within upnpd has been broken by a previous vulnerability mitigation, and thus they cannot be exploited. See the Broken Functionality section below for more information.

The upnpd daemon accepts unauthenticated HTTP SUBSCRIBE and UNSUBSCRIBE requests from clients that wish to receive updates whenever the network’s UPnP configuration changes. The gena_response_unsubscribe function handles the UNSUBSCRIBE requests. This function (shown in Figure 1) copies 512 bytes of the HTTP request to a local stack buffer, converts it to lowercase (via strlwr), and then validates that it contains the strings sid:, host:, and uuid:.

Figure 1: Pre-authentication stack overflow in gena_response_unsubscribe
 
Afterwards, it calls find_token_get_val function to parse the UUID header (i.e. get the value between the strings uuid: and \r\n). The find_token_get_val function’s 4th argument is used to return the parsed value to the caller; find_token_get_val will copy the parsed value of at most 1024 characters to this argument (as shown in Figure 2).
Figure 2: strncpy with assumed 1024 length in find_token_get_val
 
However, the uuid_buffer stack buffer passed to this function from gena_response_unsubscribe is only 64 bytes. As such, an attacker can overflow this stack buffer and control the saved registers and return address on the stack. The stack layout during the overflow is depicted in Figure 3.
 
Figure 3: stack layout during the stack overflow

Technical analysis

This section describes a Proof of Concept (PoC) exploit developed for the vulnerability that can reset the administrator password or execute arbitrary commands on a vulnerable device.

UUID Exploit

This stack overflow is a traditional stack overflow that is not protected by any modern vulnerability mitigations. However, exploitation of this stack overflow is complicated by a few factors:

  1. Prior to overflowing the stack, the buffer with the user’s input is converted to lowercase. As a result, the exploit cannot use any gadgets which contain bytes with capital letters (ASCII 0x41-0x5A).

  2. The copy which overflows the stack is a string copy. As such, it will stop copying characters if it encounters a NULL character. Thus, the exploit cannot include gadgets with NULL bytes.

While the first limitation can be easily avoided by carefully choosing gadgets, the second limitation is much more difficult to bypass. All of the addresses within the upnpd daemon contain a NULL character as the Most Significant Byte (MSB). Further, the exploit cannot specify a library address either. While the main upnpd executable does not support Address Space Layout Randomization (ASLR), the Linux kernel will automatically randomize the address of any loaded libraries. Thus, the exploit cannot know where the libraries are loaded. Instead, the PoC bypasses this limitation by omitting the gadget’s MSB in the payload, and then immediately ending the payload. The string copy which overflows the stack will automatically NULL terminate the string, and thus write a single NULL byte for us. However, this technique has the disadvantage that it can only write a single NULL byte at the end of the payload. As such, the exploit can only run a single gadget via this technique.

The PoC implements two separate techniques for converting the execution of a single gadget into a useful effect. The first technique simply jumps to the code shown below, which resets the web server password to the string password:

acosNvramConfig_set("http_passwd", "password");

The second technique jumps to a gadget which adds 0x1000 to the stack, and then continues loading gadgets. This gadget skips several stack frames to find the raw HTTP request received by the upnpd daemon. The raw HTTP request is not limited in the characters it can contain, and has not been modified from the value initially received. By loading addresses from the raw HTTP request, the PoC can include gadgets with NULL and upper case characters. This process is illustrated in Figure 4. With the ability to call arbitrary gadgets, the PoC can now call a system gadget to run a custom command. As the upnpd daemon’s machine code does not always contain a system gadget with the command on the stack, the PoC first stores the command to run in a global variable, and then references that variable when calling a non-stack based system gadget.

Figure 4: Stack pointer redirection

Testing

A Python script, upnp_uuid_exploit.py has been provided that will exploit the UUID vulnerability in the upnpd daemon. If not specified, the exploit will automatically determine the device’s model and version by querying the device’s web server for the /currentsetting.htm page. This page contains the model and version information and is available without authentication on most Netgear devices. Figure 5 demonstrates the PoC against a Netgear XR300 router. By default, the PoC will reset the web server’s password to password. Once the exploit has finished, the attacker will be able to login to the web server and modify any settings or launch further attacks on the web server. Alternatively, the PoC exposes the -rce-exploit option which will cause the PoC to send a RCE payload instead. However, the PoC only supports RCE payloads for a smaller subset of the affected devices. The RCE exploit will execute a custom command, which by default will start the telnet daemon on port 3333.

Figure 5: The UUID handler stack overflow PoC exploiting the upnp server on the XR300

The PoC has been written for and tested against the list of device and versions below. Additional devices can be added by analyzing the firmware images to find the necessary gadgets.

  1. R7000 version 1.0.11.100, 1.0.11.106, and 1.0.11.110

  2. XR300 version 1.0.3.56 and 1.0.3.38

  3. R6700v3 version 1.0.4.118

Broken Functionality

In some firmwares, the handle_subscribe_unsubscribe function, which calls the vulnerable gena_response_unsubscribe function, contains an incorrect fix for a previous stack buffer overflow (shown in Figure 6). This stack overflow occurred when the user input (up to 8191 bytes) is copied into a 512-byte stack buffer at the beginning of handle_subscribe_unsubscribe. However, beginning in version 1.0.11.116 of the R7000, the strcpy was converted to a strlcpy(beginning_of_input, all_input, 4) call. As such, only the first 3 bytes of the user’s input are copied to the stack buffer (leaving 1 byte for the terminating NULL character). This stack buffer is then parsed to respond to the request, which obviously cannot be done with only the first 3 bytes of the request. As a result, all UPnP SUBSCRIBE and UNSUBSCRIBE requests are broken in the R7000 in version 1.0.11.116 and later. Thus, the vulnerable UUID handling code within upnpd cannot be reached and these firmware images are not vulnerable to the UUID stack overflow vulnerability. However, once this functionality is fixed, the vulnerable code will once again be reachable, and the devices will be exploitable again.

Figure 6: Broken SUBSCRIBE and UNSUBSCRIBE handling within the R7000 1.0.11.123 firmware

While only the developers know the source of this incorrect patch, we can make an educated guess. As the size of a pointer on the R7000 is 4-bytes (32-bits), it’s likely that the incorrect patch is the result of the sizeof operator incorrectly being applied to a pointer type.4 For instance, consider the following strlcpy code:

char beginning_of_input[0x200];
char *beginning_of_input_ptr = beginning_of_input;
// wrong: beginning_of_input_ptr type is char*, size 4
strlcpy(beginning_of_input_ptr, input, sizeof(beginning_of_input_ptr));
// right: beginning_of_input type is char[0x200], size 0x200
strlcpy(beginning_of_input_ptr, input, sizeof(beginning_of_input));

If the sizeof operator is passed the beginning_of_input_ptr pointer, rather than the beginning_of_input character buffer, it will return a size of 4. 

While disabling the SUBSCRIBE and UNSUBSCRIBE request handlers in this way prevents exploitation of this vulnerability, it also will prevent legitimate applications from using this functionality. UPnP event subscriptions are used in home automation systems, such as SmartThings5 and Homebridge,6 to detect changes within devices on their network. Without a working event subscriptions system, they won’t be able to detect changes within the SOHO device.

Other models within the same codebase, such as the RS400, have not fixed the original bug, as shown in Figure 7.

Figure 7: Unmitigated strcpy within the SUBSCRIBE and UNSUBSCRIBE handler in the RS400 1.5.0.68 firmware

However, most models, such as the XR300, have fixed it correctly, as shown in Figure 8. In either case, the vulnerable UUID handler is reachable and can be exploited.

Figure 8: Correct SUBSCRIBE and UNSUBSCRIBE handling within the XR300 1.0.3.56 firmware

Impact

The impact of this vulnerability is that attackers on the LAN of the affected devices can compromise vulnerable devices, leading to code execution as root. Since the upnpd daemon runs as root, the highest privileged user in Linux environments, the code executed on behalf of the attacker will be run as root as well. With root access on a device, an attacker can read and modify all traffic that is passed through the device. For example, if an employee connects to a corporate network via a compromised router, the router could Man-in-the-Middle (MitM) the connection and read any unencrypted data sent between the user’s device and devices on the corporate network. Additionally, a compromised router or modem could be used to attempt to exploit any of the devices on its network.

Vendor response

While putting the finishing touches on the disclosure report, Netgear released a security bulletin and patch for this vulnerability for the R6700v3. Since the patch only covered one of the many affected devices, GRIMM decided to go forward with the disclosure to ensure that Netgear was aware of the full impact of the vulnerability as well as the extent of the affected devices. Before the end of the 45-day disclosure period, Netgear was able to release an updated security bulletin as well as patches for all of the affected devices that are still actively maintained. It should be noted that some of the devices on GRIMM’s coverage list are no longer actively supported by Netgear, so for those devices this is an evergreen vulnerability.

Conclusions

This report detailed a vulnerability in the UPnP daemon included in many Netgear SOHO Devices. Exploitation of this vulnerability allows attackers on the affected device’s network to obtain RCE as root on the SOHO device. The exact list of devices affected by these vulnerabilities is included in the Bug Identification section.

For many organizations, SOHO devices typically fly under the radar when it comes to cybersecurity risk management. However, the significant increase in employees remotely connecting to corporate networks (e.g. due to updated work-from-home policies brought into practice as a result of COVID-19) has similarly increased the risk to corporate networks from vulnerabilities in SOHO devices. To mitigate the risks to corporate environments posed by vulnerable SOHO devices, GRIMM recommends the provisioning and use of Virtual Private Network (VPN) clients. These clients should be configured to handle all traffic to ensure that an attacker cannot read or modify network traffic in a way that cannot be detected by the VPN endpoints. Additionally, typical hardening techniques, such as enabling a host-based firewall, will help prevent a compromised device from being used to pivot an attack into the corporate-owned devices.

Timeline

  • 09/16/2021 - Vendor release security advisory for the R6700v3

  • 09/28/2021 - Disclosed additional affected devices to vendor

  • 11/09/2021 - Vendor releases security advisory and patches

  • 11/16/2021 - NotQuite0DayFriday release

  • 11/16/2021 - Blog release

GRIMM’s Private Vulnerability Disclosure (PVD) program

GRIMM’s Private Vulnerability Disclosure (PVD) program is a subscription-based vulnerability intelligence feed. This high-impact feed serves as a direct pipeline from GRIMM’s vulnerability researchers to its subscribers, facilitating the delivery of actionable intelligence on 0-day threats as they are discovered by GRIMM. We created the PVD program to allow defenders to get ahead of the curve, rather than always having to react to events outside of their control.

The goal of this program is to provide value to subscribers in the following forms:

  • Advanced notice (at least two weeks) of 0-days prior to public disclosure. This affords subscribers time to get mitigations in place before the information is publicly available.

  • In-depth, technical documentation of each vulnerability.

  • PoC vulnerability exploitation code for:

    • Verifying specific configurations are vulnerable

    • Testing defenses to determine their effectiveness in practice

    • Training

      • Blue teams on writing robust mitigations and detections

      • Red teams on the art of exploitation

  • A list of any indicators of compromise

  • A list of actionable mitigations that can be put in place to reduce the risk associated with each vulnerability.

The research is done entirely by GRIMM, and the software and hardware selected by us is based on extensive threat modeling and our team’s deep background in reverse engineering and vulnerability research. Requests to look into specific software or hardware are welcome, however we can not guarantee the priority of such requests. In addition to publishing our research to subscribers, GRIMM also privately discloses each vulnerability to its corresponding vendor(s) in an effort to help patch the underlying issues.

If interested in getting more information about the PVD program, reach out to us.

Working with GRIMM

Want to join us and perform more analyses like this? We’re hiring. Need help finding or analyzing your bugs? Feel free to contact us.


  1. https://blog.grimm-co.com/2020/06/soho-device-exploitation.html↩︎

  2. https://blog.grimm-co.com/2021/09/mama-always-told-me-not-to-trust.html↩︎

  3. https://arstechnica.com/information-technology/2018/11/mass-router-hack-exposes-millions-of-devices-to-potent-nsa-exploit/↩︎

  4. https://cwe.mitre.org/data/definitions/467.html↩︎

  5. https://www.smartthings.com/↩︎

  6. https://homebridge.io/↩︎

Popular posts from this blog

New Old Bugs in the Linux Kernel

Automated Struct Identification with Ghidra

SOHO Device Exploitation