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
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:
$s1 = FILECODE
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