The dynamic analysis phase is defined as the study of the running device in a real or emulated environment. For this purpose, the device is analyzed, trying to delve into possible vulnerabilities found in previous phases (essential for hacking IoT devices).
For this phase, an emulation environment can be used that allows the firmware to be run without the need for the original hardware, as shown in the previous article. This method allows a more in-depth analysis of the system in case no debug hardware port has been found, since, in many cases, emulation frameworks allow to connect a debugger such as GDB to control the execution flow. Alternatively, when no hardware ports are available, the original hardware can be used for dynamic analysis. This option is simpler to implement and is less prone to failures, but the analysis it allows is less in-depth than with emulation. When hardware debug ports are found, it is also possible to connect a debugger and control the execution in the original hardware.
The study objectives during dynamic analysis should be established according to the findings of the previous phases, especially the firmware and file system analysis phases. The information gathered so far is essential for the execution of the dynamic analysis: it provides a general idea of the system operation and indicates the weak points and the most vulnerable services.
There are many tests that can be run depending on the type of services that are available, and, in some cases, this phase of the analysis can resemble a traditional pentest, except for the knowledge acquired in the previous phases.
This article will present some of the techniques and tools that are useful in dynamic analysis.
1. Debugging using emulation techniques
If an emulation environment for the device firmware has been successfully built, one of the most interesting dynamic analysis techniques is to use a software debugger to control the execution flow and observe the state of the system at any given moment. In the case of full system emulation, these techniques are usually aimed at studying bootloader functions or kernel elements, whose separate analysis is particularly complex.
For full system emulation, multiple tools and frameworks are available, mostly based on the QEMU emulator, which allow to control the devices connected to the system, their inputs, outputs, and execution flow. In many cases, they also allow connecting a GDB client with which to observe the state of the system at any given moment.
Among the main alternatives are QEMU, Renode, Unicorn, Qiling and Firmadyne, which are discussed in the article 6 of this series.
The well-known and popular GDB debugger can be used in integration with all these debugging tools to take a close look at the execution of programs and entire systems. For emulated software, the framework or emulation system usually offers the possibility to run a gdbserver service to which a client can connect, even remotely.
Debugging techniques with emulation can be combined with fuzzing to execute attacks on elements of the bootloader, kernel, or operating system, which is particularly complex in a traditional pentest. They are also very useful to obtain the decrypted or unpacked firmware: identify the system boot point (init script or similar), install a breakpoint before boot, run the boot up to the breakpoint and extract the firmware image from memory with the debugger.
2. Physical port depuration
Also, in some cases, the original hardware itself has physical debug ports available through a JTAG or UART interface for developers that were not properly disabled or protected on production devices.
Through interaction with JTAG interfaces, the ability to read and write content to ROM and RAM can usually be found, so that the state of the system can be observed. If the memory mappings of the devices required by the firmware are known, the firmware can be interacted with through the devices, although this would require prior study and automation work to execute in real time.
Debug UART interfaces can provide access to the bootloader and allow interaction with it through a terminal and, in combination with memory access, can be used to control the execution flow.
3. Traditional pentest
Once the firmware is running, either in an emulated environment or on the original hardware, traditional pentesting techniques and methodologies can be applied, the so-called hardware pentesting, such as network reconnaissance with tools like nmap, vulnerability searches on the discovered services and web vulnerability searches.
There are a multitude of tools and techniques that can be applied in this phase depending on the services discovered in the system. As with the rest of the tasks, the results of the previous phases in an analysis can be decisive in selecting the priority targets. Generally, techniques such as the following can be used:
- Network reconnaissance: nmap is the tool par excellence in this aspect, as it offers network discovery capabilities with multiple different techniques and at different levels of the TCP/IP stack. The result of this analysis is the list of open ports on the running device and, with nmap extensions enabled, it is also possible to obtain data on the operating system, the services running on each port and the names and versions of the servers.
- Vulnerability discovery: from the versions of the running servers and the operating system, a search in vulnerability and exploit databases, such as the NVD (https://nvd.nist.gov) or exploit-db (https://www.exploit-db.com), can provide useful results for exploitation.
- Web pentesting: In case a web service is found, which is a common case in IoT devices, this can be an interesting target for exploitation. Web services are complex systems that can introduce bugs and vulnerabilities into the system and for which many tools and techniques are available.
- Communications analysis: Many IoT devices have services with specialized protocols or implementations of a standard that are specific to the manufacturer. It is common for these services to contain poorly tested protocols and for the servers to have undiscovered vulnerabilities. Using already acquired knowledge of the system as a guide, a thorough study of the device’s unconventional communications can uncover unexpected surprises.
- Vulnerability exploitation: Once potential vulnerabilities have been analyzed, the necessary tests must be performed to confirm their feasibility. In the most favorable case, exploits or proofs of concept will be found ready to exploit the vulnerability, so that they can be executed directly or through frameworks such as the well-known Metasploit. In most cases, however, the vulnerabilities will require more in-depth study work, for which it may be useful to return to phase 5 of file system analysis to study the executables and firmware elements in detail.
For the analysis of embedded web services, the OWASP guide can be particularly useful, as well as widely known suites and tools such as Burp, ZAP or DirBuster. It is also worth considering the environment in which the web is running elements such as user authentication and backend task execution depend on the system that has already been studied and tests can be directed towards suspicious targets.
In general, although the firmware and especially the software of IoT devices may be outdated compared to other types of systems, the most vulnerable aspects are often found in the manufacturer’s own implementations, which are usually not as well tested as the rest of the components where hardware hacking commonly bears fruit.
4. Fuzzing
Fuzzing is a vulnerability search technique that has traditionally been associated with software testing and validation. In the context of cybersecurity, it is especially relevant because it allows to automate testing and find bugs that would otherwise have been more difficult. IoT fuzzing is applied to smart devices to find implementation bugs in the source code.
There are different fuzzing techniques with different results and objectives:
- Application fuzzing: It consists of modifying input data to locate bugs in the code. It is the best-known type of fuzzing and is usually implemented on the source code (white box analysis) in software testing. In the context of cybersecurity, it is also often used in black or gray box analysis to find potential bugs in systems through data ingestion (such as buffer overflows).
- File format fuzzing: In addition to modifying the input data, this fuzzing technique modifies the format, generating malformed packets and files. For example, altering bits of the properties of an mp4 or a pdf. It is very useful for identifying implementation bugs not aligned with the standard.
- Protocol fuzzing: It can act by creating modified packets for a specific communication protocol or as a proxy, modifying the packets and forwarding them to the destination. It is analogous to format fuzzing, but specialized in a communication protocol (TCP, Bluetooth…).
There are numerous tools available for fuzzing attacks such as AFL++, FormatFuzzer, CryptoFuzz. One of the most powerful tools is ClusterFuzz, developed by Google, with which they have detected, as of May 2022, 25,000 bugs in their products and more than 36,000 bugs in 550 open-source projects. These figures highlight the potential of this type of automated attack and its importance in the context of cybersecurity. In this context, IoT device fuzzing is an automatized technique to find software defects in black box systems.
5. Bootloader modification
One of the known tricks to bypass the login manager and directly access a terminal with administrator permissions is to manipulate the kernel parameters in the bootloader. This technique is based on taking advantage of the lack of security that some manufacturers may leave in the boot of the device to access the bootloader boot script and modify it for the benefit of the auditor. This same mechanism can be used to load modified firmware or u-boot images, in addition to inspecting enabled debugging functionalities.
Depending on the system and bootloader (information that may have been obtained in previous analysis) access to the terminal differs, but, in general, it is required to have access to a debug port or to have a monitor and keyboard connected to the device. If this is the case, access is usually gained by pressing “magic codes” or specific key combinations during boot.
If the bootloader has not been properly protected, it will show a terminal to interact with. These are some of the interesting modifications that can be made in U-Boot:
- To modify the bootloader boot parameters, you must modify the bootargs environment variable, whose default values are stored in a text configuration file. The bootargs variable is usually defined like the following line:
setargs=setenv bootargs console=${console} root=${nand_root} init=${init} loglevel=${loglevel}
If the init parameter is modified, a terminal with administrator permissions can be obtained at system startup.
setargs=setenv bootargs console=${console} root=${nand_root} init=/bin/bash loglevel=${loglevel}
You can also modify the same variable with the setenv command, consulting the rest of the variables beforehand:
#printenv #print environment or UEFI variables options
#setenv bootargs=console=ttyS0,115200 mem=63M root=<rootDevice> mtdparts=sflash:<partitionInfo> rootfstype=<fstype> hasEeprom=0 5srst=0 int=/bin/bash
#saveenv
#boot
- Using the bootloader terminal, U-Boot images can also be loaded and written to memory to gain root access. For this purpose, a TFTP server can be used as follows:
#setenv ipaddr 192.168.2.2 # device local IP
#setenv serverip 192.168.2.1 #tftp server local IP
#saveenv
#reset
#ping 192.168.2.1 #check if network access is available
#tftp ${loadaddr} <ubootImage> #loadaddr accept two arguments: memory address where file will be stored and file name in the tftp server.
After modifying the local IP and setting that of the external tftp server containing the image, the server is accessed with a TFTP client, and the uImage-3.6.35 image is loaded into the memory location from which it is loaded at the next boot. Alternatively, ubootwrite.py performs the same process over a UART interface.
- In addition, debugging functions such as logs, loading arbitrary kernels and booting from untrusted sources can be configured.
6. Firmware modification
In devices that do not properly check the origin of the firmware they run, it is possible to carry out attacks on their integrity by loading a modified copy that includes vulnerabilities, such as a terminal with administrator permissions on an SSH port.
To do this, the file system must first be extracted and analyzed. The goal, in this case, is to obtain the necessary tools to unpack and package the firmware image, while analyzing the boot process to locate where to modify the firmware. The best way to ensure that the firmware continues to run smoothly after modification is to avoid modifying the final size of the image, so be very careful about which files are modified or deleted.
Once the way to introduce modifications to the firmware has been found, there are multiple tests that can be performed, among which the introduction of a backdoor (e.g., a ssh terminal with administrator permissions that boots at startup) is the most important.
One of the biggest challenges for this test is finding the correct toolchain for the backdoor compilation. This is different for each architecture, and manufacturer, but, in most cases, architectures for which the gcc suite has compilers available (MIPS, ARM…) are used.
Once the backdoor is designed and compiled, considering the size restrictions, it is recommended to test it in a virtualized environment with one of the tools in article 6 (e.g., QEMU and chroot).
Once tested, the new firmware image is created with the packaging tools and uploaded as a firmware update to the device. If the update and boot process is not properly protected, a variation of this test may result in a device with a backdoor installed with which to continue dynamic analysis, with access to the admin user.
7. Conclusions
There are a multitude of techniques and tools applicable to dynamic analysis of IoT devices. Many of them overlap with traditional pentesting techniques and tools, so many of these skills can be leveraged. However, other techniques, such as firmware modification or the use of a debugger to control execution in an emulated environment, are specific to firmware analysis, opening the range of possibilities even further.
It is therefore very useful to set clear objectives before starting the analysis based on the results of the static analysis, so that efforts are directed to the most likely vulnerable components.
References
- https://github.com/scriptingxss/owasp-fstm
- https://securelist.com/dynamic-analysis-of-firmware-components-in-iot-devices/106901/
- https://www.opensourceforu.com/2018/09/dynamic-analysis-of-firmware-using-firmadyne/
- https://ics-cert.kaspersky.com/publications/reports/2022/07/06/dynamic-analysis-of-firmware-components-in-iot-devices/
- https://etutorials.org/Linux+systems/embedded+linux+systems/Chapter+9.+Setting+Up+the+Bootloader/9.5+U-Boot/
- https://u-boot.readthedocs.io/en/latest/usage/environment.html
- https://linux-sunxi.org/U-Boot/Configuration