The ability to analyze a firmware image and extract data from it is extremely useful. It can allow you to analyze an embedded device for bugs, vulnerabilities, or GPL violations without ever having access to the device.
In this tutorial, we’ll be examining the firmware update file for the Linksys WAG120N with the intent of finding and extracting the kernel and file system from the firmware image. The firmware image used is for the WAG120N hardware version 1.0, firmware version 1.00.16 (ETSI) Annex B, released on 08/16/2010 and is currently available for download from the Linksys Web site.
The first thing to do with a firmware image is to run the Linux file utility against it to make sure it isn’t a standard archive or compressed file. You don’t want to sit down and start analyzing a firmware image only to realize later that it’s just a ZIP file:
OK, it’s nothing known to the file utility. Next, let’s do a hex dump and run strings on it:
Taking a look at the strings output, we see references to the U-Boot boot loader and the Linux kernel. This is encouraging, as it suggests that this device does in fact run Linux, and U-Boot is a very common and well documented boot loader:
However, taking a quick look at the hexdump doesn’t immediately reveal anything interesting:
So let’s run binwalk against the firmware image to see what it can identify for us. There are a lot of false positive matches (these will be addressed in the up-coming 0.3.0 release!), but there are a few results that stand out:
Binwalk has found two uImage headers (which is the header format used by U-Boot), each of which is immediately followed by an LZMA compressed file.
Binwalk breaks out most of the information contained in these uImage headers, including their descriptions: ‘u-boot image’ and ‘MIPS Linux-2.4.31′. It also shows the reported compression type of ‘lzma’. Since each uImage header is followed by LZMA compressed data, this information appears to be legitimate.
The LZMA files can be extracted with dd and then decompressed with the lzma utility. Don’t worry about specifying a size limit when running dd; any trailing garbage will be ignored by lzma during decompression:
We are now left with the decompressed files ‘uboot’ and ‘kernel’. Running strings against them confirms that they are in fact the U-Boot and Linux kernel images:
We’ve got the kernel and the boot loader images, now all that’s left is finding and extracting the file system. Since binwalk didn’t find any file systems that looked legitimate, we’re going to have to do some digging of our own.
Let’s run strings against the extracted Linux kernel and grep the output for any file system references; this might give us a hint as to what file system(s) we should be looking for:
Ah! SquashFS is a very common embedded file system. Although binwalk has several SquashFS signatures, it is not uncommon to find variations of the ‘sqsh’ magic string (which indicates the beginning of a SquashFS image), so what we may be looking for here is a non-standard SquashFS signature inside the firmware file.
So how do we find an unknown signature inside a 4MB binary file?
Different sections inside of firmware images are often aligned to a certain size. This often means that there will have to be some padding between sections, as the size of each section will almost certainly not fall exactly on this alignment boundary.
An easy way to find these padded sections is to search for lines in our hexdump output that start with an asterisk (‘*’). When hexdump sees the same bytes repeated many times, it simply replaces those bytes with an asterisk to indicate that the last line was repeated many times. A good place to start looking for a file system inside a firmware image is immediately after these padded sections of data, as the start of the file system will likely need to fall on one of these aligned boundaries.
There are a couple interesting sections that contain the string ‘sErCoMm’. This could be something, but given the small size of some of these sections and the fact that they don’t appear to have anything to do with SquashFS, it is unlikely:
There are some other sections as well, but again, these are very small, much too small to be a file system:
Then we come across this section, which has the string ‘sqlz’ :
The standard SquashFS image starts with ‘sqsh’, but we’ve already seen that the firmware developers have used LZMA compression elsewhere in this image. Also, most firmware that uses SquashFS tends to use LZMA compression instead of the standard zlib compression. So this signature could be a modified SquashFS signature that is a concatination of ‘sq’ (SQuashfs) and ‘lz’ (LZma). Let’s extract it with dd and take a look:
Of course, ‘sqlz’ is not a standard signature, so the file utility still doesn’t recognize our extracted data. Let’s try editing the ‘sqlz’ string to read ‘sqsh’:
Running file against our modified SquashFS image gives us much better results:
This definitely looks like a valid SquashFS image! But due to the LZMA compression and the older SquashFS version (2.1), you won’t be able to extract any files from it using the standard SquashFS tools. However, using the unsquashfs-2.1 utility included in Jeremy Collake’s firmware mod kit works perfectly:
Now that we know this works, we should go ahead and add this new signature to binwalk so that it will identify the ‘sqlz’ magic string in the future. Adding this new signature is as easy as opening binwalk’s magic file (/etc/binwalk/magic), copy/pasting the ‘sqsh’ signature and changing the ‘sqsh’ to ‘sqlz’:
Re-running binwalk against the original firmware image, we see that it now correctly identifies the SquashFS entry:
And there you have it. We successfully identified and extracted the boot loader, kernel and file system from this firmware image, plus we have a new SquashFS signature to boot!


















Awesome! Great read.
Very nice tutorial, thank you !
Great!
Will repost on my blog
very cool! I would be interested in seeing the reverse as well. Making a new firmware file
Great reading!!
I agree with two55309, i d also love to read more about editing the firmware
Great post! Congrats! Looking forward for more about editing the firmware.
Awesome!
I also would be interested in seeing the reverse of this.(building firmware image)
Awesome tutorial! Thankyou!
+1 for reverse tutorial?
Awesome
Fantastic post! I had always wondered about how this was done, but could never find a good resource.
I wish to add my +1 for a further post in this series, possibly detailing the reverse of this as others have suggested.
Many thanks!
Pingback: Reverse engineering a firmware | punnie.ath.cx
Thanks for the feedback everyone! It sounds pretty unanimous – a tutorial on building a firmware image will have to be next.
Pingback: Reverse engineering embedded device firmware - Hack a Day
Pingback: Reverse engineering embedded device firmware | You've been blogged!
Excellent tutorial! You describe this in a way that makes it seem very easy. I look forward to reading what you write next.
Really good work, hope to see more of these in the future, for other platforms perhaps?
Thank you for your detailed explanation, followed all the steps and it worked pretty nicely.
I like this and I’m thinking about putting this on my blog as a linkback.
Wow, great! Thanks for sharing your wisdom with the world!
What do I do when the firmware (e.g. http://bit.ly/jMx2Si) has some kind of checksum at the end? This makes re-packing it quite tricky.
This is a great tutorial! I had never heard of binwalk before, seems like a really handy tool for embedded work. Thanks for sharing!
Pingback: Ingeniería inversa en firmware, un ejemplo práctico | CyberHades
Hello,
I’ve gotten up to the part where unsquashfs-lzma. I’ve downloaded the Firmware Modification Kit, and compiled with make. Then I’ve taken the unsquashfs-lzma and put it in the same directory as my firmware file. Upon running it:
>./unsquashfs-lzma wag120.squashfs
>Reading a different endian SQUASHFS filesystem on wag120.squashfs
>zlib::uncompress failed, unknown error -3
>Bus error
Any help?
By far one of the best tutorials I’ve seen.
Very well done!
Thank you for all the effort you had on putting this altogether!
Great info, congrats by me also!!
Tried to follow your tut on a Thomson 585v7 firmware. Binwalk unfortunately cant recognise anything in the .bin file. Is it because of no signature for it in the magic file or it has to do something with the bin file?
Keep up the good work and please do post an editing the firmware tutorial
Great detail tut
thank you thank you
Pingback: links for 2011-05-31 « xtra’s blog
Hey, thanks a lot for this article! Love it!
This was such an informative read.
Thanks
I skimmed the article and see what’s going on but I couldn’t be bothered to click on one thumbnail after another of a terminal only to see text, e.g. of a command and its output.
Don’t you think it would be a much more readable, and Googleable, article if the text of the screenshots was presented as text in the article and none of the images existed?
>GPL violations
GPL is The Cancer
Nice post ! Very interesting. Found anything interesting in the SquashFS image?
BTW, I do however agree with Ralph you could lighten the screenshots or just put the commands inline with
I truly appreciate the article, it will be bookmarked for future reference. Unlike Ralph Corderoy, I especially liked the screen shots, as they allow one to see exactly how the different commands are invoked and what their outputs are. Once again, thanks, kudos!
Just great dude! I started messing with firmware modding and penetration testing on embedded devices and this tutorial gave me a good boost…
Bookmarked!
sercomm was not a total dead end, by the way:
http://www.nslu2-linux.org/wiki/Main/SercommFirmwareUpdater
@Adam Baxter:
If there’s a checksum in the firmware you’ll have to determine where the checksum is and what checksum algorithm is used. Haven’t looked at the ZIP file you linked to yet, but if there’s GPL code available for the device that that’s usually the easiest way to figure it out. Also look to see if open source projects like OpenWRT or DD-WRT (since you didn’t mention what this device is I’m assuming it’s a router!) have done any work on it. I plan on covering firmware mods in more detail in a later tutorial.
@Joseph:
The unsquashfs error you’re getting looks like you are using the standard version of unsquashfs instead of the lzma version. Are you sure you’re running the correct unsquashfs binary from the firmware mod kit source?
@ Jim:
I haven’t looked at the Thomson routers before. If you aren’t getting any results from binwalk then it didn’t find any known signatures in the file. What kind of output do you get from running strings? If there are few readable strings then I would suspect the firmware (or part of it) is compressed. Try running binwalk with the -a option; this will use all signatures and will result in a lot of false positive matches but may help you find some gzip or other compressed data in the firmware.
@ Ralph/Axelle:
I started writing the tutorial by just copy/pasting the text, but felt that the screenshots made the commands and their output much easier to follow. I agree though that having to click back and forth is a pain – I’ll be sure to have future pictures viewable inline with the text!
@Rogan Dawes:
I did Google Sercomm and found that link too, but since it wasn’t related to the filesystem I was looking for and wasn’t the object of the tutorial I skipped over it. Good point though that I should have mentioned in the tutorial – always Google odd strings in the firmware!
Binwalk compilation errors for Mac OSX – Could you please tell me how could I install libmagic for mac. Sorry for naive question but I couldn’t find source on the web.
thanks.
Chintan: I did look for libmagic for OSX, but couldn’t find it. Linux only I’m afraid. If you find a port for OSX thought, let me know!
@Axelle:
Yes, a quick skim through firmware found the hard coded SSL public/private key pair for the HTTPS server. Another one for LittleBlackBox!
Great post!
@Chintan Parikh
Try compiling the library:
http://sourceforge.net/projects/libmagic/
powertomato: Have you tried building against that libmagic library? It doesn’t look like it’s compatible with the libmagic library binwalk is built against.
@Craig
Also tried your instructions on a Thomson 585v7 7.4.4.7 UK firmware (Download link of bin file: http://goo.gl/fvTcr). Strings cant get anything usefull (link: pastebin.com/ibXN4KQy) and binwalk with the -a switch seems to get too much info (i m guessing false positive, as you mentioned. Link:pastebin.com/nCbvDuq2)
If you have any time to provide any ideas/steps to get pass this, i would gladly try to provide signatures for Thomson firmwares for binwalk.
Once again, thank you for your tutorial and time!
Gi0: I don’t see anything obvious in that firmware image, but given the size and the layout of the firmware update file, I’d be surprised if it’s Linux based.
Given the lack of nearly any strings, I’d say that aside from the header (the first few bytes look like they are “magic” bytes for the firmware header) the firmware image is probably compressed, but nothing that I recognize.
Thomson apparently has its own boot loader, at least for that model, so it’s possible that there could be a custom compression algorithm. See more here: https://forum.openwrt.org/viewtopic.php?pid=101182
Do you have physical access to one of these routers? Getting to the jtag/serial ports will likely give you a lot more information.
Pingback: Reverse Engineering Firmware « Yet Another Technology Blog
@Graig:
I have access to a couple of those routers, thank you for the tip and also for the link you provided!
This is an amazing article. The next part is definitely inevitable.
simple, yet effective.
nice read.
An interesting article.
Binwalk is definitely something I’ll be making use of in the future.
Also the method for searching for section starts using the padding in the image was crafty
Great article! I’ll try to do the same with TP-Link firmwares. For now, binwalk showed me the image is “Linux Journalled Flash filesystem, little endian”
@Craig:
No I didn’t try it… It’s not compatible – my bad! Sorry!
AFAIK libmagic is an optional part of posix so there is a good chance that the .so library file is somewhere on the MacOS system.
Is there an active place to chat about reversing firmware or an active binwalk community?
ret, http://www.openrce.org is a good place to start. Focuses on x86 reversing, but there is also some embedded discussions there too.
I’m actually having an odd issue. I tried to strip the latest firmware from linksys’ site like you did with dd with the exact same command. However when I try to decompress with lzma I get the error : lzma: uboot.lzma: Compressed data is corrupt. Currently, I’m using this version of lzma: xz (XZ Utils) 4.999.9beta
liblzma 4.999.9beta. What version are you using?
My lzma version is:
LZMA command line tool 4.32.0beta3
LZMA SDK 4.43
It’s the lzma utility in Ubuntu, so maybe it’s a different version from what you are using? I would expect any lzma decompression tool to handle the file though, it should just be standard lzma compression.
Are you sure you did the dd command correctly and got the ‘bs’ and ‘skip’ parameters correct? What does the file utility report the uboot.lzma file to be?
I am having the same problem.
lzma –version
xz (XZ Utils) 5.0.3
liblzma 5.0.3
file uboot.lzma
uboot.lzma: LZMA compressed data, non-streamed, size 147212
looks like an lzma/xz bug
Excellent article by the way
Ah, I figured out the problem. XZ Utils supersedes LZMA Utils.
From http://tukaani.org/lzma/
‘LZMA Utils
LZMA Utils are legacy data compression software with high compression ratio. LZMA Utils are no longer developed, although critical bugs may be fixed as long as fixing them doesn’t require huge changes to the code.
Users of LZMA Utils should move to XZ Utils. XZ Utils support the legacy .lzma format used by LZMA Utils, and can also emulate the command line tools of LZMA Utils. This should make transition from LZMA Utils to XZ Utils relatively easy.’
I downloaded the old LZMA Utils source, compiled and ran that version of lzma and everything was happy.
compiled ./lzma –version
LZMA command line tool 4.32.7
LZMA SDK 4.32
There are quite a few Chinese wireless routers, with 2mb rom, 16MB ram and atheros chips. They are all in Chinese. I was trying to figure out if I could install openwrt, when I found it was not possible, I was thinking if I could turn them into English. Using binwalk and other techniques mentioned here, I was unable to even find out what OS and file system it uses. Is it possible to extract html files from this rom image and modify them and repack them? The bin file is in this archive.
http://www.mercurycom.com.cn/downloadfilesuploadfolder/2011610171165.rar
strings and hexdump shows the file names in plain text. Don’t know how to extract them.
Pingback: /dev/ttyS0 » Blog Archive » Mystery File System
@Jim:
See the above track back. I was able to at least partially reverse the file system from the router firmware.
I am a bit late on the topic, but Linksys does provide source code for the previous 1.00.12 firmware on their website. Using that and a Linux machine to compile the source, I believe it may be easier to play around with this router. Plus, easier to enable all other incomplete/missing features, like IPv6, VPN, and the blessed telnet access to the device.
@Alex:
Good point, GPL source code is always helpful when reversing/playing with firmware. Unfortunately, source code isn’t always available or complete, so knowing how to take a firmware update apart is useful in those situations.
I really just picked out the WRT120N as an example after seeing someone else on the Web who had been trying unsuccessfully to take apart the firmware.
Just wanted to leave a note to say thank you! I’ve been having some problems with a YeaLink VoIP phone which runs Linux. Was able to use binwalk and gzip to extract the files required and was able to debug through the problem.
Very helpful post!!
I need your thoughts on decrypting Bravia Linux Firmware.
I used binwalk to anylse the file and got that:
root@ubuntu:/home/user/İndirilenler/binwalk-0.3.9/src# binwalk fw.bin
binwalk: /usr/local/lib/libcurl.so.4: no version information available (required by binwalk)
DECIMAL HEX DESCRIPTION
——————————————————————————————————-
3485529 0x352F59 bzip2 compressed data, block size = u00k
23646804 0x168D254 bzip2 compressed data, block size = S00k
24439192 0x174E998 BFLT executable version 3698180314, code offset: 0xD0DBFC89, data segment starts at: 0xFC57E3C8, bss segment starts at: 0x314AD91C, bss segment ends at: 0x579AC36E, stack size: -209315630 bytes, relocation records start at: 0x10C36FC1, number of reolcation records: 1388897630, gotpic gzdata
32409668 0x1EE8844 bzip2 compressed data
40790549 0x26E6A15 gzip compressed data, ASCII, has CRC, extra field, last modified: Sat Dec 8 07:18:40 2012
41683215 0x27C090F bzip2 compressed data
44487229 0x2A6D23D bzip2 compressed data, block size = X00k
But I can not move further. Could you please help me with that?
Sorry I forgot to post the firmware itsef. It is here:
http://www.mediafire.com/?371sodalbkui26h
And the source files Sony provided:
http://www.sony.net/Products/Linux/TV/KDL-40NX700.html
Pingback: Reverse Engineering Firmware: Linksys WAG120N
I have a zynos firmware here, i want to extract it but i got a error @Decode error
What means lzma Decode error
Tks
@Pintas:
It most likely means that the data you have is not lzma compressed.
Thanks for the answer
It worked it was my error Craig. I probably now have the kernel. The file extracted with lzma -d: http://www.2shared.com/file/rKMa4y5n/kernel.html
I cant find the filesystem. I tried to extract with firmware kit but not worked.
I have acess to the serial port of the router, can you point a link of what i can do with the serial port to extract the kernel.
Thanks in advance
Sorry my english
Well that depends on the underlying OS.
If the device runs Linux then it’s pretty easy: the /prod/mtd file will list all the mtd partitions and their names. One will likely be named ‘kernel’ or something similar. you can then read the kernel directly from /dev/mtdblockX (where X is the mtd number listed in /proc/mtd).
If it is running some other proprietary system, then who knows. But most of them provide at least basic mechanisms to view configuration data and read/write to memory/flash, so if you can figure out where the kernel is on flash or in RAM then you might be able to dump it though the serial port.
Pingback: Reverse Engineer Firmware | Pattonwebz Info
Hey, I’m attempting this with the Annex A version of the firmware. I get up to the step where you find the FS but searching the kernel for filesystem strings doesn’t return anything that I could identify as a FS (though my knowledge is fairly limited).
Any tips on where to go from here?
Heres the output in case it helps:
preboot=echo;echo Type “run flash_nfs” to mount root filesystem over NFS;echo
root_filesystem=rootfs.img
update_rootfs=tftpboot 80400000 $(root_filesystem);upgrade 80400000 $(filesize)
Cheers
Heya i am for the first time here. I found this board and I to find It really helpful & it helped me out much. I am hoping to offer something back and help others like you aided me.
You could definitely see your skills in the paintings you write. The world hopes for even more passionate writers like you who aren’t afraid to say how they believe. At all times follow your heart.
How can i extract the firmware of Linksys WRT120N?
Link:http://homedownloads.cisco.com/downloads/firmware/FW_WRT120N_1.0.01.001.bin
The only thing i can do is extracting the lzma compressed PFS.IMG file (file system similar to 3COM/SMC not linux based) located at
DECIMAL HEX DESCRIPTION
——————————————————————————————————-
945152 0xE6C00 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 1348080 bytes
Binwalk output gives a lot of false positives.
Thanks
Awsome, Thanks!!!
Nice hack information. Can i quote this article in my website.
http://linksyswag120n.blogspot.in/
Let me as i need more authentic content and i will mention your source.
Sure subin, that’s fine.
Hello,
First of all great tutorial!
I have an assigment for my master in router reverse engineering. Is there a way to emulate a router like
linksys wag120N? I don’t have the router and I would like
to test some of these great tips. Searching google I
found qemu and virtualbox, but I can’t find a tutorial
on how I can virtualize a router.
Thank you in advance!!!!!!!!!!!
Hi, great tutorial! Is there a reverse tutorial available to create the firmware back from what achieved in this tutorial? Thank you
I don’t know of one for this specific firmware, but the firmware-mod-kit should be able to extract and re-construct the firmware. You can also look at the firmware patch tutorial for the TEW-632 here.
Thank you!
Hi
I tried to follow your steps to reverse engineer my router’s firmware. Binwalk easily pointed the SquashFS file system to me.
“1180160 0×120200 Squashfs filesystem, little endian, version 4.0, size: 626964223 bytes, 538 inodes, blocksize: 0 bytes, created: Fri Dec 15 19:34:48 1989″
It starts with “hsqs” and seems to employ lzma compression.
I tried using various “firmware modding tools”, but even the unsquash-lzma tool, on compiling, gave the following error:-
“Can’t find a SQUASHFS superblock on router.sqashfs”
The other unsquashfs tools refused, citing lack of lzma support. Can you help me out? I’ve googled a lot and found no solutions.
Have you tried the various unsquashfs tools in the firmware mod kit as well? It has a couple different variations on the squashfs 4.0 utilities that may work for your firmware.
Pingback: Reverse Engineering Firmware | Alan Carvalho de Assis
how to extact frimware from a device…say modem or mobile!
is anybody actually planning to write a complete new firmware so our nightmare WAG120N turns into good old Tplink ??
I was just wondering if there is an easy way to convert the ascii-output from an firmware dump into a regular data/bin file? I’m trying to dump the firmware from an embedded linux device using the “dump” command in the redboot bootloader via a serial connection.
Pingback: YAWN … and TV Firmware… | Vote4Katz YAWN … and TV Firmware… | Katz's Blog
Pingback: Модификация на фирмуера