In the preceding chapters, you learned about the attacking of IoT devices using hardware and embedded exploitation techniques. This chapter focuses on the firmware exploitation with which we can exploit the device.
One of the instances where you might have heard of firmware security is during the time a widespread Mirai Botnet infection. Mirai Botnet infects devices by getting access to them using default credentials. This poses a question: How can you, as a security researcher, keep your IoT devices safe from Mirai or ensure that they are not vulnerable? One of the ways is to manually check for the different login credentials on various running services, which is not quite scalable. This is where firmware security skills become useful. It also helps us by not having the limitation of being able to perform a security assessment only when we have the physical device with us. Firmware, for a security researcher, is the factor that enables research and exploitation without having any direct physical access to the device. From a security perspective, it is the most critical component of an IoT device. Almost every device you can think of runs on firmware.
Tools Required for Firmware Exploitation
Before we begin looking into firmware, here are the list of tools that we will be using in this chapter.
Firmware is a piece of code residing on the nonvolatile section of the device, allowing and enabling the device to perform different tasks required for its functioning. It consists of various components such as kernel, bootloader, file system, and additional resources. It also helps in the functioning of various hardware components for the IoT device.
Even if you are not from an electronics background or do not have prior experience working with firmware, you might remember coming across firmware during instances when your smart phone or smart TV was getting updated, and in turn downloading the new version of the device’s firmware.
Firmware, as we have discussed, contains various sections embedded within it. The first step to analyzing firmware to gain deeper insight into it is to identify the various sections that function together to make the complete firmware.
Firmware is a binary piece of data, which when opened in a hex viewer reveals the various sections within it, which then could be identified by looking at the signature bytes of the individual sections.
Before jumping into analyzing a real-world firmware and performing security research on it, let’s first understand what we expect to see once we start our firmware analysis. The only component of firmware that I focus on in this chapter is the file system.
The file system in embedded or IoT device firmware can be of different types, depending on the manufacturer’s requirements and the device functionality. Each of the different file system types has its own unique signature headers that we use later to identify the location where the file system starts in the entire firmware binary. Common file systems that we typically encounter in IoT devices are listed here:
1.
Squashfs
2.
Cramfs
3.
JFFS2
4.
YAFFS2
5.
ext2
On top of the different type of file systems, there are also varying types of compressions in use. File systems in IoT devices save on device storage space, which is a valuable asset when we are dealing with IoT devices. Some common compressions that we see in IoT devices are as follows:
1.
LZMA
2.
Gzip
3.
Zip
4.
Zlib
5.
ARJ
Depending on what file system type and compression type a device is using, the set of tools we will use to extract it will be different. Now, before we jump into extracting a file system from a firmware and digging deep into it, we need to understand the various ways in which we can access a device’s firmware. All the methods that we discuss here are covered in much more detail in the later sections of this book.
How to Get Firmware Binary
The first thing to learn to perform IoT exploitation is to get hold of the device’s firmware. Depending on the device you are targeting, the way of getting to the firmware binary might differ.
There are different ways to access the firmware binary.
1.
Getting it online is one of the most common ways of getting hold of the firmware binary. As you go further in your IoT security journey, you will notice that a lot of manufacturers decide to put their firmware binary package online on either their Support page or the Downloads section of their web site.
You can also navigate through the various community support and discussion forums for the device and might end up finding the firmware binary has been uploaded by another user.
For instance, if you navigate to TP-Link’s web site and open any of their devices, there is a strong possibility that you will find the firmware download link (see Figure 7-1).
2.
Extracting from the device is an approach I personally prefer. This means that once you have physical access to the device, using various hardware exploitation techniques, you can dump the firmware from the device’s flash chip and then run additional analysis on it.
Depending on the device, the protection level might vary and you might have to use one or the other hardware exploitation techniques to get to the firmware binary.
Sometimes, you will find that you can dump the firmware via a simple UART connection, in some cases you might have to use JTAG, and in other cases you would have to dump it from the flash chip.
3.
Sniffing Over The Air (OTA) is another common technique of getting to the firmware binary package while the device is performing an update.
The process here is to set up a network interceptor for the device. As soon as the device queries for downloading the new firmware image from the server, you will be able to extract it from the network capture.
Obviously, there might be complications while doing this. You might not always have the traffic go through a proxy, or the file being downloaded might not be the entire firmware but rather just a small update package.
4.
Reversing applications is one of the other smart ways of accessing the firmware. This technique involves you looking at the web and mobile applications of the IoT device and from there figuring out a way to obtain the firmware.
Extracting Firmware
Once we have a firmware image, one of the most important things we can do with it is extract the file system from the binary image. We can extract file systems from a firmware image using either a manual or an automated approach. Let’s start with the manual way.
Manual Firmware Extraction
Let’s start with a very simple firmware—a Dlink 300B firmware, which is used in the Dlink 300 series routers and would be a good starting point in learning about firmware internals, taking real-world firmware and digging deep into it.
The firmware binary is in the code samples for this book at the location /lab/firmware/.
If we do a file at this step to understand the type of file format, the output indicates that it is a data file (see Figure 7-2).
Because the file in this case did not reveal much information, we can use hexdump to dump the contents of the binary firmware file in hex format. At the same time, we will also grep for shsq, which is the signature header bytes for a Squashfs file system. If it does not match shsq, we will then try with the signature bytes for LZMA, Gzip, and so on.
As we can see from Figure 7-3, the hexdump output contains the shsq bytes at the location 0x000e0080. This means that our file system begins from the offset address of 0x000e0080, as shown in Figure 7-3.
This is a critical piece of information, and can be used to selectively dump the file system from the binary into a new file. This file could then either be mounted as a new file system or run through tools such as unsquashfs to reveal the file system contents. Let’s go ahead and dump the file system from the entire firmware binary image using a tool called dd. With dd, we can either use the address in hex or in decimal, passing it as the offset from where dd should start dumping the file system, as shown in Figure 7-4.
We now have just the file system in a new separate file called Dlink_fs. If we run this through unsquashfs, a tool to uncompress squashfs file systems, Figure 7-5 shows the result.
We now have the entire file system extracted that was present in the Dlink firmware binary. This is a huge win for us, as we now have full access to all the individual files and folders present in the firmware.
Automated File System Extraction
As you have probably realized by now, manually performing all the steps manually for any firmware you will have to analyze can gradually become a cumbersome and repetitive task.
Binwalk is a tool written by Craig Heffner that automates all the steps in the preceding section and helps us in the extraction of the file system from a firmware binary image. It does this by matching the signatures present in the firmware image to the ones in its database and provides us an estimate of what the different sections could be. You will find it works for most of the publicly available firmware.
Setting up Binwalk on an Ubuntu instance is quite straightforward:
git clone https://github.com/devttys0/binwalk.git
cd binwalk-master
sudo python setup.py
Let’s download a new firmware and use Binwalk to extract the file system from the firmware as well as perform additional analysis. The firmware we use here is the Damn Vulnerable Router Firmware (DVRF) by @b1ack0wl.
Once we have the firmware, let’s fire up Binwalk and see the various sections present in the firmware image.
binwalk -t dvrf.bin
-t in this command simply tells Binwalk to format the output text in a nice tabular format. Figure 7-6 shows what you see when you run that command.
As you can see, it specifies that there are four sections in the entire firmware image:
1.
Bin header
2.
Firmware header
3.
Gzip compressed data
4.
Squashfs file system
Additionally, Binwalk can also provide more details about the firmware, such as an entropy analysis. An entropy analysis helps us to understand whether the data in firmware are encrypted or simply compressed.
Let’s perform an entropy analysis on this firmware and see what we get.
binwalk E dvrf.bin
As you can see in Figure 7-7, the entropy analysis shows us a line with a bit of variation in the middle. A line with variation in an entropy analysis indicates that the data are simply compressed and not encrypted, whereas a completely flat line indicates that the data are encrypted.
Now we know that we have a firmware image with the data not encrypted. As we learned from the first Binwalk command of identifying various sections, the file system in this case is Squashfs. Now instead of using dd and dumping individual segments, we can simply use Binwalk with the -e flag (lowercase) to extract the file system from the firmware image (see Figure 7-8).
binwalk -e dvrf.bin
Even though the displayed output is the same as running it without any flags, in this case Binwalk also generated a new directory for us containing the extracted file system. The generated directory in Binwalk is named with the firmware name, prepended with an underscore (_) and appended with.extracted.
If we look inside the directory, it has the following contents:
1.
A .squashfs file system
2.
Piggy
3.
Squashfs-root folder
If we navigate inside the squashfs-root folder, we notice that it consists of the entire file system of the firmware image, as shown in Figure 7-9.
As you can imagine, Binwalk makes it extremely simple and straightforward to extract file systems from a firmware image.
Firmware Internals
At this point in time, it’s essential to get a deeper knowledge of what a firmware holds and what some of the unknown values such as piggy mean. To understand firmware, we must first understand the specific things that firmware holds.
1.
Bootloader: Bootloader for an embedded system is responsible for numerous tasks such as initializing various critical hardware components and allocating the required resources.
2.
Kernel: Kernel is one of the core components of the entire embedded device. Speaking at a very general level, a kernel is simply an intermediary layer between the hardware and the software.
3.
File system: The file system is where all the individual files necessary for the embedded device runtime are stored. This also includes components such as web servers and network services.
To give a bit more insight into an embedded device bootup process, here’s how a typical embedded device boots up.
1.
Bootloader initiates required hardware and system components for bootup.
2.
Bootloader is passed in the physical address of the kernel as well as the loading of the device tree.
3.
Kernel is loaded from the preceding address, which then initiates all the required processes and additional services for the embedded device to operate.
4.
Bootloader dies as soon as the kernel gets loaded.
5.
The root file system is mounted.
6.
As soon as the root file system is mounted, a Linux kernel spawns a program called init.
This also means that if we have access to the bootloader or if we can load our customized bootloader to the target device, we will be able to control the entire operation of the device, even making the device use a modified kernel instead of the original one. It is a good experiment to perform, but it is beyond the scope of this book.
Hard-Coded Secrets
One of the most important use cases for extracting the file system from firmware is to be able to look for sensitive values within the firmware. Now, if you are getting started in security or are not familiar with the concept of reverse engineering, here are some of the things that we can potentially look for, which will be good for us from a security researcher’s point of view:
1.
Hard-coded credentials.
2.
Backdoor access.
3.
Sensitive URLs.
4.
Access tokens.
5.
API and encryption keys.
6.
Encryption algorithms.
7.
Local pathnames.
8.
Environment details.
9.
Authentication and authorization mechanisms.
There could be more, depending on what device you are assessing.
To understand this, let’s take the same firmware we used earlier, the Dlink 300B firmware image. Because we have already extracted the file system from the firmware image, we can directly go to the extracted folder, which in this case is ~/lab/Dlink_firmware/_extracted/squashfs-root/.
Here, let’s look for a sensitive value such as telnet credentials that could be used to access the device remotely. Depending on the situation, this would have a huge impact; imagine a baby monitor having telnet access enabled with a hard-coded password, in which you can view the images and even start and stop video recording.
Once we are in the firmware folder, we can use grep to search for all the files inside the various folders and see if any of them contain a match of the word telnet (see Figure 7-10).
It appears that this firmware image does contain a couple of mentions of the word telnet. If we look closely, we see that the file /etc/scripts/telnetd.sh has a command specifying telnet login and a mention of telnetd.sh in the system.sh file. Open the system.sh file in a text editor as shown in Figure 7-11.
As you can see, system.sh simply invokes the other file telnetd.sh located in /etc/scripts/misc/. Let’s go ahead and fire up the file in nano as shown in Figure 7-12.
Understanding the command, it turns out that it is being used to start the telnet service with the username of AlphaNetworks and the password being a variable $password. Looking at the very first line tells us that the variable $password is the output of the command cat /etc/config/image_sign.
This is what we find when we run the command mentioned in the file. As we can see in Figure 7-13, wrgn23_dlwbr_dir300b is the actual telnet password of this device with the username being root. Note here that the credential is common for all the Dlink 300B devices available.
Encrypted Firmware
In the IoT ecosystem, you might sometimes encounter encrypted firmware. The encryption might vary depending on the firmware. You might sometimes find firmware encrypted with simply XOR or sometimes even with Advanced Encryption Standard (AES). Let’s go ahead and see how we can analyze firmware that is encrypted with XOR encryption and reverse it to identify vulnerabilities.
For this exercise, we use the firmware encrypted.bin provided with the Download bundle for this book. This vulnerability was first identified by Roberto Paleari (@rpaleari) and Alessandro Di Pinto (@adipinto).
Let’s start by performing a Binwalk analysis and see what sections are present (Figure 7-14).
As we can see, Binwalk in this case fails to identify any specific section. This is a strong indication of either of two things:
1.
We are dealing with a proprietary firmware with a modified and unknown file system and sections.
2.
The firmware is encrypted.
The first thing we can do is check whether the firmware is encrypted with XOR encryption. For this, simply perform a hexdump and see if there are any recurring strings, which is a good indication of usage of XOR encryption, as shown in Figure 7-15.
As we know, XOR of a value with 0x20 (in ASCII) results in the same value.
Let’s run Binwalk on decrypted.bin now, and see if Binwalk can identify the various sections, as shown in Figure 7-16.
Extract the firmware using Binwalk and as shown in Figure 7-17, you can see that we now have access to the contents of the file system in the firmware.
binwalk -e decrypted.bin
As we dig deeper in the firmware, one of the things we usually look for during penetration tests are custom binaries that seem interesting. There is another squashfs image inside the file system, as you can see from Figure 7-17. We can extract it using unsquashfs, as shown in Figure 7-18.
Once we have unsquashed the ess_apps.sqsh file, we can then have a look at all the underlying components, as shown in Figure 7-19.
There are three folders here—lib, sbin, and www. We can look into various files and folders individually.
Libraries in embedded file systems often contain sensitive information and might also reveal certain vulnerabilities. Even though we cover ARM and MIPS disassembly later on in this book, I’ll show a walkthrough of how you can do some basic analysis on the library using a tool called radare2.
We only look at the various functions at this point to give you a basic idea. Let’s launch radare2 with the -a and -b flags specific to the architecture and block size.
radare2 -a mips -b32 libdbox.so
Once we are in radare2, let’s run the complete initial analysis required by radare2, which could be done by aaa.
This might take a couple of seconds or a couple of minutes, depending on the size of the library. In this case, our library is quite small and this shouldn’t take more than a few seconds. As soon as the analysis is done, we will run afl to list all the functions in the library (see Figure 7-20).
A better way to do it is to grep for interesting strings in the function names that we could later analyze. Let’s do a grep for wifi, gen, and get strings, and see if there are any functions containing these strings.
To do a grep in radare2, we need to use the ~ character (see Figure 7-21).
At this point, you can look into the disassembly of individual functions and also identify vulnerabilities such as command injection and buffer overflows.
Emulating a Firmware Binary
Once we have a firmware with an extracted file system, one of the first things that we need to do as security researchers is look at the individual binaries and see if there are any vulnerabilities.
Now, because IoT devices run on different architectures and not necessarily x86 (on which most of our systems run), we must be able to understand and analyze binaries meant for different platforms such as ARM, MIPS, PowerPC, and so on.
To statically analyze the binaries, we use tools such as radare2, IDA Pro, and Hopper. We will see an in-depth analysis of binaries meant to be run on different architectures in later chapters. For now, we are only concerned with emulating the binary and making it run. Even though these binaries are for different architectures, we can use a utility known as Qemu to emulate the binaries on our platform. To do this, we need to first install qemu on our platform for the corresponding architectures.
Once we have Qemu installed, let’s have a look at our target firmware. For this exercise, we use DVRF, which we used earlier to demonstrate file system extraction using Binwalk.
Navigate to the file system folder of DVRF so that your current directory structure looks like the one shown in Figure 7-22.
Here, we need to copy the Qemu binary corresponding to the architecture of binaries in DVRF. Let’s first determine the architecture on which DVRF is meant to run. We can use readelf -h on any individual binary inside the DVRF file system to identify the architecture. As we can see, the architecture in this case is MIPS (Figure 7-23).
Let’s go ahead and grab the Qemu binary for MIPS and copy to the squashfs folder of DVRF.
$ which qemu-mipsel-static
/usr/bin/qemu-mipsel-static
$ sudo cp /usr/bin/qemu-mipsel-static .
Now that we have qemu-mipsel-static, which is the binary for running MIPS little-endian binaries, it also provides the libraries that are required.
Once we have this, the next step is to run a binary emulating the architecture and providing the correct path for all the related files. For example, if we run ./bin/busybox it might be meant to look for additional related files in the location /lib or any other similar location. If we run it simply, it would look for that file in our system’s /lib location and not _dvrf.bin.extracted/squashfs-root/lib. This can also be verified by running it as shown in Figure 7-24.
We get an error saying /lib/ld-uClibc.so.0: No such file or directory. If we look in the lib folder of DVRF, we see that this library is indeed present (see Figure 7-25).
It is giving an error because the program is looking for that library in the /lib folder and not the lib folder of DVRF. To make it look for it in the location _dvrf.bin.extracted/squashfs-root/lib we need to specify while running the program that the home folder path is _dvrf.bin.extracted/squashfs-root/ and not /. To do this, we use a utility called chroot, with which we can pass in our own location as the program’s home or root location. The root location in this case will be the squashfs-root folder.
Let’s now go ahead and run the binary with qemu-mipsel-static specifying chroot with the program root folder, which is the current folder from which we are executing the command (see Figure 7-26).
sudo chroot . ./qemu-mipsel-static ./bin/busybox
Thus, now we can emulate a firmware binary that was originally meant to be run on only MIPS-based architectures. This is a huge win for us because now we can perform additional analysis on the binary, such as running it with arguments, attaching a debugger to it, and so on.
Emulating an Entire Firmware
Once we have successfully emulated a firmware binary, the next step for us would be to emulate the entire firmware image. This is helpful in a number of ways:
It gives us access to all the individual binaries in the firmware image.
It allows us to perform network-based attacks on the firmware
We can hook a debugger to any specific binary and perform vulnerability research.
It allows us to view the web interface if the firmware comes with any.
It enables us to perform remote exploitation security research.
These are just some of the advantages that come along with emulating the entire firmware image. However, there are a few challenges to make the entire firmware emulation.
1.
The firmware is meant to run on another architecture.
2.
The firmware during bootup might require configurations and additional information from Non-Volatile RAM (NVRAM).
3.
The firmware might be dependent on physical hardware components to run.
If we tackle all of these problems and come up with a solution for each, it is highly possible that we will be able to run the firmware in full emulation.
The first challenge, in which the firmware is meant to run on another architecture, is something we already solved using Qemu in the previous section. We again use Qemu to solve this challenge.
The second challenge, which is the dependence of firmware on components such as NVRAM, can be solved in an interesting way. If you are familiar with the concept of web proxying, where we set up a proxy that intercepts and allows us to modify any data that are being sent or received by the client to or from the server, we use the same approach here. We can set up an interceptor that listens to all the calls being made by the firmware to NVRAM and can return our custom values. This way, the firmware will believe that there is an actual NVRAM responding to the queries made by the firmware.
The next challenge to emulate the firmware is to figure out the dependence on hardware. For now, we simply ignore this challenge as it is really a device-specific scenario and often you will find most of the components to be working even with no physical device access.
To do this, we use a script called Firmware Analysis Toolkit (FAT), which is a script built on top of Firmadyne, a tool meant for emulating firmware. Let’s set everything up.
At this point, we also need to modify the value of FIRMWARE_DIR and set it to the current path of the firmware-analysis-toolkit, which is where we will be storing the firmware.
Figure 7-27 shows what our current firmadyne.config file looks like now.
Once we have everything set up, we can go ahead and emulate the entire firmware. For this exercise, we use the Dlink 300B firmware we used in the very first exercise.
sudo ./fat.py
Once we run the FAT, it will ask us to enter the path of the firmware we want to analyze and the brand name of the firmware. This information is stored in a postgresql database for management purposes. It will then go ahead and store the various properties, such as the architecture type and other relevant information in the database. During the entire operation, it will ask for the password a couple of times. The default password for the database is firmadyne (see Figure 7-28).
After around a minute, you will see that the script has network access and has finally run the firmware. You can now access the IP address provided by the script to access the web interface of the firmware in the exact same way as you would have accessed the real device’s web interface (see Figure 7-29).
Let’s go to the IP address provided, which in this case is 192.168.0.1. As we can see in Figure 7-30, we have the login panel of the Dlink router.
We can try with some common credentials, and it turns out that the valid credential in this case is admin with no password. We can use the same technique to emulate the firmware of any other IoT device as well.
Backdooring Firmware
Backdooring firmware is one of the security issues firmware faces if the device has no secure integrity checks and signature validation. As attackers, we could extract the file system from firmware and then modify the firmware by adding our own backdoor. This modified firmware could then be flashed to the real IoT device, which would then give us backdoor access to the device.
In this section, we take the Dlink firmware as an example to backdoor and then we add a custom backdoor to open Port 9999 for us to access the device. To modify the firmware, we need to first extract the file system from the firmware. Instead of using Binwalk, here, we use a tool called Firmware Mod Kit.
Once we have the Firmware Mod Kit (FMK) downloaded, we need to change the address of Binwalk in the file shared-ng.config, as shown in Figure 7-31. We can find the address of Binwalk and update that address in the file.
Now, let’s go ahead and copy the firmware Dlink_firmware.bin to this address and run ./extract-firmware.sh. If you run it for the first time, as shown in Figure 7-32, it will show you a lot of verbose output and several warnings, but it’s safe to ignore them.
Once the extraction is complete, the location of the extracted files is displayed as shown in Figure 7-33.
Here, we need to go to rootfs, which is the root file system where we will find the entire file system contents. At this point, we can modify the values or add any additional file or binary, which we can then repackage into the new firmware image.
We have two tasks here:
1.
Creating a backdoor and compiling it to run on MIPS-based architecture.
2.
Modifying entries and placing the backdoor in a location so that it can be started automatically at bootup.
Creating a Backdoor and Compiling It to Run on MIPS-Based Architecture
The backdoor we use in this case was created by Osanda Malith (@OsandaMalith) and is located in the additional folder in the Downloads bundle for this book (Listing 7-2).
The backdoor in Listing 7-2 opens Port 9999 and connects it to the busybox binary, allowing us to execute commands when interacting over the port.
To compile this, we would need the cross-compiling tool chain for MIPS architecture. BuildRoot is a special tool that can help us compile programs for a different target architecture than the one we are on.
Once we are in the buildroot directory, we can type make menuconfig to bring up the options for which we would like to build our tool chain (see Figure 7-34).
Navigate to Target Options and change the Target Architecture to MIPS (little-endian) as shown in Figure 7-35.
Under Toolchain, select Build Cross GDB for the Host, as well as GCC Compiler (see Figure 7-36).
Once this is complete, save the configuration and exit. The only step left now to build our tool chain is to execute the make command as shown in Figure 7-37. Remember that the make command could take some time to complete.
Once done, we are now ready to compile our bindshell.c with the GCC for MIPS, which we have just created using buildroot, as shown in Figure 7-38.
For compilation, we can use the binary ./mipsel-buildroot-linux-uclibc-gcc and run it on bindshell.c, as shown in Figure 7-39.
We just created a bindshell binary, which now can be executed on the MIPS-based architecture.
Modifying Entries and Placing the Backdoor in a Location so It Could Be Started Automatically at Bootup
Once we have compiled our bindshell, let’s go in the FMK directory and find a place to put this newly compiled binary. One idea, if we are looking for a script in Linux that automatically starts during bootup, is to look inside the /etc/init.d folder, which contains a number of scripts as shown in Figure 7-40.
However, the scripts here are symlinked to files in /etc/scripts, so let’s look at the /etc/scripts location, which again contains a number of .sh files (Figure 7-41).
Let’s take a look at the script system.sh, which was one of the entries we found in the /etc/init.d location (Figure 7-42).
This script indeed looks like a good location and looks like it is starting several services by executing scripts such as telnetd.sh, lan.sh, and so on. This would be a perfect place to add our own entry that would then be auto started.
Let’s add a line in system.sh asking it to invoke a backdoor binary that we would place in the /etc/templates location (Figure 7-43).
You can save this file and exit. We will now put the backdoor binary in the /etc/templates location as we mentioned in the script.
Now that we have placed the backdoor as well as the script in the appropriate location, the only task left is to recompile the firmware. To do this, we need to go to the parent folder of FMK where we had the directory Dlink_firmware/ and execute the following command as shown in Figure 7-44:
./build-firmware.sh Dlink_firmware/ -nopad -min
Once we have compiled the firmware, we now have the new firmware located inside the Dlink_firmware folder with the name new-firmware.bin (see Figure 7-45).
We can now either flash this firmware to a real device or emulate it using FAT, just like we did earlier. For now, we will emulate it using FAT, as shown in Figure 7-46, and see if we have a backdoor access to Port 9999 where we could execute our commands.
sudo ./fat.py
It will show you that an IP address of 192.168.0.1 has been assigned to the new firmware. The error shown in the Figure 7-47 is simply because I earlier created an entry for the same firmware, and thus a database conflict happens, which is okay as long as you are dealing with the same firmware. At this step, we can use netcat or nc to connect to the IP and see if we have backdoor access, as demonstrated in Figure 7-47.
As you can see, we now have backdoor access to the firmware over Port 9999, which could also be used to execute malicious commands as root privileges.
Running Automated Firmware Scanning Tools
One of the other ways of identifying low-hanging vulnerabilities in firmware is to run an automated script that greps through interesting strings, which then can be manually looked at. You can build such scripts by yourself or use one of the publicly available ones. One such tool is Firmwalker by Craig Smith (@craigz28). We already downloaded this tool when we were cloning the FAT repo, as this is also a part of the GitHub repo of FAT.
Let’s go to the firmwalker folder inside the FAT directory. If you look inside the data folder, it contains the entries that firmwalker looks for, as shown in Figure 7-48.
Let’s go ahead and run firmwalker, passing in the argument as the extract file system of Dlink_firmware.bin and see what it comes up with.
On completion of execution, it generates a firmwalker.txt file that contains the output. As we can see in Figure 7-49, it now identifies many things that we can manually look at to identify potential vulnerabilities.
Conclusion
In this chapter, we looked at firmware internals and how we could extract a file system from a firmware binary image. We also had a look at the emulation of both firmware binaries as well as the complete firmware itself.
In the next chapter, we look at some other attacks that we can use once we have successfully emulated firmware, or if we have an IoT device sitting on the network.