Reverse Engineering A Router Firmware Image

Odds are that if you're reading this blog, you own one of these: Router.png

These routers appear like closed-off boxes, with this “firmware” voodoo that you need to download and update it once every few months. However, what if it was possible to take apart a router image and discover how it works? Let's tear the D-Link DWR-956 Router's firmware apart and discover how it works.

What You'll Need To Follow Along

You will need the following to start ripping apart router images and figure out how they work:

Getting Started

First things first, we will need to run binwalk on our .bin firmware image: initalbinwalk.png

As you can see, this image consists of two parts: An LZMA compressed file (compare to a .zip or .rar file) and a SquashFS Filesystem, common for compressing a Linux or Unix OS into small space. It's important to make a note that the LZMA file starts at byte 0 (or 0x0 in hexadecimal) and fills up in size to an unknown length, while the SquashFS filesystem is located at byte 2949120 (or 0x2D0000 in hexadecimal). Let's make a note of this as we continue to pick this apart.

Get Me Some SquashFS

Alright, so let's extract the SquashFS file from the bin image using dd: SquashFSinitdd.png

To explain this command, dd stands for data duplicator. It's a simple program that can be used in SUPER fancy ways, as it's capable of copying data bit-for-bit. dd takes an input file (the if= argument) and writes to an output file (the of= argument). We want to skip to byte 2949120, so we used the skip=2949120 argument, and we used bs=1 to tell dd to write to our linux output file in 1-byte increments. The status=progress thing gives us a way to track how much dd has written.

Great! We've plucked the SquashFS file out of the .bin image. Now let's decompress this filesystem to see what's inside. Run unsquashfs linux at the command line. When it completes, running the ls command to list folders and files will show that it's produced a folder called squashfs-root, which we can run cd squashfs-root and explore a bit.

Let's list the files inside this thing! Running find . | less gives us a scrollable terminal with a list of all files that came from this SquashFS file. It's immediately noticed that the system uses busybox for it's system binaries to keep it lightweight, and has website files in the srv directory. When it boots, it will become /srv. The Javascript is a little ugly, so we can throw it into a JS Pretty Printer tool, like the ones available online to make it more readable. We could dive deeper into this system image and even repackage the SquashFS image if we wanted to customize our router.

Recovering the LZMA

Now let's figure out what's in the LZMA archive: LZMAarchive.png

In dd, we change the value of skip= to 0 because that's where the LZMA archive begins. We can then use count=2949120 to go byte-by-byte, stopping at where the SquashFS system starts. We also changed the of= to the value “unknown.lzma” to save a file called unknown.lzma. However this file will be corrupt because we're appending extra binary data to it with dd. We can fix this by performing lzma -d < unknown.lzma > UNKNOWN. This little trick in bash uses the < operator to feed the unknown.lzma file to the decompression program and uses the > operator to spew the results into a file called UNKNOWN. Even if the program returns an error, we'll at least wind up with some results we can look at.

Performing binwalk on the file UNKNOWN shows that it contains a Linux Kernel, certificates, and firmware- all files required to boot the router. We could extract each individual file using the same dd commands we used above and fully recover all the data. We can also tell that this router uses a realtek wireless card due to the binwalk output as well, and can also tell that the system was compiled using GCC version 4.8.5.

What Could To Do From Here?

If all the files were extracted from the LZMA and the SquashFS is extracted as well, it would be possible to repackage your own customized router image. Want to remove the Web Console and enable SSH so you can control it that way? Want to re-theme the Web Console to your liking? Want it to host a game server instead of behaving as a router? All of these are possible things one could achieve.

However, the code for this is licensed to the company that produced it (in our case, D-Link). Publishing these findings as Open Source could make people angry, unless a rewrite was performed to make it your own creative spinoff.

As one final note, there's so much more one can learn in terms of taking apart firmware and binaries to figure out how they work, and building this skill is crucial for any developer, security analyst or tinkerer if they want their projects to stand out.

See You Next Time!

Liked This Content? Check Out Our Discord Community and Become an email subscriber!