Sunday, May 10, 2015

Elecom WRC-733FEBK Custom Firmware: Part 1 - Investigation

Elecom WRC-733FEBK. With an IC card on top for scale.
Elecom WRC-733FEBK. With an IC card on top for scale.


I bought this cute little router from Yodobashi Camera a few weeks ago for about 2,000JPY. I quite like compact hardware, and this was the smallest Wi-Fi router with four LAN ports that I could find. It works pretty well, but as usual the firmware is horrible and only exposes basic functionality. I haven't checked for security issues, but I wouldn't be surprised if it's full of holes. So I figured this weekend I'd spend some time hacking around with it!
Standard Disclaimer: Everything here will void your warranty. Messing around with bootloaders and firmware is a good way to kill your hardware. If you don't know the meaning of "3.3v UART", "initramfs" or "Kernel LZMA loader" then you should probably not try this at home :)

Basic Specifications

Model: Elecom WRC-733FEBK (Manufacturer site)
Size: 107x72x25mm, about 86grams
Power: 5V Barrel connector, rated at 1Amp. (Positive in the middle)
Wi-Fi support: 802.11ac, 802.11n, 802.11g, 802.11b, 802.11a | 2.4GHz and 5GHz supported
Antenna layout: 2.4GHz 2x2 | 5GHz 1x1
Ethernet: 1xWAN, 4xLAN. All ports are 100BASE-TX. No gigabit here. This is my main disappointment with the hardware.

Hardware Investigation

Step one is figuring out what hardware it uses, and evaluating if it's actually decent enough to warrant going any further. I've seen consumer routers with only 2MB of flash and 4MB of RAM, but hopefully this is a bit beefier. (Spoiler: Since I've bothered to write this blog post, you can probably guess the hardware is somewhat decent)

T9 Security Torx Screws and Wrench
T9 Security Torx Screws and Wrench

My first issue was these stupid "T9 Torx Security" screws that hold the case together. They are just Torx screws with a pin in the middle, which means you can't use a normal Torx wrench. Luckily a shop nearby had a set of security wrenches for 150JPY! There are only two screws under the front rubber feet, so even without the correct tools one could probably coax them out somehow. After removing both screws the top of the case unclips easily and reveals the board. There is a light pipe assembly on the front of the board that is easily removed too.

The Board

WRC-7333FEBK Board with highlighted parts.
WRC-7333FEBK Board with highlighted parts.

CPU (Cyan): RTL8881AN (Lexra RLX5281 MIPS based SoC)
Wi-fi (Blue): RTL8192ER (2x2 2.4GHz, Product page)
RAM (Red): 64MByte DDR2 (ESMT M14D5121632A, Datasheet)
Flash (Yellow): 8MByte SPI (MX25L6406E, Datasheet)
UART Header (Magenta): Pin1: VCC (3.3v), Pin2: GND, Pin3: TXD(3.3v), Pin4: RXD(3.3v)
Header (Green): Unknown right now, possibly USB? SPI? I2C?

Okay this looks good! It seems that the RTL8881AN is the main processor, and the RTL8192ER is acting as an auxiliary radio to allow simultaneous 2.4GHz + 5GHz operation.
A bit of googling shows that the RTL8881AN is a SoC based on a Lexra RLX5281 Big-Endian MIPS derivative, with some extensions for efficient network traffic processing.
64MB of RAM is pretty decent for a cheap consumer router, and 8MB of Flash is workable for a small Linux installation.
The unpopulated pin headers are a promising sign for hacking, and on the back of the board there's even silk screen text that labels the Magenta header as "UART"! It's easy to see on the board that Pin2 connects to the ground plane and Pin3/Pin4 traces run to the CPU. Connecting to each pin during boot reveals that Pin3 is TXD, and after some trial and error it can be found that the UART config is 38400 8N1.

Here are a few lines from boot:

---RealTek(RTL8881A)at 2013.11.01-19:18+0800 v0.7 [16bit](520MHz)
Jump to image start=0x80500000...
decompressing kernel:
Uncompressing Linux... done, booting the kernel.
done decompressing kernel.
start address: 0x80003400
init started: BusyBox v1.13.4 (2014-12-12 17:35:33 CST)
# cat /proc/version
Linux version (root@localhost.localdomain) (gcc version 4.4.5-1.5.5p4 (GCC) ) #1098 Wed Mar 4 13:15:16 CST 2015

So it runs an ancient version of Linux! And BusyBox! Both of these are GPL, so I should be able to go to the vendor site and get the source code and build my own kernel!
Yeah, about that... it turns out it's impossible to find source code on the Elecom, Logitec and Realtek sites. I've fired off some e-mails, but I'm not holding my breath. At least I have a root shell on it, although it seems to be lacking quite a lot of basic commands.
A bit more messing around reveals that entering the bootloader is possible using a couple of methods. Sending "ESC" over the serial line or holding the reset button during boot dumps you to a "<RealTek>" prompt with some interesting commands. Having access to a pre-boot environment makes it a lot safer to play around with. This bootloader actually allows loading a kernel over TFTP into RAM without touching Flash which will make experimenting much easier.

Realtek Bootloader Command Reference

If you type ? at the bootloader prompt you get some basic help, but I had to experiment a little bit to find out the exact operation of each command, so here's a quick reference.

---RealTek(RTL8881A)at 2013.11.01-19:18+0800 v0.7 [16bit](520MHz)
---Ethernet init Okay!
----------------- COMMAND MODE HELP ------------------
HELP (?)                                    : Print this help message
DW <Address> <Len>
EW <Address> <Value1> <Value2>...
DB <Address> <Len>
EB <Address> <Value1> <Value2>...
CMP: CMP <dst><src><length>
LOADADDR: <Load Address>
J: Jump to <TargetAddress>
FLR: FLR <dst><src><length>
FLW <dst_ROM_offset><src_RAM_addr><length_Byte> <SPI cnt#>: Write offset-data to SPI from RAM
MDIOR:  MDIOR <phyid> <reg>
MDIOW:  MDIOW <phyid> <reg> <data>
PHYW: PHYW <PHYID><reg><data>

DW - Hex dump memory in 32bit words
Address: Start address in hex ; Len: Words to dump in decimal (rounded up to nearest 4)
<RealTek>DW 80000000 8
80000000: DEADBEEF 13371337 00C0FFEE D15EA5ED
80000010: 00000000 00000000 00000000 00000000

EW - Write hex values to memory in 32bit words
Address: Start address in hex ; Values: space separated hex words (Unlimited?)
<RealTek>EW 80000000 deadbeef 13371337 c0ffee d15ea5ed

DB - Hex dump memory in bytes
Address: Start address in hex ; Len: Bytes to dump in decimal
<RealTek>DB 80000000 32
[Addr] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
80000000: de ad be ef 13 37 13 37 00 c0 ff ee d1 5e a5 ed .....7.7.....^..
80000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

EB - Write hex values to memory in bytes
Address: Start address in hex ; Values: space separated hex words (Unlimited?)
<RealTek>EB 80000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

CMP - Compare memory in 32bit chunks
dst: First address in hex ; src: Second address in hex ; length: Size in bytes (rounded to nearest word)
<RealTek>CMP 80000000 80000010 4
0th data(deadbeef 00000000) error
<RealTek>CMP 80000010 80000014 4
No error found

IPCONFIG - Get/Set the IP address the bootloader listens for TFTP on (default is
ip: The IP address to set
Target Address=
Now your Target IP is

AUTOBURN - Should the bootloader automatically burn the received image from TFTP into flash?
0 = no, 1 = yes

LOADADDR - Set the address TFTP loads data to
address: Address in hex
<RealTek>LOADADDR 80000000
Set TFTP Load Addr 0x80000000

J - Jump to an address
address: Address in hex
<RealTek>J 80500000
---Jump to address=80500000
Decompressing kernel... done!
Starting kernel at 80000000...

FLR - Read from Flash into RAM
dst: RAM address in hex ; src: Flash address in hex ; length: Byte count in hex(!!!)
<RealTek>FLR 80000000 100000 f
Flash read from 00100000 to 80000000 with 0000000F bytes         ?
(Y)es , (N)o ? --> y
Flash Read Successed!

FLW - Flash Write (UNTESTED)


MDIOW - MDIO Register Write (UNTESTED)

PHYR - PHY Register Read (UNTESTED)

PHYW - PHY Register Write (UNTESTED)

The bootloader accepts data over TFTP. Using the built-in Windows TFTP command it's possible to upload a kernel:
X:\>tftp -i put testkernel.bin
Transfer successful: 1048576 bytes in 2 second(s), 514296 bytes/s
On the target you'll see:
**TFTP Client Upload, File Name: testkernel.bin
- (Spinning progress indicator)
**TFTP Client Upload File Size = 00100000 Bytes at 80500000

That's enough investigation for now! It looks like getting OpenWRT working on this board should be within the realms of possibility and without too much risk. Right now the main roadblock is finding source code for the kernel and figuring out if it needs customizing (GPIO pinout, antenna setup, etc)

If you've actually read this far, then I recommend checking out this awesome talk on router firmware security: Too Many Cooks - Exploiting the Internet-of-TR-069-Things