In order for things to work for the ULYSSIS CTF, we had to configure a bunch of routers (in this case, a D-Link GO-RT-N150). However, the web UI config was very limited, but we suspected the actual config format underneath was much more flexible.
In the web UI, there’s an option to import and export a config file. But on first sight, it looks like nothing useful at all:
|
1 2 3 4 5 6 7 8 9 10 |
00000000 5e a3 a4 17 00 00 00 40 00 00 07 a0 6b 2f f4 9e |^......@....k/..| 00000010 bc de 1b a0 46 1d 90 3c b0 0e e1 98 73 69 67 6e |....F..<....sign| 00000020 61 74 75 72 65 3d 47 4f 2d 52 54 2d 4e 31 35 30 |ature=GO-RT-N150| 00000030 5f 77 72 67 6e 36 32 00 6e 6f 68 65 61 64 65 72 |_wrgn62.noheader| 00000040 3d 31 00 74 79 70 65 3d 64 65 76 63 6f 6e 66 00 |=1.type=devconf.| 00000050 64 65 76 3d 75 70 67 72 61 64 65 00 1f 8b 08 00 |dev=upgrade.....| 00000060 00 00 00 00 00 03 c5 19 5d 53 db 38 f0 99 fc 8a |........]S.8....| 00000070 7b ef 94 c4 26 64 68 c7 e3 19 0a b9 1e 33 5c 60 |{...&dh......3\`| 00000080 20 bd de 5b 47 d8 4a a2 69 22 bb b6 4c 48 7f fd | ..[G.J.i"..LH..| 00000090 ed 87 64 cb 26 09 d0 a3 6d a7 83 57 ab d5 6a b5 |..d.&...m..W..j.| |
Searching on the Internet doesn’t yield much either. However, on further inspection, one can see the following:
5ea3a417is 4 bytes long and looks rather random, so it’s probably magic.00000040and000007a0Look like big-endian ints, probably the length of something.- Then there are 16 bytes of random data:
6b2ff49e bcde1ba0 461d903c b00ee198 - Following that, a bunch of null-terminated strings are found.
- Random data for the rest of the file.
Let’s try making sense of those integers first. The string starts at offset 1C and end at 5C. In other words, that’s where the 00000040 comes from!
The file is 2044 bytes long. In hexadecimal, that is 07fc. Subtract 5C (start of garbled data) from that, and you get 7a0. This probably means that blob is one whole instead of multiple things concatenated.
Now, if you look closer at the random data, it starts with the following bytes: 1f 8b. That’s the magic header for gzip.
Decompressing that data reveals an XML file with a plethora of options not available in the web UI. \o/ This isn’t of much use unless we can create these files by ourself, though. However, the only thing we still need to figure out is the 16 random bytes. I suspect this is a hash of some sort.
So, let’s try a bunch of hash functions with an 128-bit output on the data: (The output we want is 6b2ff49ebcde1ba0461d903cb00ee198)
|
1 2 |
$ tail -c +93 cfg.bin|zcat|md5sum 6207de154ebdc3c03ec836630831c059 - |
Nope. What if we try this instead?
|
1 2 |
$ tail -c +93 cfg.bin|md5sum 6b2ff49ebcde1ba0461d903cb00ee198 - |
Bingo!
So, here’s the file format:
|
1 2 3 4 5 6 7 8 |
cfg { u8 magic[4] = {0x5E, 0xA3, 0xA4, 0x17}; u32_be descrlen; u32_be bloblen; u8 md5sum[0x10]; // MD5 of `data` char descr[descrlen]; u8 data[bloblen]; // gzipped XML }; |
The implementation is left as an exercise for the reader 🙂
klonia”>alert(7);