HackTricks
Searchโ€ฆ
๐Ÿ‘ฝ
Network Services Pentesting
Firmware Analysis
Support HackTricks and get benefits!

Introduction

Firmware is a type of software that provides communication and control over a deviceโ€™s hardware components. Itโ€™s the first piece of code that a device runs. Usually, it boots the operating system and provides very specific runtime services for programs by communicating with various hardware components. Most, if not all, electronic devices have firmware.
Devices store firmware in nonvolatile memory, such as ROM, EPROM, or flash memory.
Itโ€™s important to examine the firmware and then attempt to modify it, because we can uncover many security issues during this process.

Information gathering and reconnaissance

During this stage, collect as much information about the target as possible to understand its overall composition underlying technology. Attempt to gather the following:
  • Supported CPU architecture(s)
  • Operating system platform
  • Bootloader configurations
  • Hardware schematics
  • Datasheets
  • Lines-of-code (LoC) estimates
  • Source code repository location
  • Third-party components
  • Open source licenses (e.g. GPL)
  • Changelogs
  • FCC IDs
  • Design and data flow diagrams
  • Threat models
  • Previous penetration testing reports
  • Bug tracking tickets (e.g. Jira and bug bounty platforms such as BugCrowd or HackerOne)
Where possible, acquire data using open source intelligence (OSINT) tools and techniques. If open source software is used, download the repository and perform both manual as well as automated static analysis against the code base. Sometimes, open source software projects already use free static analysis tools provided by vendors that provide scan results such as Coverity Scan and Semmleโ€™s LGTM.

Getting the Firmware

There are different ways with different difficulty levels to download the firmware
  • Directly from the development team, manufacturer/vendor or client
  • Build from scratch using walkthroughs provided by the manufacturer
  • From the vendor's support site
  • Google dork queries targeted towards binary file extensions and file sharing platforms such as Dropbox, Box, and Google drive
    • Itโ€™s common to come across firmware images through customers who upload contents to forums, blogs, or comment on sites where they contacted the manufacturer to troubleshoot an issue and were given firmware via a zip or flash drive sent.
    • Example: intitle:"Netgear" intext:"Firmware Download"
  • Download builds from exposed cloud provider storage locations such as Amazon Web Services (AWS) S3 buckets (with tools such as https://github.com/sa7mon/S3Scanner)
  • Man-in-the-middle (MITM) device communication during updates
  • Extract directly from hardware via UART, JTAG, PICit, etc.
  • Sniff serial communication within hardware components for update server requests
  • Via a hardcoded endpoint within the mobile or thick applications
  • Dumping firmware from the bootloader (e.g. U-boot) to flash storage or over the network via tftp
  • Removing the flash chip (e.g. SPI) or MCU from the board for offline analysis and data extraction (LAST RESORT).
    • You will need a supported chip programmer for flash storage and/or the MCU.

Analyzing the firmware

Now that you have the firmware, you need to extract information about it to know how to treat it. Different tools you can use for that:
1
file <bin>
2
strings -n8 <bin>
3
strings -tx <bin> #print offsets in hex
4
hexdump -C -n 512 <bin> > hexdump.out
5
hexdump -C <bin> | head # might find signatures in header
6
fdisk -lu <bin> #lists a drives partition and filesystems if multiple
Copied!
If you don't find much with those tools check the entropy of the image with binwalk -E <bin>, if low entropy, then it's not likely to be encrypted. If high entropy, Its likely encrypted (or compressed in some way).
Moreover, you can use these tools to extract files embedded inside the firmware:
Or binvis.io (code) to inspect the file.

Getting the Filesystem

With the previous commented tools like binwalk -ev <bin> you should have been able to extract the filesystem. Binwalk usually extracts it inside a folder named as the filesystem type, which usually is one of the following: squashfs, ubifs, romfs, rootfs, jffs2, yaffs2, cramfs, initramfs.

Manual Filesystem Extraction

Sometimes, binwalk will not have the magic byte of the filesystem in its signatures. In these cases, use binwalk to find the offset of the filesystem and carve the compressed filesystem from the binary and manually extract the filesystem according to its type using the steps below.
1
$ binwalk DIR850L_REVB.bin
2
โ€‹
3
DECIMAL HEXADECIMAL DESCRIPTION
4
----------------------------------------------------------------------------- ---
5
โ€‹
6
0 0x0 DLOB firmware header, boot partition: """"dev=/dev/mtdblock/1""""
7
10380 0x288C LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 5213748 bytes
8
1704052 0x1A0074 PackImg section delimiter tag, little endian size: 32256 bytes; big endian size: 8257536 bytes
9
1704084 0x1A0094 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 8256900 bytes, 2688 inodes, blocksize: 131072 bytes, created: 2016-07-12 02:28:41
Copied!
Run the following dd command carving the Squashfs filesystem.
1
$ dd if=DIR850L_REVB.bin bs=1 skip=1704084 of=dir.squashfs
2
โ€‹
3
8257536+0 records in
4
โ€‹
5
8257536+0 records out
6
โ€‹
7
8257536 bytes (8.3 MB, 7.9 MiB) copied, 12.5777 s, 657 kB/s
Copied!
Alternatively, the following command could also be run.
$ dd if=DIR850L_REVB.bin bs=1 skip=$((0x1A0094)) of=dir.squashfs
  • For squashfs (used in the example above)
$ unsquashfs dir.squashfs
Files will be in "squashfs-root" directory afterwards.
  • CPIO archive files
$ cpio -ivd --no-absolute-filenames -F <bin>
  • For jffs2 filesystems
$ jefferson rootfsfile.jffs2
  • For ubifs filesystems with NAND flash
$ ubireader_extract_images -u UBI -s <start_offset> <bin>
$ ubidump.py <bin>

Analyzing the Filesystem

Now that you have the filesystem is time to start looking for bad practices such as:
  • Legacy insecure network daemons such as telnetd (sometimes manufactures rename binaries to disguise )
  • Hardcoded credentials (usernames, passwords, API keys, SSH keys, and backdoor variants )
  • Hardcoded API endpoints and backend server details
  • Update server functionality that could be used as an entry point
  • Review uncompiled code and start up scripts for remote code execution
  • Extract compiled binaries to be used for offline analysis with a disassembler for future steps
Some interesting things to look for inside the firmware:
  • etc/shadow and etc/passwd
  • list out the etc/ssl directory
  • search for SSL related files such as .pem, .crt, etc.
  • search for configuration files
  • look for script files
  • search for other .bin files
  • look for keywords such as admin, password, remote, AWS keys, etc.
  • search for common web servers used on IoT devices
  • search for common binaries such as ssh, tftp, dropbear, etc.
  • search for banned c functions
  • search for common command injection vulnerable functions
  • search for URLs, email addresses and IP addresses
  • and moreโ€ฆ
Tools that search for this kind of information (even if you always should take a manual look and get comfortable with the filesystem structure, the tools can help you finding hidden things):
  • โ€‹LinPEAS: Awesome bash script that in this case is useful for searching sensitive information inside the filesystem. Just chroot inside the firmware filesystem and run it.
  • โ€‹Firmwalker: Bash script to search for potential sensitive information
    • Identification of software components such as operating system, CPU architecture, and third-party components along with their associated version information
    • Extraction of firmware filesystem (s ) from images
    • Detection of certificates and private keys
    • Detection of weak implementations mapping to Common Weakness Enumeration (CWE)
    • Feed & signature-based detection of vulnerabilities
    • Basic static behavioral analysis
    • Comparison (diff) of firmware versions and files
    • User mode emulation of filesystem binaries using QEMU
    • Detection of binary mitigations such as NX, DEP, ASLR, stack canaries, RELRO, and FORTIFY_SOURCE
    • REST API
    • and more...
  • โ€‹FwAnalyzer: FwAnalyzer is a tool to analyze (ext2/3/4), FAT/VFat, SquashFS, UBIFS filesystem images, cpio archives, and directory content using a set of configurable rules.
  • โ€‹ByteSweep: A Free Software IoT Firmware Security Analysis Tool
  • โ€‹ByteSweep-go: This is a complete rewrite of the original ByteSweep project in Go.
  • โ€‹EMBA: EMBA is designed as the central firmware analysis tool for penetration testers. It supports the complete security analysis process starting with the firmware extraction process, doing static analysis and dynamic analysis via emulation and finally generating a report. EMBA automatically discovers possible weak spots and vulnerabilities in firmware. Examples are insecure binaries, old and outdated software components, potentially vulnerable scripts or hard-coded passwords.
Inside the filesystem you can also find source code of programs (that you should always check), but also compiled binaries. These programs might be somehow exposed and you should decompile and check them for potential vulnerabilities.
Tools like checksec.sh can be useful to find unprotected binaries. For Windows binaries you could use PESecurity.

Emulating Firmware

The idea to emulate the Firmware is to be able to perform a dynamic analysis of the device running or of a single program.
At times, partial or full emulation may not work due to a hardware or architecture dependencies. If the architecture and endianness match a device owned such as a raspberry pie, the root filesystem or specific binary can be transferred to the device for further testing. This method also applies to pre built virtual machines using the same architecture and endianness as the target.

Binary Emulation

If you just want to emulate one program to search for vulnerabilities, you first need to identify its endianness and the CPU architecture for which it was compiled.

MIPS example

1
file ./squashfs-root/bin/busybox
2
./squashfs-root/bin/busybox: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped
Copied!
Now you can emulate the busybox executable using QEMU.
1
sudo apt-get install qemu qemu-user qemu-user-static qemu-system-arm qemu-system-mips qemu-system-x86 qemu-utils
Copied!
Because the executable is compiled for MIPS and follow the big-endian byte ordering, weโ€™ll use QEMUโ€™s qemu-mips emulator. To emulate little-endian executables, we would have to select the emulator with the el suffix(qemu-mipsel):
1
qemu-mips -L ./squashfs-root/ ./squashfs-root/bin/ls
2
100 100.7z 15A6D2.squashfs squashfs-root squashfs-root-0
Copied!

ARM Example

1
file bin/busybox
2
bin/busybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-armhf.so.1, no section header
Copied!
Emulation:
1
qemu-arm -L ./squashfs-root/ ./squashfs-root/bin/ls
2
1C00000.squashfs B80B6C C41DD6.xz squashfs-root squashfs-root-0
Copied!

Full System Emulation

There are several tools, based in qemu in general, that will allow you to emulate the complete firmware:

Dynamic analysis

In this stage you should have either a device running the firmware to attack or the firmware being emulated to attack. In any case, it's highly recommended that you also have a shell in the OS and filesystem that is running.
Note that some times if you are emulating the firmware some activities inside the emulation will fail and you might need to restart emulating it. For example, a web application might need to get information from a device the original device is integrated with but the emulation is not emulating.
You should recheck the filesystem as we already did in a previous step as in the running env new information might be accessible.
If webpages are exposed, reading the code and having access to them you should test them. In hacktricks you can find a lot of information about different web hacking techniques.
If network services are exposed you should try to attack them. In hacktricks you can find a lot of information about different network services hacking techniques. You could also try to fuzz them with network and protocol fuzzers such as Mutiny, boofuzz, and kitty.
You should check if you can attack the bootloader to get a root shell:
You should test if the device is doing any kind of firmware integrity tests, if not this would allow attackers to offer backdored firmwares, install them in devices other people owns or even deploy them remotely if there is any firmware update vulnerability:
Firmware update vulnerabilities usually occurs because, the integrity of the firmware might not be validated, use unencrypted network protocols, use of hardcoded credentials, an insecure authentication to the cloud component that hosts the firmware, and even excessive and insecure logging (sensitive data), allow physical updates without verifications.

Runtime analysis

Runtime analysis involves attaching to a running process or binary while a device is running in its normal or emulated environment. Basic runtime analysis steps are provided below:
  1. 1.
    sudo chroot . ./qemu-arch -L <optionalLibPath> -g <gdb_port> <binary>
  2. 2.
    Attach gdb-multiarch or use IDA to emulate the binary
  3. 3.
    Set breakpoints for functions identified during step 4 such as memcpy, strncpy, strcmp, etc.
  4. 4.
    Execute large payload strings to identify overflows or process crashes using a fuzzer
  5. 5.
    Move to step 8 if a vulnerability is identified
Tools that may be helpful are (non-exhaustive):
  • gdb-multiarch
  • โ€‹Pedaโ€‹
  • Frida
  • ptrace
  • strace
  • IDA Pro
  • Ghidra
  • Binary Ninja
  • Hopper

Binary Exploitation

After identifying a vulnerability within a binary from previous steps, a proper proof-of-concept (PoC) is required to demonstrate the real-world impact and risk. Developing exploit code requires programming experience in lower level languages (e.g. ASM, C/C++, shellcode, etc.) as well as background within the particular target architecture (e.g. MIPS, ARM, x86 etc.). PoC code involves obtaining arbitrary execution on a device or application by controlling an instruction in memory.
It is not common for binary runtime protections (e.g. NX, DEP, ASLR, etc.) to be in place within embedded systems however when this happens, additional techniques may be required such as return oriented programming (ROP). ROP allows an attacker to implement arbitrary malicious functionality by chaining existing code in the target process/binary's code known as gadgets. Steps will need to be taken to exploit an identified vulnerability such as a buffer overflow by forming a ROP chain. A tool that can be useful for situations like these is Capstone's gadget finder or ROPGadget- https://github.com/JonathanSalwan/ROPgadget.
Utilize the following references for further guidance:

Prepared OSs to analyze Firmware

  • โ€‹AttifyOS: AttifyOS is a distro intended to help you perform security assessment and penetration testing of Internet of Things (IoT) devices. It saves you a lot of time by providing a pre-configured environment with all the necessary tools loaded.
  • โ€‹EmbedOS: Embedded security testing operating system based on Ubuntu 18.04 preloaded with firmware security testing tools.

Vulnerable firmware to practice

To practice discovering vulnerabilities in firmware, use the following vulnerable firmware projects as a starting point.

References

Trainning and Cert

Support HackTricks and get benefits!