This chapter covers the topic of exploiting embedded devices. This topic is becoming increasingly important with the emergence of the Internet of Things (IoT), as covered in previous chapters. From elevators to cars, toasters, and everything “smart,” embedded devices are becoming ubiquitous, and the security vulnerabilities and threats are becoming innumerable. As Bruce Schneier has observed, it is like the Wild West of the 1990s all over again; everywhere we look, there are vulnerabilities in these embedded devices. Schneier explains that this is because of many factors, including the limited resources of the devices themselves and the limited resources of the manufacturers in the low-margin field of producing embedded devices.1 Hopefully, more ethical hackers will rise to meet this challenge and make a dent in the tide of vulnerabilities of embedded devices. To that end, in this chapter, we discuss the following topics:
• Static analysis of vulnerabilities in embedded devices
• Dynamic analysis with hardware
• Dynamic analysis with emulation
Static analysis of vulnerabilities involves looking for vulnerabilities by inspecting the update packages, file systems, and binaries of the system without having to power up the device being evaluated. In fact, in most cases, the attacker doesn’t need to have the device to do most of the static analysis. In this section, you are exposed to some tools and techniques for conducting static analysis on an embedded device.
In most cases, the update packages for the device can be downloaded from the vendor site. Currently, most updates are not encrypted and therefore can potentially be deconstructed with various tools such as unzip, binwalk, and Firmware Mod Kit. For instruction purposes, we will look at a Linux-based system since you are most likely familiar with these systems.
In Linux-based embedded systems, the update packages often contain a new copy of all the essential files and directories required to operate the system. The required directories and files are referred to as the root file system (RFS). If an attacker can gain access to the RFS, they will have the initialization routines, web server source code, any binaries that are required to run the system, and possibly some binaries that provide the attacker with an advantage when attempting to exploit the system. For example, if a system uses Busybox and includes the telnetd server, an attacker might be able to leverage the Telnet server to provide remote access to the system. Specifically, the telnetd server included in Busybox provides an argument that allows it to be invoked without authentication and bind to any program (/usr/sbin/telnetd –l /bin/sh).
As an example, we will investigate an older version of the D-Link DAP-1320 wireless range extender’s firmware update (version 1.1 of the A hardware). This update was chosen because it is an older update that has been patched, and the vulnerability disclosure (www.kb.cert.org/vuls/id/184100) was reported by several of the authors.
The first step is to create the environment for deconstructing the firmware. In our case, we will use the Firmware Mod Kit. The base host system for our analysis is Kali Linux 2017.1. In order to install the Firmware Mod Kit, the prerequisites must first be installed using the package manager apt-get . Once the prerequisites are met, the install only requires cloning the project from GitHub
. The first time extract-firmware.sh is run, it compiles the necessary tools and results in a lot of output (the first run has been omitted in the example). We then attempt to extract the firmware
, and if the package and content types are known by the tool, they will be extracted for further analysis. From the output, we can see that the tool has found both an MIPS Linux kernel image
and a squashfs file system
, and they have been successfully extracted to the fmk directory
. By browsing the extraction, we identify it to be the rootfs
and verify that the binaries are compiled for MIPS
.
Now that the update package has been extracted, it is time to browse the files, looking for features, configurations, or unknown applications. Table 24-1 defines some items to look for while browsing.
Table 24-1 Examples of Interrogating the File System
NOTE Any executable or library found that has a version needs to be cross-checked against known vulnerabilities. For example, use a Google search of <name> <version number> vulnerability.
Once you’ve collected all this information, you will want to understand what is processing requests from the browser or any services running. Because I’ve already done all the preceding steps, I reduced the following example in order to make the analysis more condensed and straightforward. The web server was found to be lighttpd , which uses lighttpd*.conf
and modules.conf
for the configuration. Furthermore, it uses cgi.conf
, which points almost all handling to /bin/ssi
(a binary executable).
At this point, we have an idea of how to proceed and will begin our vulnerability analysis.
At this point, vulnerability analysis is not much different from what has been taught in previous chapters. Command-injection, format-string, buffer-overflow, use-after-free, misconfiguration, and many more vulnerabilities can be searched for. In this case, we will use a technique to find command-injection-type vulnerabilities in executables. Since /bin/ssi is a binary, we will look for format strings that use %s (for string) and then redirect the output to /dev/null (meaning we don’t care about the output). This pattern is interesting because it may indicate a sprintf function that’s creating a command, with a potentially user-controlled variable, to use with popen or system. For example, a command to see if another host is alive might be created as follows:
If the variable is controlled by the attacker and not sanitized, and the cmd is used to execute in a shell, the attacker can inject their command into the intended command. In this case, we have two interesting strings that appear to download a file:
Armed with these two strings, we will begin to do some reversing of the binary to see if we have control over the variable, URL. IDA Pro will be our tool of choice for this exercise.
The main objective of the IDA Pro analysis is to determine whether the string is used in a way that the attacker has a chance to alter it. After opening the ssi binary in IDA Pro and ensuring that the processor is set to MIPS, we then take the following steps:
1. Search for the string of interest.
2. Determine how the string is used.
3. Determine where the URL comes from (if it is hardcoded, we are not interested in it).
Press ALT-T to bring up the text search screen and then select Find All Occurrences for the string, as shown next.
We find only two occurrences of the string: one is the static format string and the other is a reference to the static string, as shown next. (Note that you can ignore the function name; it was not there during the initial analysis but rather was added by the author.)
By double-clicking on the highlighted result, we are taken to that instruction in the disassembly. Scrolling down, we see that the string is being used in a sprintf to construct a download command and that is being passed to system at 00409064, as shown next.
At this point, we at least know that the string is being used to make a call to system. From here, we need to understand how the URL in the format string is provided. This requires us to trace the control flow of the program to this point.
To trace the control flow to the entry of this subroutine/function, we need to scroll to the top of the function and select the address on the left. Once the address is selected, we simply press X to jump to the cross-reference to it, as shown here.
The cross-reference to the download routine is actually a lookup table with function pointers to the entry points for each command. The code searches for the command and jumps to the routine pointer that is adjacent to it. You will see the commands for “IPv6 Function,” “Download FW and language to DUT,” and “get_wan_ip,” as shown next. Note that the commands are in the form of the short name, function pointer, and long name. Because this is a lookup table, we need to find the beginning of the table in order to locate a cross-reference to it.
Although we have not completely traced the origin of the system call back to the root, it is safe to say that it points back to the cgi command to download the firmware. A few greps of the “download_fw_lp” string give us the origin
. At this point, we will move on to attempting to exploit the device through the firmware update.
The static analysis portion of the assessment is complete. From this point forward, we will be looking at the system as it runs. We need to set up an environment for intercepting requests from the device to the WAN, connect the DAP-1320 to our test network, and begin exercising the firmware update process. The end goal is to execute something on the wireless extender through command injection.
The test setup we’ve chosen uses 64-bit Kali Linux 2017, Ettercap, the DAP-1320 wireless range extender with firmware version 1.11, and a stock wireless network. The idea is to ARP-spoof the DAP-1320 so that all traffic to and from the device goes through our Kali Linux system. Although we could have simply put a device inline between the extender and the router that can forward traffic after inspection and modification, ARP spoofing would be the likely attack mechanism used in the field.
As a quick refresher, Address Resolution Protocol (ARP) is the mechanism for resolving an IP address to its Media Access Control (MAC) address. The MAC address is a unique address assigned by the manufacturer of the network device. Simply put, when a station needs to communicate with another station, it uses ARP to determine the MAC address associated with the IP to use. ARP spoofing effectively poisons the ARP tables of the stations, causing them to use the attacker’s MAC address instead of the actual MAC address of the target station. Therefore, all traffic to a destination traverses through the attacker’s station. This effectively puts a device inline without having to physically modify the network.
Ettercap is a tool that allows us to ARP-spoof for the purposes of man-in-the-middle (MITM) attacks, parse the packets, modify them, and forward them to the recipient. To begin with, we use Ettercap to see the traffic between the device and the Internet by issuing the following command (where the device is 192.168.1.173 and the gateway is 192.168.1.1 in this example):
Once Ettercap has started, we will use Wireshark to view the traffic as we interact with the device. Once Wireshark is started and the capture has been initiated, we can check for a firmware update on the device’s upgrade page, as shown here.
Click the Check for New Firmware button and then follow the TCP stream within Wireshark. We now see that the device goes to http://wrpd.dlink.com.tw/router/firmware/query.asp?model=DAP-1320_Ax_Default in the first two lines and the response is XML-encoded data, as shown next.
By going to the URL we captured, we can see that the XML contains the FW version’s major and minor numbers, the download site, and release notes.
Armed with this information, we can assume that if we change the minor number to 12 and the firmware link to a shell command, we will force the device to attempt to update and, consequently, run our command. In order to accomplish this task, we need to create an Ettercap filter (previously saved and displayed here), compile it
, and then run it
, as follows:
In order to determine if our command is getting executed, we need to ping the box and monitor the ping messages as we issue an upgrade. But first, notice that after clicking the Check for New Firmware button, we now see that there is a 1.12 version available to download.
Prior to clicking the Upgrade Firmware button, we need to set up our ping to monitor the device. When we click the Upgrade Firmware button, we should see the following download progress box:
You will notice that the host becomes nonresponsive and later comes back online
. This indicates that the box was rebooted. At this point, we’ve proven that we can inject a command into the upgrade URL and the device will execute it. Without uploading an executable to the device, you are limited by what is on the device. For example, as previously explained, if telnetd is compiled into the Busybox (it is not on this system), you can just start it to access the shell without a password, as follows:
This approach is demonstrated in the next section. If needed, you could cross-compile a binary such as netcat for this processor and then upload it via tftp or tfcp, as Craig Heffner has demonstrated,2 or you could use another method.
It turns out, in some cases, not to be necessary to have hardware in hand to perform vulnerability analysis and exploit firmware.
The FIRMADYNE3 tool allows for the emulation of firmware by using the QEMU hypervisor. The beauty of this approach is that you do not have to buy the hardware to test the firmware. This powerful approach allows for scaled testing in parallel. Dominic Chen downloaded and tested more than 23,000 specimens of firmware and was able to successfully run about 9,400 of them (approximately 40 percent),4 which is not bad at all. In the following labs, we will set up and execute FIRMADYNE.
If you want to follow along in this lab, we will be using Ubuntu 16.04.3 server, running in VMware or VirtualBox, with NAT network settings, only OpenSSH installed, with a username of firmadyne. First, we need to set up the FIRMADYNE tool by using the instructions found on the FIRMADYNE GitHub (see the “For Further Reading” section at the end of this chapter):
Next, install the PostgreSQL database:
Then, set up user firmadyne with the password “firmadyne” (when prompted):
Now, create the database and initialize it. Notice firmware is appended to the end of the next command:
Download the pre-built binaries for FIRMADYNE (or build binaries using instructions on the FIRMADYNE GitHub):
Now install QEMU:
Finally, set the FIRMWARE_DIR variable in the firmadyne.config file to the location of the firmadyne files:
Now that you have set up the environment, you may emulate a sample firmware (again, as described on the FIRMADYNE GitHub).
First, using the extractor script, extract the firmware:
Now, you may use the getArch script to get the architecture and store it in the database (enter the firmadyne DB password when prompted, which is “firmadyne”):
Now, store the location of the extracted file system into the database:
Next, make a virtual image to launch with QEMU, using the makeImage script:
Then, infer the network (this command will run for up to 60 seconds, so be patient):
Now that you know what the IP is, run the emulator:
If at any time you mess up the preceding commands and want to reset the database and environment, simply run the following commands:
At this point, the firmware should be running on the preceding IP as a tap device. You should also be able to connect to this virtual interface from the machine on which you are running QEMU. This is fine if you are working from that machine with a desktop environment (GUI) running. However, in our case, because we are running the QEMU in a virtual machine with no desktop environment running, we will need to get creative if we want to play with the interface from another host.
NOTE It is important to be running in NAT mode on your virtual machine in order for the following instructions to work.
To do this, we can use the Python sshuttle5 program to tunnel all network traffic through SSH to the virtual host. In this manner, we can access the remote tap device, as if we were local to the virtual machine. Because sshuttle runs in Python, it works on Linux, macOS, and Windows.
To begin, install sshuttle with pip:
Now launch it:
Here’s an example from a Mac:
Now, from the system that is running sshuttle, open a web browser and try to connect to that IP, as shown next. You may need to wait a minute for the web service to fully start after the emulator launches the firmware.
The credentials are admin/password, which can be found online. And just like that, we are logged into an emulated router, as shown here.
If your web browser hangs, check the sshuttle application; it may have crashed and needs to be restarted.
So far we have emulated the Netgear WNAP320 firmware in QEMU. Now it is time to do what we came for: exploit the firmware. Dominic Chen and his team found a command injection vulnerability in this firmware, running in FIRMADYNE. Let’s test it and see if it can be exploited:
From the previous output, you should note that we have injected a command to start the telnet server. The “telnet –l /bin/sh” argument starts the telnet server on the default port and binds it to the “/bin/sh” shell. The nmap scan shows that port 23 is now open.
After connecting to telnet, you will note that the user is root.
Although this has been done on emulated firmware, the same can be accomplished on the actual firmware. At this point, the attacker has root access on the device and can potentially use the device as a launching point for other attacks on the network.
This chapter demonstrated vulnerability analysis, both from a static and dynamic point of view. It also demonstrated exploiting a command-injection attack both from a dynamic and emulated point of view. In the latter case, you learned that vulnerabilities can be discovered and proof-of-concept exploits can be developed without even purchasing the hardware equipment. Using these techniques, it is hoped that ethical hackers will find security vulnerabilities in embedded devices and disclose them in an ethical manner, thus making us all more secure.
ARP spoofing https://en.wikipedia.org/wiki/ARP_spoofing
Busybox https://busybox.net
Craig Heffner’s Binwalk GitHub, https://github.com/ReFirmLabs/binwalk.
Craig Heffner’s blog (creator of binwalk) http://www.devttys0.com/blog/
Craig Heffner’s Firmware Mod Kit GitHub, https://github.com/rampageX/firmware-mod-kit.
Ettercap https://ettercap.github.io/ettercap
Firmadyne GitHub https://github.com/firmadyne/firmadyne
Firmware Mod Kit Prerequisites https://github.com/rampageX/firmware-mod-kit/wiki
IDA Pro Hex-Rays, https://www.hex-rays.com/products/ida
1. Bruce Schneier, “Security Risks of Embedded Systems,” Schneier on Security, January 9, 2014, https://www.schneier.com/blog/archives/2014/01/security_risks_9.html.
2. Craig Heffner, “Hacking the Linksys WMB54G, Using tfcp to Upload a Binary,” /DEV/TTYS0, July 12, 2012, www.devttys0.com/2012/07/hacking-the-linksys-wmb54g/.
3. Dominic Chen, FIRMADYNE, https://github.com/firmadyne/firmadyne.
4. Dominic Chen, “D-Link/Netgear FIRMADYNE Command Injection/ Buffer Overflow,” Packet Storm, February 26, 2016, CVE 2016-1555, https://packetstormsecurity.com/files/135956/D-Link-Netgear-FIRMADYNE-Command-Injection-Buffer-Overflow.html.
5. Brian May, “sshuttle: Where Transparent proxy Meets VMS Meets SSH,” sshuttle, July 8, 2017, http://sshuttle.readthedocs.io/en/stable/.