The last time, I analyzed the the hardware and figured out where the
firmware is stored. So let's dump it. The datasheet
tells us, that the flash IC has an SPI interface. Now we need something
that adapts SPI to a more common interface like preferably USB. There
are several devices to to this:
- Use some microcontroller and write firmware for it that reads the
SPI flash and dumps its contents via UART/USB. Downside: have to
write code for microcontroller, hard to debug
- Bus Pirate already
supports SPI flashes. Unfortunately, Selfnet doesn't have one.
- FTDI also makes USB to SPI converters besides USB to UART. I didn't
have one at hand either, but I've had existing code for using
certain FTDI bridges as USB - SPI converts.
So I purchased the FT2232H Mini Module
and built an adapter to connect the SPI flash to it.
The FT2232H contains a so called MPSSE (Multi-Protocol Synchronous
Serial Engine) to do SPI. Side note: FTDI claims that the MPSSE also
supports I²C, but since the FT2232H doesn't have open-drain outputs
and has some glitching issues, it's really painful to implement. Since
my existing code was developed on Windows™, it used the proprietary
FTD2XX driver. After some fiddling, I got ftd2xx to work on python 3. Sorry, libftdi people :(
Implementing the protocol used by the SPI flash was rather
straightforward since its datasheet is available. One particular nice
aspect of the protocol is that you can read an arbitrary amount of data
after sending the start address. So I hacked an IPython notebook to
dump the flash. Magically, it worked the first time, therefore I didn't
bother to clean it up to make it publishable.
That's inside the romdump:
$ binwalk romdump
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
94976 0x17300 U-Boot version string, "U-Boot 1.1.3 (Dec 4 2013 - 08:55:41)"
131584 0x20200 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3515396 bytes
1441792 0x160000 Squashfs filesystem, little endian, version 4.0, compression:lzma (non-standard type definition), size: 5051300 bytes, 627 inodes, blocksize: 131072 bytes, created: Fri Jun 20 05:19:24 2014
8126480 0x7C0010 XML document, version: "1.0"
In the next post, we'll dig into the romdump.
To provide our members with the latest and greatest budget routers the
market has to offer, we buy updated models when restocking. So it
happened that procurement ordered some boxes of
TP-Link Archer C2.
Since plastikonf writes the configuration to the router by creating a
custom configuration file, the first thing to do is to get a
configuration backup and decrypt it to base the custom configuration on.
Fortunately other people already figured out the crypto stuff for all
models we've had so far. But when trying to decrypt the new router's
configuration file, the MD5 check failed. After disabling the MD5
check, we're left with garbled XML:
$ xxd cmpr | head -n 16
0000000: d186 bc52 606a da8c 8d2a abcc d855 f4b1 ...R`j...*...U..
0000010: fa80 0000 3c00 003f 786d 6c20 7665 7273 ....<..?xml vers
0000020: 696f 6e3d 2231 2e00 0030 223f 3e0a 3c44 ion="1...0"?>.<D
0000030: 736c 4370 6543 6f6e 6600 0069 673e 0a20 slCpeConf..ig>.
0000040: 203c 496e 7465 726e 6574 4708 0061 7465 <InternetG..ate
0000050: 7761 7944 6576 6963 6500 0a19 2020 3c0c wayDevice... <.
0000060: 5375 6d6d 61af 0072 7920 7661 6c3d 2200 Summa..ry val=".
0000070: 002e 3a31 2e31 5b5d 2842 6173 656c 6960 ..:1.1[](Baseli`
0000080: 006e 653a 312c 2045 7468 564c 4160 014e .ne:1, EthVLA`.N
0000090: 3a31 2922 202f 524c 4100 504e 554e 756d :1)" /RLA.PNUNum
00000a0: 6265 724f 6687 0145 6e74 7269 6573 5d31 berOf..Entries]1
00000b0: 018a 2623 496e 666f 0040 3720 203c 4d61 ..&#Info.@7 <Ma
00000c0: 6e75 6661 63c0 0074 7572 6572 4f55 4930 nufac..turerOUI0
00000d0: 4538 4400 1c45 3237 3520 203c 5365 722b E8D..E275 <Ser+
00000e0: 1469 616c 5b56 0021 4143 4445 3443 1400 .ial[V.!ACDE4C..
00000f0: 2748 6172 6477 6172 6556 00b0 1f2a 2241 'HardwareV...*"A
Looks as if they changed the crypto... Reverse engineering time :) Since
the router knows how to decrypt the configuration file, we need to get
its firmware for further investigation. Unfortunately, the firmware
upgrade files are encrypted as well, so we somehow have to extract the
firmware from the device itself. The guy who reverse engineered the
crypto for the previous models did so by loading a custom build of
openwrt into the RAM and then using openwrt to read out the firmware.
Since I'm a hardware guy and the Archer C2 seems to be unsupported by
openwrt, let's open the case. This is what we're looking at: (Ignore the
missing U18 for now, we'll get to that later)
- U11, U12, U14 and surrounding components: Voltage regulators
- T2-T4: Ethernet isolation Transformers
- U14: Realtek RTL8367RB
Switch, one port is connected to the processor via (R)GMII link
- U1: Mediatek MT7620
MIPS SoC, integrated 2.4GHz WLAN
- U504: Winbond W9751G6KB-25
64MByte DDR2 SDRAM
- U620: Mediatek MT7610 5GHz WLAN
- U619: Skyworks SKY85703
5GHz WLAN Frontend
- U18(missing): Winbond W25Q64BV
8MByte SPI Flash
- J2: UART
The device containing the firmware is U18, as it's the only one with
considerable amount of nonvolatile memory. It's commonplace for
embedded systems like these routers to store the firmware in serial
flash chips like we've got one here.
So I removed U18 in order to get hold of its contents. See the next
post on how that has been accomplished.
Ever wondered where all these wifi networks with strange names like WH-Derki or
WH-Bulu come from? These are the preconfigured wireless routers WH-Netz
sells. During the last several years, one of our members has
continously been developing and improving plastikonf, our custom
solution for automatically configuring budget routers. Finally, it's
available on Github! https://github.com/Selfnet/plastikonf
See upcoming posts for recent developments.