Over the past 10 years, Praetorian has tested hundreds of embedded systems, ranging from autonomous vehicles, medical devices, critical infrastructure, and smart consumer devices. Through our collective experience, Praetorian developed techniques and methodologies for testing a large range of IoT systems. In this article, we will go through our methodology to hacking IoT systems, starting with hardware and ending with cloud communications.
After receiving an IoT device from a client, the first thing we do is map out its possible attack surface. Since there are significant differences between embedded systems, there are always new attack paths to consider. For example, testing a smart doorbell could include a camera, microphone, and Wi-Fi interfaces, whereas testing a Kiosk machine could include a touch screen and USB slots. Regardless of the device, there will be some form of interface in the underlying system than an attacker could attempt to abuse. One common denominator is the printed circuit board (PCB) within each device.
The above images are taken from an extracted PCB of a Google Home Mini (credits to https://www.allaboutcircuits.com/news/teardown-tuesday-google-home-mini/). When we first disassemble a device, the very first thing we do is write down the chip packages (the black boxes with markings) and look up their datasheets. The next thing we do is rank the packages by level of importance: microcontrollers, memory, and peripherals. For the examples above, the two Marvell chips are the main microcontrollers on the PCB but used for different purposes (top is for application logic, bottom is for Wi-Fi). The main memory components are the Toshiba chip for long term memory and the Samsung chip for DRAM. The peripherals, such as the MEMS microphone, are important to note but are not the main focus of testing in most cases.
Once we have an understanding of the hardware components, the main areas we focus on hardware security testing are interacting with debug pins, extracting data from memory, and monitoring data over interesting buses (such as between the main microcontroller and the Wi-Fi microcontroller). Some of the common tools we use for testing are multimeters, logic analyzers, and on-chip debuggers (OCD) such as a J-Link. Additionally, things like power supply units (PSU), a soldering bench, and jumper cables are essential to connect to the PCB components.
Almost all microcontrollers contain a debugging interface, and the most common are JTAG and SWD. When these interfaces are enabled, it is very easy to connect a J-Link to extract onboard memory from the chips or re-flash the memory with malicious firmware. To prevent this debug access, companies should set the eFuse on the chip or add security controls like JTAG password protection to prevent easy access to the underlying microcontroller. Another common debug interface occurs over UART. Since UART is generic by design, this could be a console terminal to the device or a debug application with a custom protocol. Praetorian often gains terminal access over UART with a password that was extracted using some of the techniques described here.
Extracting data from memory can also occur in dedicated chips on the PCB. For example, it is very common to have an additional SPI flash chip used to store larger amounts of data such as a filesystem. In these cases, it is important to find the pads corresponding to the SPI interface. In the event the pads are not exposed, it is feasible to attach to metal scrapped from the PCB, or remove the flash chip entirely from the board using a heat gun and attaching wires directly to the chip (dead bug method). Both of these methods may destroy the device, so it is important to have multiple devices during hardware testing. Once the pads are identified, we interact with the flash chip and read/write data.
When devices use dedicated Wi-Fi / BLE / ZigBee chips for network processing, data is often sent to the main microcontroller over an unencrypted bus. In this case, using a logic analyzer to monitor traffic can be an interesting attack path to obtain privileged information. For example, the bus could contain the stored Wi-Fi credentials it uses to connect to the user’s home network. In that case, an attacker without previous knowledge of the user’s home network could capture that information and access their Wi-Fi network.
IoT devices are connected in many different ways, however some of the most common network interfaces in IoT are Wi-Fi, BLE, and ZigBee. Typically, an IoT device communicates with the internet over Wi-Fi, however how does the device get connected to the right Wi-Fi network? The most common ways are either the device exposes its own access point (AP), or a mobile device communicates over BLE. When a device hosts its own AP, it is important to encrypt data at the transport or application layer. For example, Praetorian often finds that devices expose an open AP but also passes application data between a mobile device via cleartext HTTP. In this case, the device should use HTTPS to ensure the information is encrypted and the TLS certificate is signed by a trusted certificate authority.
As time has passed, BLE has become more mainstream to provision IoT devices to the internet. BLE communications occur via GATT characteristics, which can be loosely understood as a key-value pair that devices can read/write depending on the characteristic’s permissions. The most important permissions are whether a characteristic needs encryption or authentication to access. If neither of these permissions are set for sensitive characteristics, it can be easy for an attacker to sniff BLE communications using an UberTooth and capture sensitive information over-the-air.
Another common network protocol is ZigBee (802.15.4), and it is most commonly used in smart home communications due to the benefit of its low frequency. There are more technical details in ZigBee due to the separation of application and network layers, however one of the pitfalls Praetorian commonly sees is neglecting to pre-configure a ZigBee network. In the event Praetorian is able to trick other devices into thinking it is a Coordinator device, it is possible to take over the entire network. Additionally, network keys are often not encrypted and sent over plaintext. Tools such as the RZ Raven Stick are good to interact with ZigBee networks.
Hardware and network interfaces are only one piece of the bigger IoT picture, and most of the security vulnerabilities within devices can be found in its running firmware. Praetorian typically receives firmware source code from clients for white-box analysis, however in some cases we only have access to the extracted firmware from hardware testing. In those cases, running a binwalk over the binary will give clues as to what the binary contains of and which components can be further analyzed using reverse engineering tools such as Ghidra. Regardless if we have source code, some of the most important things we analyze are the over-the-air (OTA) update process, shared secrets, device authentication/authorization, and input handling.
Most consumer IoT devices have some sort of OTA update process that is initiated remotely or by a mobile device. During the OTA process, we check that firmware signatures are properly validated and the communication channel is encrypted. This will prevent a man-in-the-middle attacker from modifying the OTA update package and performing a malicious firmware update.
Cryptographic secrets or API keys are often stored in device firmware and can be shared across multiple devices. Since one compromised device could affect other devices, inspecting the firmware for these secrets can have a high impact on the system’s security. For example, a shared encryption key for OTA updates could be extracted from one IoT device and used to craft malicious firmware for other devices.
Other security controls we test are commonly found in the OWASP top 10, such as authentication, authorization, and input handling. Given the number of hardware and network interfaces, there are many injection points where user input could cause undefined behavior or even fully compromise the device by remote code execution. For example, Praetorian has performed buffer overflow attacks against unauthenticated BLE characteristics that handled input incorrectly. It is again important to stress that most security vulnerabilities are found in firmware source code.
So far, we have mainly focused on hacking a single IoT device. However, IoT consists not only of the end device, but the mobile applications, gateway devices, and Cloud backend services that communicate with it. There are two common ways that devices communicate with Cloud services: HTTPS and MQTT. For both of these protocols, we attempt to proxy communications between the IoT device and services. There are often problems in how an IoT device validates server TLS certificates that allow man-in-the-middle attack scenarios.
For developed services like AWS IoT Core, communication typically occurs over MQTT. This publish/subscribe protocol makes it easy for many devices to subscribe to one topic and receive information all at the same time, such as new OTA updates. However, MQTT authorization controls quickly become important to prevent one device from publishing/subscribing to other device topics. In a worse case scenario, a single device could update all other devices with malicious firmware at once!
In this article, we provided an overview of Praetorian’s methodology to hacking IoT systems. First, we perform a thorough enumeration of attack surfaces to create plausible attack vectors against the system. Next, we disassemble the device and categorize hardware components that are interesting to inspect, such as microcontrollers or external memory. After extracting the firmware, we analyze how the device handles external input and attempt to identify attacks such as buffer overflows. Finally, we proxy communications between the device and cloud services and test the backend service’s authentication and authorization controls to prevent cross-device attacks.