For the Router Hacking Challenge Adrian Pastor was wondering if anyone knew how to read the configuration backup file that you can download from your ZyXEL router.
I happen to have a ZyXEL gateway as well, a P-2602HW-D1A to be precise, so I decided to take a look.
After looking at several of these files (called "rom-0" when
downloaded) I came up with the following structure:
There's two blocks in my file, one for memory and one for files I
guess. They start at 0x00000000 and 0x00002000 respectively and look
like this:
BYTE blocknumber BYTE unknown WORD nr of objects DWORD blockLength foreach object: CHAR[14] objectname DWORD uncompressed size DWORD compressed size DWORD offset to data from start of block
And there we encounter our first problem: the files can be
compressed..
For me the first block mentioned a "dbgarea", and the second block
"boot", "spt.dat" and "autoexec.net". But only the spt.dat seems to be
compressed. Since the other files show little of interest this is also
the file we're interested in.
Now to figure out the type of compression..
The first 32 bytes of my file look like this:
CE ED DB DB 00 03 00 09 00 00 06 84 08 00 00 ED 67 3B 5B 6D B0 00 0C 00 09 00 00 00 C8 4C 20 00
At first I had a hunch it might be LZW compression because that is often used in embedded devices, but I could not make it work on the data I had. Google also turned up nothing useful for me. So I decided to reverse engineer the firmware for my device to find the routines that read and write the spt.dat file.
I'm not going to go into the reversing itself today, but all I needed was this site and IDA Pro 5.1
From the disassembly I managed to figure out this structure for the spt.dat file:
DWORD Unclear (Load-addres?, Magic?, Endianness?) WORD Major Version WORD Minor version DWORD Unclear (Chunks?) until EOF: WORD org_size WORD raw_size BYTE[raw_size] Compressed data
The decompression routines were a bit too big and complicated for
me to follow since I'm no star at MIPS processors. But I did find
reference to files called "lzsc.c" and "lzsd.c".
A quick google led
me to the Stac LZS compression mechanism decribed at ANSI
X3.241-1994
I could not quickly find an implementation or tool to now decompress the spt.dat so I went ahead and started writing my own implementation in C# (source). It still has some bugs in it so the decompression is not perfect, but it is good enough to read all settings like passwords, snmp community strings, wep keys etc.