UPDATE: It turns out that the steps outlined here are all you need to do – the PKCS12 bundle is malformed (it looks like they accidentally hex-encoded the identifier twice as if it was ASCII both times, exceeding the maximum identifier size in the spec, and the app I was using couldn’t unlock it, but the OpenSSL CLI can handle it – begrudgingly)
My attempt to crack the md5crypt hash found in /etc/shadow on the device had failed (due to someone unplugging the machine I was using in the middle of the job), and after poking around at test pads around the SOC and finding nothing immediately useful, I decided the next step would be to dump the flash chip. I ordered an inexpensive device programmer from China along with a TSOP48 socket and it finally arrived after several weeks, so I bit the bullet and rendered my router useless for a while.
I was able to remove the flash chip from the board pretty cleanly with a hot air station. The flash chip uses a TSOP48 package, which has 48 0.25mm pins, 24 on opposite sides of each other, and it took several tries to get all of the pins lined up properly in the device programmer.
I was able to download and verify the data on the Flash chip, producing a 128MB binary (and a vague unease as I’d killed my only way to get onto the Internet)
I went ahead and cleaned up the pads on the board.
Since I had issues with pin alignment on the flash chip, I went ahead and wrote the binary to a brand new chip, and was able to get it put back on the board (drag soldering technique) and it fired right up.
After digging around in the flash chip, I found what appeared to be two PKCS12 bundles stored as base64-encoded variables passed to the bootloader.
I had to manually remove a few 64-byte chunks throughout the base64 data I was reading – my assumption is that these are EXT2 block descriptors or something, but once I removed the extraneous bytes, I was able to decode valid PKCS12 bundles from the base64 strings.
We’re almost there! Next step is to find the passwords.
After doing some grepping, I found some lua scripts on the device that seemed to refer to the certs I’d extracted.
The most interesting thing here is the
tw_ulib_get_network_cert method. After doing some more grepping, it looks like it’s exported from
libluacpe.so.0.0.0. Let’s take a look with radare2’s cutter.
Another interesting call here –
librgw_sec_get_shroud_key. That one is defined in
librgw_compat.so.0.0.0. Let’s check there!
So, at first glance, it looks like we take the devkey, serial number, and an ASCII string, and append them to each other to unlock these certs. Let’s see if we can find them on the flash.
Bringo! Both of the missing values are right here. Let’s give them a try.
Tried several different combinations and ordering, and capitalization, but no dice. I think we’re very close though. Next time, we’ll take a look at how the system is actually pulling back the devkey and serial number, and we’ll go back over the method being used to reassemble everything.