Re-enabling JTAG and Debugging the WRT120N

After de-obfuscating the WRT120N’s firmware, I started taking a closer look at the code, which runs the now-defunct SuperTask! RTOS.

Thanks in no small part to copious debug strings littered throughout the code and some leaked Atheros datasheets, I made good progress in statically disassembling the code. The next step was to start debugging the system while exercising some of the router’s services.

The WRT120N does have a JTAG port (labeled J8), which appears to conform to the MIPS EJTAG standard header:

The WRT120N JTAG header

The WRT120N JTAG header

It didn’t work right out of the box though:

$ sudo openocd -f flyswatter2.cfg -f wrt120n.cfg 
Open On-Chip Debugger 0.7.0 (2014-01-05-12:41)
Licensed under GNU GPL v2
For bug reports, read
Info : only one transport option; autoselect 'jtag'
adapter speed: 6000 kHz
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain connect_deassert_srst
trst_and_srst separate srst_nogate trst_push_pull srst_open_drain connect_assert_srst
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
Info : max TCK change to: 30000 kHz
Info : clock speed 6000 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: mips.cpu: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Error: Error writing unexpected address 0xffffffff
Error: Error writing unexpected address 0xffffffff
Error: Error writing unexpected address 0xffffffff
Error: Error writing unexpected address 0xffffffff

It turns out that JTAG has been disabled in hardware and in software on the WRT120N. Luckily both were relatively easy to fix.

Continue reading

Reversing the WRT120N’s Firmware Obfuscation

It was recently brought to my attention that the firmware updates for the Linksys WRT120N were employing some unknown obfuscation. I thought this sounded interesting and decided to take a look.

The latest firmware update for the WRT120N didn’t give me much to work with:

Binwalk firmware update analysis

Binwalk firmware update analysis

As you can see, there is a small LZMA compressed block of data; this turned out to just be the HTML files for the router’s web interface. The majority of the firmware image is unidentified and very random. With nothing else to go on, curiosity got the best of me and I ordered one (truly, Amazon Prime is not the best thing to ever happen to my bank account).

Continue reading

From China, With Love

Lest anyone think that D-Link is the only vendor who puts backdoors in their products, here’s one that can be exploited with a single UDP packet, courtesy of Tenda.

After extracting the latest firmware for Tenda’s W302R wireless router, I started looking at /bin/httpd, which turned out to be the GoAhead webserver:

Server header string in /bin/httpd

Server header string in /bin/httpd

But Tenda has made a lot of special modifications themselves. Just before entering the HTTP receive loop, main calls InitMfgTask, which spawns the MfgThread function as a separate thread:

pthread_create(&var_10, 0, MfgThread, 0);

pthread_create(&var_10, 0, MfgThread, 0);

Hmmm…InitMfgTask and MfgThread? Related to manufacturing tasks perhaps? Iiiiiinteresting…

Continue reading

Reverse Engineering a D-Link Backdoor

All right. It’s Saturday night, I have no date, a two-liter bottle of Shasta and my all-Rush mix-tape…let’s hack.

On a whim I downloaded firmware v1.13 for the DIR-100 revA. Binwalk quickly found and extracted a SquashFS file system, and soon I had the firmware’s web server (/bin/webs) loaded into IDA:

Strings inside /bin/webs

Strings inside /bin/webs

Based on the above strings listing, the /bin/webs binary is a modified version of thttpd which provides the administrative interface for the router. It appears to have been modified by Alphanetworks (a spin-off of D-Link). They were even thoughtful enough to prepend many of their custom function names with the string “alpha”:

Alphanetworks' custom functions

Alphanetworks’ custom functions

The alpha_auth_check function sounds interesting!

Continue reading

Differentiate Encryption From Compression Using Math

When working with binary blobs such as firmware images, you’ll eventually encounter unknown data. Particularly with regards to firmware, unknown data is usually either compressed or encrypted. Analysis of these two types of data is typically approached in very different manners, so it is useful to be able to distinguish one from the other.

The entropy of data can tell us a lot about the data’s contents. Encrypted data is typically a flat line with no variation, while compressed data will often have at least some variation:

Entropy graph of an AES encrypted file

Entropy graph of an AES encrypted file

Entropy graph of a gzip compressed file

Entropy graph of a gzip compressed file

But not all compression algorithms are the same, and some compressed data can be very difficult to visually distinguish from encrypted data:

Entropy graph of an LZMA compressed file

Entropy graph of an LZMA compressed file

However, there are a few tests that can be performed to quantify the randomness of data. The two that I have found most useful are chi square distribution and Monte Carlo pi approximation. These tests can be used to measure the randomness of data and are more sensitive to deviations in randomness than a visual entropy analysis.

Continue reading

Reverse Engineering Serial Ports

Given the name of this blog and the number of requests that I’ve had, I think it’s high time we discussed serial ports; specifically, serial ports in embedded systems.

My goal here is to describe the techniques that I’ve found effective in identifying and reverse engineering embedded serial ports through the use of definitive testing and educated guesses, and without the need for expensive equipment.


Serial ports are extremely useful to embedded developers, who commonly use them for:

  • Accessing the boot loader
  • Observing boot and debug messages
  • Interacting with the system via a shell

Needless to say, this functionality is also useful to hackers, so finding a serial port on an embedded device can be very advantageous. As a case study, we’ll be examining the PCB of a Westell 9100EM FiOS router for possible serial ports:

Westell 9100EM PCB

Continue reading

Jailbreaking the NeoTV

Today we’ll be jailbreaking the Netgear NTV300 set top box…with a TV remote.

The Netgear NeoTV 300

Negear’s NeoTV set top boxes are designed to compete with the popular Roku, and can stream video from all the usual sources (Netflix, HuluPlus, Youtube, etc). The NTV300 is one of the least expensive NeoTV models, and while a GPL release is available, it contains only copies of the various standard open source utilities used by the NTV300. All the interesting bits – such as Netflix streaming, or the ability to build a custom firmware image – are not included.

Inside the NTV300 we find a Mediatek ARM SoC, a 128MB NAND flash chip and 256MB of RAM:

Inside the NTV300

Continue reading

Exploiting a MIPS Stack Overflow

Although D-Link’s CAPTCHA login feature has a history of implementation flaws and has been proven to not protect against the threat it was intended to thwart, they continue to keep this feature in their products. Today we’ll be looking at the CAPTCHA implementation in the D-Link DIR-605L, which is a big-endian MIPS system running Linux 2.4.

A pre-authentication vulnerability exists in the DIR-605L’s processing of the user-supplied CAPTCHA data from the Web-based login page. The formLogin function in the Boa Web server is responsible for handling the login data, and obtains the value of the FILECODE POST variable using the websGetVar function. The FILECODE value contains a unique string identifying the CAPTCHA image displayed on the login page, and is saved to the $s1 register:


If the CAPTCHA feature is enabled, this value is later passed as the second argument to the getAuthCode function:

FILECODE value being passed to getAuthCode

The getAuthCode function saves the FILECODE value back to the $s1 register:

$s1 = $a1

Which in turn is passed as the third argument to sprintf, (note the ‘%s’ in the sprintf format string):

sprintf’s are bad, mmmk?

The result of the sprintf is saved to the address contained in $s0, which is the address of the stack variable var_80:

$a0 = var_80

This is a classic stack based buffer overflow, and overflowing var_80 allows us to control all of the register values saved onto the stack by getAuthCode’s function prologue, including the saved return address and the saved values of the $s0 – $s3 registers:

getAuthCode stack layout

Continue reading

Reverse Engineering a DTV Converter

I have an old DTV converter sitting around gathering dust, so I thought it would be interesting to take a look inside:

Inside the DTV Converter

As you can see, there’s not much there: a Thomson TV tuner, an IR receiver, 32MB of RAM and a 2MB flash chip (on the underside of the board). What really makes this interesting though is the LGDT1111 SoC; this is a DTV chip manufactured by LG, so it’s a little different than the Broadcom/Atheros/Ralink/etc SoCs found in a lot of other consumer devices. It is very popular with many DTV converters though, so determining its CPU architecture and reversing the underlying firmware could be interesting.

Digging around on the Internet turned up a nice block diagram of the LGDT1111 (courtesy of MVPtek):

LGDT1111 Block Diagram

The MVPtek web site states that the SoC uses an “AMR926EJ-STM” controller…could they mean an ARM926EJ-STM? Hmmm…

Continue reading