Skip to content

Case Study: Unkown Firmware Container

Peter Weidenbach edited this page Nov 14, 2019 · 5 revisions

Case Study: Unkown Firmware Container

Congrats! You have an unknown firmware container and not only one but multiple files of the same container type.

First you will try to discern common and uncommon bytes between the containers. Any magic or other useable info for a file type will be shared among all files and usually at the same offset. To identify common bytes you can either "look on the files" or use tooling to help your poor eyes find them faster. Luckily in about XX % of the cases (XX being somewhere in the 80s, according to my experience) the magic will be at the very start of the binary (think of ELF in elf binaries). As existing tool for help I would propose binwalk with the -W flag. You can also write some short python script to identify common bytes.

Let's look at an example:

$ xxd -c 32 -l 32 TL-MR3420_5_1.2.0.bin.enc                                                     
00000000: 5344 4e00 0105 3038 2e34 362e 3433 0000 59b1 c160 0012 d1a4 0017 860d 3cf6 da46  SDN...08.46.43..Y..`........<..F

$ xxd -c 32 -l 32 TL-MR3420_5_1.3.0.bin.enc 
00000000: 5344 4e00 0105 3137 2e30 392e 3432 0000 5a29 c7f0 0006 9930 0008 3f7c 4385 b248  SDN...17.09.42..Z).....0..?|C..H

$ xxd -c 32 -l 32 TL-MR3420_5_1.4.1.bin.enc 
00000000: 5344 4e00 0105 3137 2e32 352e 3436 0000 5b46 7de0 0006 9942 0008 3f93 7f8e 9386  SDN...17.25.46..[F}....B..?.....

You can see there are a total of 12 bytes shared among all three container files.

5344 4e00 01-- ---- 2e-- --2e 34-- 0000 ---- ---- 00-- ---- 00-- ---- ---- ----
  • The first 5 bytes look most promising, since they represent the largest shared block and at least the first three bytes are ascii letters.
  • The 6th, 7th and 8th shared byte are also connected, but looking at their surroundings reveals them to be part of a larger ascii string that might represent some version and is not completely shared among all files
  • Shared bytes 9 and 10 are both "Zero" bytes and might represent some padding while numbers 11 and 12 could be most significant bytes of a 32-bit integer.

While it would be possible to develop a magic signature for any or all of these bytes, a sensible way would be to either

  1. take the first 5 bytes (better chance to avoid false positives)
  2. take only the first 3 bytes (better chance to avoid false negatives) having more containers at hand could help choosing correct. We will take the former (5 bytes) approach in this case study.

The common bytes are 53 44 4E 00 01. In file magic definition one can define a series of bytes as string:

0	string	\x53\x44\x4E\x00\x01	Some unknown container

where 0 is the offset of our string in the file string is the type definition (for more on types see the docs), \x53\x44\x4E\x00\x01 is our string and Some unknown container is the "full" file type that will be shown if our signature is found. To enable the file command of also showing a mime type you have to add a !:mime definition after the signature:

0	string	\x53\x44\x4E\x00\x01	Some unknown container
!:mime	application/unknown-container

This signature can now be appended to a magic database of your choice. If you just want to test it, store it in a file (e.g. signature.file) and compile this file using the file command:

$ file -C -m signature.file

The command will generate a file called signature.file.mgc which you can now use with file:

$ file -m signature.file.mgc TL-MR3420_5_1.3.0.bin.enc
Some unknown container
$ file -m signature.file.mgc --mime TL-MR3420_5_1.3.0.bin.enc
application/unknown-container

See? Not that hard 😉 Have fun writing your first (or whichever) file signature.

Clone this wiki locally