SOHO Device Exploitation
Netgear R7000
SOHO Device Exploitation
Initial Analysis
While the router may have many services worth analyzing, the web server is often the most likely to contain vulnerabilities. In SOHO devices like the R7000, the web server must parse user input from the network and run complex CGI functions that use that input. Furthermore, the web server is written in C and has had very little testing, and thus it is often vulnerable to trivial memory corruption bugs. As such, I decided to start by analyzing the web server, httpd.
As we’re interested in how the web server (mis)handles user input, the logical place to begin analyzing the web server is the recv function. The recv function is used to retrieve the user input from a connection. Thus by looking at the references to the recv function in the web server, we can see where the user input begins. The web server has two helper functions which call recv, one used in the http parser and one used to read the responses from Dynamic DNS requests to oemdns.com. We’ll focus on the former use, as shown below in the Hex-Rays decompiler:
After the call to read_content (the recv helper function), the parser does some error checking, combines the received content with any previously received content, and then looks for the strings name="mtenFWUpload" and "\r\n\r\n" in the user input. If the user input contains these strings, the rest of the user input after these strings is passed to the abCheckBoardID function. Grepping the firmware’s root file system, we can see that the string mtenFWUpload is referenced from the files www/UPG_upgrade.htm and www/Modem_upgrade.htm, and thus we can conclude that this is part of the router’s upgrade functionality.
1996 Called, They Want Their Vulnerability Back
In most modern software, this vulnerability would be unexploitable. Modern software typically contains stack cookies which would prevent exploitation. However, the R7000 does not use stack cookies. In fact, of all of the Netgear products which share a common codebase, only the D8500 firmware version 1.0.3.29 and the R6300v2 firmware versions 1.0.4.12-1.0.4.20 use stack cookies. However, later versions of the D8500 and R6300v2 stopped using stack cookies, making this vulnerability once again exploitable. This is just one more example of how SOHO device security has fallen behind as compared to other modern software.
Exploit Development
In addition to lacking stack cookies, the web server is also not compiled as a Position-independent Executable (PIE), and thus cannot take full advantage of ASLR. As such, it’s trivial to find a ROP gadget within the httpd binary, such as the one shown below, that will call system with a command taken from the overflown stack.
The exploit in GRIMM’s NotQuite0DayFriday repository uses this gadget to start the telnet daemon as root listening on TCP port 8888 and not requiring a password to login.
As the vulnerability occurs before the Cross-Site Request Forgery (CSRF) token is checked, this exploit can also be served via a CSRF attack. If a user with a vulnerable router browses to a malicious website, that website could exploit the user’s router. The developed exploit demonstrates this ability by serving an html page which sends an AJAX request containing the exploit to the target device. However, as the CSRF web page cannot read any responses from the target server, it is not possible to remotely fingerprint the device. Rather, the attacker must know the model and version that they are exploiting, as shown below.
Automating the Process
A lot of SOHO devices share a common software base, especially among devices created by the same manufacturer. As such, a vulnerability in one device can normally be found in similar devices by the same manufacturer. In this particular case, I was able to identify 79 different Netgear devices and 758 firmware images that included a vulnerable copy of the web server. This vulnerability affects firmwares as early as 2007 (WGT624v4, version 2.0.6). Given the large number of firmware images, manually finding the appropriate gadgets is infeasible. Rather, this is a good opportunity to automate gadget detection.
Included in GRIMM’s NotQuite0DayFriday repository is the find_arm_gadget.sh and find_mips_gadget.sh shell scripts. The find_arm_gadget.sh shell script uses objdump and grep to look for the needed gadget, as shown below. While the R7000 has an ARM processor, some of the other vulnerable devices use a MIPS processor. Unlike ARM, objdump cannot easily resolve the function names of functions being called in a MIPS binary. As such, the MIPS gadget identification scripts use IDAPython in order to identify the gadgets for a binary. Using these sets of scripts, I was able to create an exploit for each of the 758 vulnerable firmware images. Afterwards, I manually tested the exploit on 28 of the vulnerable devices to ensure that the identified gadgets worked as expected.
Version Detection
The last step before exploitation can reliably be achieved is to remotely detect the model and version of the router. Thankfully, almost all of the vulnerable versions listen for requests to the URL /currentsetting.htm and return the model and version of the device. As such, remotely fingerprinting a device is trivial. The published exploit for the vulnerability described in this blog post automatically determines the target model and version using this approach.
Conclusion
On 6/15/2020, ZDI published an advisory by d4rkn3ss from VNPT ISC on this vulnerability. We discovered the issue independently and reported the vulnerability directly to Netgear on 5/7/2020. ZDI's advisory can be read at https://www.zerodayinitiative.com/advisories/ZDI-20-712/
Want to join us and exploit some binaries? We’re hiring. Need help auditing or exploiting your binaries? Feel free to contact us.