Firmware Security: A guide to learning firmware pentesting from zero to one
As technology advances, so does the need for security. One area that has seen an increased focus in recent years is firmware security. Firmware is the low-level software that controls the hardware components of electronic devices. It's essential for the proper functioning of the device, but at the same time, it's also a vulnerable attack surface that can be exploited by malicious actors.
Firmware pentesting is a highly sought-after skillset in the security industry, as firmware is found in nearly all electronic devices. However, learning firmware pentesting can be a daunting task as there is a lot of information to cover. Without a structured approach, it can seem difficult to make sense of it all. But don't let that discourage you! By following a step-by-step process, anyone can master the concepts of firmware security.
It is important to note that security concepts should not be tackled without first gaining a solid understanding of the underlying technology. Jumping into security without a proper foundation can lead to confusion and limited progress. That's why we've compiled a list of things you need to know to get started with firmware security.
In this blog, we'll explore a structured step-by-step process to help guide you through the essentials of getting started with firmware concepts, security and pentesting.
The Learning Process
The process of mastering anything involves two stages: Prepare and Act. In the Prepare stage, you'll learn the concepts and gain practical hands-on experience. In the Act stage, you'll apply what you've learned to the real world.
Stage 1: Prepare
1. Computer Architecture: To understand firmware, you must first have a solid understanding of computer architecture.
2. CISC and RISC Architecture: Understand the concepts of CISC (Complex Instruction Set Computing) and RISC (Reduced Instruction Set Computing) architecture, including their differences.
3. OS Concepts: Knowledge of an Operating System (preferably Linux) is crucial to understanding how Linux firmware works. Familiarize yourself with the ARM toolchain, and if possible, explore the MIPS toolchain as well.
4. C Programming: Learn the Linux/Embedded C programming language. Understand the concepts of pointers, functions, memory, string handling, size of primitive and structure data types.
5. Python: Gain practical hands-on experience with Python programming. In addition, gain an understanding of how Python operates at a low level, including the role of the interpreter
6. Linux User Space: Familiarize yourself with concepts like ELF (Executable and Linkable Format), program memory space, proc filesystem, UDS (Unix Domain Sockets), networking in Linux. Write simple programs to illustrate the practical application of each concept.
7. Linux Low-level: Study concepts like kernel, device drivers, syscalls/ioctl, kernel image, build root.
8. Assembly and Instruction Set Architecture: Study assembly language, with a focus on the ARM architecture.
9. Bootloaders: Study bootloader concepts such as Uboot and Secure Boot. How baremetal, RTOS and Linux boot process works.
10. RTOS Development: Learn about Real-Time Operating Systems (RTOS) development, including FreeRTOS and QNX. Create and compile a "Hello World" (basic functionality) RTOS.
11. BareMetal Firmware Development: Study bare metal firmware development, create a LED blinking or "Hello world" firmware and run it on any dev board of choice (preferably) or in an emulation (See emulation below) if you do not want to buy a dev board.
12. External/Internal Storage: Learn about external and internal storage, including microcontrollers, SoC, ROM, flash, eMMC, SD card etc. Learn how to read/write data to the storage on the chips (on the PCB board). At a minimum, study and gain hands-on experience with the I2C and SPI protocols.
13. Datasheets: Pick a microcontroller of choice and go through its datasheet. Understand the pin functionality, memory regions, protocols supported and any interesting information like encryption, read/write blocking etc.
14. Emulation: Learn about binary and code emulation. Familiarize yourself with tools such as Qemu and Unicorn for binary and code emulation. There are also many tools that utilize Qemu to emulate Linux firmware. Write code and try to emulate it using unicorn.
15. Reverse Engineer Stuff: Write simple C programs with functions performing different tasks, compile it, then disassemble (objdump) it and compare the C code and the assembly code. Try to identify patterns and standards like function prolog/epilog, how data is pushed on the stack, how functions are called etc. Now utilize open-source reverse engineering tools such as radare2 and Ghidra to analyze the code and become familiar with the functionality and features they offer. Once you are comfortable with the tools, take any real life binary of your choice and reverse engineer its code, understand the code flow, analyse interesting functions. Play CTFs and challenges (old or new, does not matter) with Reverse engineering challenges.
16. Study Encryption Concepts: Learn Symmetric and Asymmetric encryption. Study how AES works. Study PKI concepts practically - X509 certificates, public/private keys. Understand how TLS protocol works (you can refer to TLS RFC 8446 for communication details). Use the OpenSSL utility to generate keys, certificates, encrypt/decrypt data, then write small programs to do the same thing using the OpenSSL library. Play CTFs and challenges (old or new, does not matter) with encryption challenges.
17. Study Firmware Update Concepts: Understand the concept, study different techniques used for updates like FOTA (Firmware-Over-The-Air), secure FOTA updates.
18. Fuzz Testing: Study the concept of fuzz testing, different fuzzing techniques and gain practical hands-on experience with open-source fuzzers. Start with simple to use fuzzers like radamsa, AFL etc. Use any binary of choice that you are comfortable with and fuzz it. lay CTFs and challenges (old or new, does not matter) with Fuzzing challenges.
19. Binary Exploitation Concepts: Study binary exploitation techniques, memory corruption, and attack techniques, including overflows, heap/stack relevance, return-oriented programming, and privilege escalation. Play CTFs and challenges (old or new, does not matter) with binary exploitation challenges.
20. Teach What You Learned: This one is a very important step. It has helped me immensely in my learning journey. Give talks and workshops at community events, it helps you to get critical feedback to solidify your understanding of the material you learnt and find anything you missed. I always advise everyone to give talks at various community events like null chapter monthly meets (https://null.community), and OWASP chapter meets (https://owasp.org). You should prefer not to give talks at conferences at this stage as we have yet to find real-life vulnerabilities.
Stage 2: Act
1. Pick a Firmware: Choose a firmware to analyze and check if there are any concepts that you need to know before starting. If there are, make a list and go back to the relevant step in Stage 1.
2. Extract: If the firmware file needs extraction scubas as a Linux firmware image, extract it and explore the extracted data and file system if any.
3. Static Analysis: Perform static analysis to explore the file system (if it has one), reverse engineer proprietary binaries/code, and look for implementation or standard security issues. In case of Bare metal, load it into Ghidra or similar tools, you may need to provide the controller type, Instruction Set Architecture and memory region details which you can easily get from the microcontroller datasheet.
4. Dynamic Analysis: Emulation is your friend here if you do not have direct access to the running firmware. Perform dynamic analysis of the binaries to understand the logic and behavior of the firmware. Emulation for baremetal firmware is a bit challenging as of today, however things might change in the future.
5. Find Bugs: This is the step you have been waiting to take all along. If you have done all the above and reached here, you are on your way to greatness :). Look for security bypasses or vulnerabilities. It's recommended to start with finding similar vulnerabilities that you found in previous iterations and gradually increase the complexity to more advanced bug classes. If this is your first time, focus on low-hanging fruits, do not jump straight away to complex vulnerabilities. Static analysis should give you some juicy information or simple vulnerabilities.
6. Go Back to Step 1: Once you have found one or more vulnerabilities, you can then go back to step 1 of the ACT stage, pick another firmware, and repeat the process. By continually practicing and applying your learning to real-world scenarios, you will continue to build your skills and become an expert in firmware pentesting. Gradually, keep improving to find complex vulnerabilities.
In conclusion, getting started with firmware pentesting requires a structured learning process, combining both theoretical and practical components. By following the steps outlined above, you can gain a solid foundation in firmware security concepts and develop the skills you need to find vulnerabilities in real-world firmware.
It's important to remember that this process is an iterative one and will require patience and persistence. Keep practicing and applying your learning to real-world scenarios, and don't be afraid to reach out to the community for help and feedback. The more you learn and practice, the better you'll become at firmware pentesting. So, don't give up, and keep pushing yourself to level up your skills!
Best of luck on your firmware pentesting journey!