Image Image Image Image Image Image Image Image Image Image

This 8-Bit Life | April 16, 2014

Scroll to top



Adventures in Linux: Reverse Engineering Firmware - This 8-Bit Life

Adventures in Linux: Reverse Engineering Firmware
Leland Flynn

***Update. I should note that I found SHA1 unsalted hashes in the filesystem. Unfortunately none of those passwords worked for my mysterious admin port. Gotta say thanks to all the folks in /r/hacking for the encouragement and helpful info. And many thanks to Hack a Day for posting my stuff!

I got home today after class with the intent to start playing around with some new network security tools in my lab, my classes are intellectually stimulating enough that I usually leave with ahead full of ideas and plans to break things in new an interesting ways. Today was no exception, except I never actually got to playing around with my new tools, and ended up learning how to reverse engineer binary firmware instead. I love when things take a turn for the organic!

So there I was, getting ready to hack around on my network. The first thing I did, as it occurred to me I never had before, was to port scan my external IP. I didn’t find much out of the ordinary open aside from one strange port, 4567. A few quick Google searches informed me that common belief was this was a port used by Verizon to automatically push firmware updates to customer premise equipment, namely that FiOS router (mine is a Westell 9100EM) you have sitting near your machine if you are one of the chosen. Well this piqued my interest, “Surely this would be password protected”, I thought.

Visiting my public IP with that port appended to it from a web browser returned a login prompt and sure enough my normal administrative login didn’t work. I found a few theories on the defaults for the account credentials in various forums but nothing concrete or functional. But this just wouldn’t do. I refuse to have a port exposed to the Internet that I don’t have access to. So I did what any self-respecting man would do. I tore apart the firmware for the router to look for the credentials by hand!

What follows serves as a pseudo tutorial/hacklog. I spend a number of hours learning from point zero how to do something that should ultimately take about 15 minutes. I know because I had to do it a second time to get all the screenshots. This project has been a ton of fun for me and it’s not over yet. I still have a lot more to learn here. But enough prattling, on to dirty work!

I began by pulling down a clean image of the router firmware from Verizon’s website.



I am a pretty regular listener of the PaulDotCom Security Podcast and have been hearing the hosts speak a lot about reverse engineering firmware for various embedded devices. They’ve mentioned that some of their first steps in understanding what you are dealing with is to run strings and hexdump against the binary in question. I had both tools place their output into files under a directory called “dumps”.


From here I opened each of the files up in the nano editor to get a look ate what might be in the header of the binary. Behold! It is Linux! Big surprise…

Luckily I also learned that this firmware is based on the OpenRG platform, that is to say that this firmware was developed by a third-party and customized by the manufacturer. **For more on OpenRG check out this link here.




So now we I knew I was dealing with a Linux-based firmware and I had a developer resource as well! Not much info but a place to start. Now it was time to fire up that binwalk tool I had heard so much about. I went ahead and gave the download its own directory in the interest of neatness.



Then took a look at the README which explained how to install with its handy little Python script. **Note to self, finish that damned book on Python and start learning it!



From here I went ahead and ran binwalk against my binary and got just a tiny step further. Looking at the screenshot below we can see that the last decimal (byte value location) of this uImage header is 171 bytes into the binary. Since all I wanted was the soft underbelly of the filesystem I needed to ignore this section. Using the dd command I was able to carve out the filesystem portion from the rest of the binary as shown below. And to verify that I got everything intact I ran the file command against this chunk to be sure it was a valid uImage file.




So what to do now? I have a binary filesystem that I can’t read from. A bunch of Googling an caffeine led me to a pretty nifty shell script that was built with the express purpose of  automatically extracting uImage data. Thank goodness for people smarter than I!

I downloaded the script from the developer’s website and used chmod to make it executable, otherwise it would bitch at me.



After running this handy script (that saved me a TON of trial and error) I now had a gzip compressed file called Image. I made sure to run file against it to verify that it was a sane image. I also got some more useful data! The file command told me when this file was last updated! This could be useful if I ever decided to start hunting for exploits for the firmware as I now had a time frame from which to base my exploit inquiry.



Next I uncompressed the gzipped “Image” file and renamed it to “vmlinux.bin”.



Now that I had an uncompressed binary of just the filesystem binwalk might just give me some real information about the firmware. Sure enough it found 3 separate filesystems, one called “romfs” and 2 others called “CramFS”. Now I don’t know the first thing about these filesystems but I definitely intend to learn more about CramFS, you’ll see why in a moment.


A bit more dd magic and I had 1 readable filesystem and 2 compressed (crammed?) filesystems. So I mounted up the romfs first only to find that it contained kernel modules. Not quite what I was after…






There wasn’t much here for me but I’ll probably poke around a bit more later on.


So, onward to the CramFS stuff! Again I have no idea how this filesystem works so I Googled around until I found a tool called lzma-uncramfs. This tool is meant to uncompress a CramFS filesystem and provide you with the raw directory structure and hopefully its delicious insides. I pulled the tar down from this link Then I compiled it from source with the make command. Then I went ahead and ran it with a “./” to run it from the path I specified and inserted a period as the output directory. I repeated this process for both cramfs files I had previously created with dd.







And just like that I had a fully uncompressed firmware image to dig around in! I even found the image files used by the browser interface for the router.





But sadly I have hit a wall. I’ve found plenty of good data in here but it looks like all of the really interesting stuff was exported as broken symbolic links and I’m not sure what to do to fix them. I’m going to be doing more research online over the weekend to see what I can come up with. Oh and if anyone who reads this has an idea as to why this happened please feel free to comment and let me know!

Until next time guys!

**If you would like to take a look at the work I have done so far download THIS TAR FILE!


  1. Sean W

    I have no experience with embedded development, but I wonder if those symbolic links point to another file system, possibly network mounted. Did you find an fstab?

  2. cheese

    found the passwords. hope they help.
    pass1: 00000000111222333
    pass2: entropic

    • Leland Flynn

      Oh awesome!
      I should update the post that I found SHA1 unsalted hashes in the filesystem. Unfortunately none of those passwords worked for my mysterious admin port.

  3. michaelbolton

    Very interesting. I hope you find out more about that hidden interface. Keep it up!

  4. This is a great writeup, now featured on hack a day.

    I do these boxes for my day job. One of the first things that you might want to consider is whether the router is “Tivo-ized,” meaning the firmware is digitally signed. Hopefully it isn’t, or it’s down to trying to exploit the router and take control while it’s running.

    There are some other threads on and that show up in a google search for keywords like “westell 9100 verizon” or “a90-9100em15″ but not much progress.

  5. Legai Lutin

    Men! Felt like I was reading a James Bond Book.
    Anyway, like Sean, my first guess about broken symlinks is that they refer to a file in another filesystem. Since you were proceeding by “elimination”, you might have to put all the uncompressed files together from all three filesystem to make sense of the whole thing.
    Did a great job about explaining the process. ouf!!!

  6. Xiao-Long Chen

    It looks like you tried to extract the second cramfs filesystem into the same directory as the first. That’s what’s causing you issues.

    For example, the first cramfs filesystem has /lib/ as a symlink. The second has /lib/ as a file. uncramfs-lzma will *not* overwrite files.

    Here’s a tarball with the files properly extracted:

    Hope this helps :)

    • Leland Flynn

      Taking a look right now! Thanks a so much for the info! I’m still learning here and I’m thankful for helpful folks like you.

    • Leland Flynn

      Also, may I ask what you did to extract this correctly?

      • Xiao-Long Chen

        You’re welcome!

        I used uncramfs in separate directories, like this:

        mkdir cramfs.1.extracted cramfs.2.extracted
        cd cramfs.1.extracted
        ../uncramfs-lzma . ../cramfs.1.bin
        cd ../cramfs.2.extracted
        ../uncramfs-lzma . ../cramfs.2.bin

        As long as you don’t extract them to the same directory, everything will be fine :)

    • Leland Flynn

      Ah, nvm I see. You extracted them as separate filesystems. I had tried this in my earlier attempts and thought that I had done it wrong due to all of the symlinks. I then tried to extract one on top of the other but got the same result. Any thoughts about the symlinks?

      • Xiao-Long Chen

        From what I can see, the second cramfs filesystem is mounted in /mnt/cramfs from the first filesystem. That way, all the symlinks would point to a valid file.

  7. Xiao-Long Chen

    By the way, the password is “activeVOLUser1″. More information available here:

    It seems you can enable telnet to get access to a shell :)

    • Leland Flynn

      Oh man! This is exactly what I was digging for. Guess I should have Googled harder. Well, at least I learned some cool stuff along the way!

      • Xiao-Long Chen

        Totally agree! It’s fun to learn about this stuff :)

      • Xiao-Long Chen

        By the way, I couldn’t find that page by searching for 9100EM. I was running “strings” on all of the files. When I got to “”, I found a link to So then I searched “jungo port 4567″ and, lo and behold, the first result was that link :D

  8. Elliot Saba

    Leland, this is a really great writeup, very enjoyable, and you introduced me to a great new tool called binwalk! Thank you for taking the time to do this, and keep sharing your hacking adventures!

  9. binwalk <= 1.0 includes an -e option that automatically does the dd'ing of the files for you based on a simple rules configuration file. Makes pulling files out alot easier.

    • Leland Flynn

      Yep! That post helped me a lot.

  10. Tormod

    “What follows serves as a pseudo tutorial/hacklog. I spend a number of hours learning from point zero how to do something that should ultimately take about 15 minutes. I know because I had to do it a second time to get all the screenshots.”

    This is why you are awesome, Sir. Your extra 15 minutes spent will save hours and hours for countless people.

  11. I\’m trying to RE an Apple Time Capsule, but unfortunately the firmware image is encrypted / compressesed, and binwalk did not help. Nice write up and screen grabs.

    • Leland Flynn

      Any idea how it is encrypted?

  12. name

    “Looking at the screenshot below we can see that the last decimal (byte value location) of this uImage header is 171 bytes into the binary.”
    Where is this screenshot ???

    • Leland Flynn

      Oh man thanks! I will insert that once I get back to my computer.

    • Leland Flynn

      Ok, that screenshot is up now. Thanks for the heads up.

      • name


  13. Fahraynk

    A full … maybe full tutorial of this with ALOT of examples for different devices would encourange alot of people to break into everything. Phones, especially portable gaming consoles would be hacked easyer. I want to get there one day myself. The more we hack these things, the faster life will get better… in my opinion anyway.

  14. jojoMcjojo

    Amusing that this particular device was being dug into last week. Coincidentally, I was attempting to do the same with the verizon branded openrg/jungo firmware for the mi424-wr a-e series last week, though to no avail, per a bunk output by binwalk. There is a python script to deobscurify the passes that has been known of since ’07, though google has chosen to kill off all references to “ActiveVOLUser1″ since this blog was promoted, or so it seems

    I also stopping by devttys0 where it is mentioned the device similarly uses cromfs, but as of the ’11 firmware, the only output is ~the last 16bytes iirc, a sig for a gzipped tar that once dd’d fails to extract… also flipped the endianness, but to no avail… supid firmware :( Anyway, the older firmware config files utilize the same obscured pw, ActiveVOLUser1, though from what I gathered -remember, verizon altered this in the new firmware to match a hashed/salted variant of the devices serial number -doesn’t work anymore for the TR-069 management interface (wan:4567), hopefully a bit more complex than what they initially did with their (horrible) use of wep (did I say horrible, I mean’t it) keys based on the mac id prefix/ssid… anyway if anyone wants to take a crack at it,
    the fw

    old cfgs, mi424wr

    sleep calls

  15. jojoMcjojo
  16. pretty interesting read – thank you leland!

Submit a Comment