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

The four pin header in the top right corner of the PCB is a serial port (115200 baud 8N1), and while it provides access to the U-Boot boot loader, it does not provide a root shell. After the system boots, it displays copious debug messages and allows for rudimentary control over the NTV300’s user interface (i.e., pressing the right arrow key on the keyboard while in the serial terminal is the same as pressing the right arrow key on the remote control). Various attempts to send BREAK and SIGINT signals have no affect; we’ll have to dig a little deeper into this one.

Luckily, the firmware updates for the NTV300 aren’t encrypted. A binwalk scan of the firmware update image reveals a few firmware headers and two SquashFS images:

While the firmware update does not appear to contain a complete file system, most of the interesting stuff appears to be in the first SquashFS image. The /usr/local/bin/ntv300ui binary is particularly interesting as it is responsible for providing the NTV300’s user interface, including the handling of user input from both the remote control and the serial console.

Although the ntv300ui binary has been stripped, there are plenty of debug printfs that reveal the original function names:

Printf’s reveal original function names

A quick IDAPython script takes care of renaming most of these functions:

With functions properly named, reversing can begin in ernest, and the code in ntv300ui isn’t exactly confidence inspiring. It looks like Netgear hired some Unix admins and told them to write an application in C; for example, here is how they re-implemented libc’s stat() function:

How not to stat a file

In fact, system() and popen() are used generously throughout the code. These are particularly interesting:

System calls to iwpriv

Popen calls to iwpriv

System call to wpa_cli

The SSID and encryption key values are used as part of system() and popen() calls. So where do the SSID and network key values come from? You guessed it, the user:

User controlled data!

So what happens if we tell the NTV300 to connect to an SSID named “`reboot`”?

Command injection via SSID

Connecting to `reboot`

Rebooting!

Sweet! Since we are already connected to the serial port, it would be nice if we could spawn a shell for ourselves on the serial terminal. Let’s try:

Connecting to “;/bin/sh #

Shell successfully spawned on the serial terminal

While this provides us with a minimalist shell, it is not very user friendly. There is no command echoing, and a ton of debug output is intermixed with the command output. Let’s see if we can find an easier way to get a shell – preferably one that doesn’t involve taking the device apart.

Examining the file system on the live device, there are plenty of files and directories that were not included in the firmware update file. Checking out some of the start up scripts, we find this juicy piece of code in /root/rc.user:

It checks to see if the /mnt/ubi_boot/mfg_test/enable file exists, and if so, it fires up a telnet service (among other things). However, the mfg_test directory doesn’t exist at all on the production system:

Directory listing of /mnt/ubi_boot/

But with the SSID command injection vulnerability, we can easily create it. The commands to create the file are too long to fit into the restricted 32-character SSID input field, so we’ll echo them piecemeal into a shell script and then execute that script:

cd /mnt/ubi_boot

mkdir mfg_test

cd mfg_test

echo >> enable

/bin/sh /tmp/a

Finally, we power cycle the box. If successful, the NTV300’s IP address should have been set statically by the /root/rc.user script upon reboot. Let’s check:

Static IP settings

We can now change the DHCP settings back to dynamic, connect the NTV300 to our access point and telnet in (username root, no password):

Root telnet shell

Rooted with nothing but the remote control it came with. That’s all folks.

151 Responses to Jailbreaking the NeoTV

Do you know if that’s also true for the other NeoTV models?
Is it possible to modify the system to make jailbreak permanent?

I’d like a programmable set top box that can play Hulu & Netflix – this seems to fit the bill. Do you know if I get the NeoTV Max (the one with analog outputs and qwerty remote), will it blend? (that is, jailbreak?)

I have no idea if this affects other NeoTV models. It wouldn’t surprise me if it did (vendors tend to re-use code a lot), but the ntv300ui binary seemed specific to the NTV300 so maybe not.

The above jailbreak is permanent for the NTV300. The created file persists across reboots and ensures that the telnet server is started on every boot. You could add your own files/binaries to the system and they should remain across a reboot as well. Note that file system modifications do appear to be removed when you reset the device though.

First, I tried that. 🙂 Although inetd would run, for whatever reason, even with the ampersand inetd never returned, so the NeoTV would think that it was permanently stuck trying to “connect” to the AP, and it wouldn’t let me connect to my actual AP in order to telnet in. If you look at the screenshot from when I started the shell on the serial terminal, it prints out a message saying that the shell has no job control, so that might be the culprit. I didn’t really look into it further. You can probably get around this by plugging in a wired connection to the NeoTV’s ethernet jack.

Second, creating the mfg_test/enable file ensures that the telnet server is started every time the devices boots up, so I don’t have to keep re-running inetd each time I reboot the system.

Technically yes, but it was a very unfriendly shell. Random characters typed into the shell would get dropped (presumably because the ntv300ui application was also reading keystrokes from the serial port) and with no command echoing there was no way to know if that had happened until after you’d typed out your command and hit enter.

Also, I really wanted a way to do it without having to open the case and connect to the serial port since that would make it easier for others to duplicate if they desired. Plus I really liked the idea of being able to root the box using *only* the remote control. 😀

Ultimately, once you have command injection as root, what you do from there is just details and personal preference. Curl is already installed, so you could just as easily have curl download something from a Web server and execute that for example.

Depends on your needs; the main reason I was looking at the NeoTV is because it has Netflix suport, which is something open source alternatives all currently lack. Although I have been meaning to look into the possibility of taking the netflix binaries off the NeoTV and putting them on a raspi.

The netflix binary appears to be heavily tied to the ntv300ui binary – if the ntv300ui process is not running, the netflix binary will just sit there and hang. There are also several DRM files referenced by the netflix binary that are on the system, but not included in the firmware update, so these may be dynamically generated. I haven’t really had time to take a serious look at it, but if you are just trying to get Netflix running on your Linux PC, this is probably a better bet.

Can’t believe they put a backtick onto an on screen keyboard! 😀
(Apparently not even in confusion with the apostroph, which is present as well) I cannot imagine what an average user would want that for.

Craig, Would you also kindly advise how we may go about manually updating the NTV200’s firmware if we have a .fwu image instead of the automatic updates that is done by the NTV200 itself? Thanks a lot! – DB

I don’t think there is an official way to perform manual firmware upgrades. On boot up the devices phone home to see if there are any firmware updates available, and if so, they upgrade themselves. The connections to Netgear’s servers aren’t encrypted though, so you could redirect the DNS lookups to a local server of your own and serve up firmware upgrades from there.

Hi Craig! Good article as always.
I always thought files you create on embedded systems are deleted upon reboots as i thought they reside in RAM. and all permanent files should be flashed by part of filesystem image.
Could you cover a bit on this topic. What it depends on if new files survive reboot or not.
Thanks and keep posting.

It depends on the filesystem(s) used by the embedded device. SquashFS and CramFS are read-only, so you can’t write data to them at all. RamFS is obviously writable, but gets blown away on a reboot. Other file systems, like JFFS2, EXT2, and Minix, are full read/write file systems and retain data across a reboot.

It is not uncommon for devices to use SquashFS/CramFS for the main system files, and have some other directories mounted as JFFS2 so that they can save configuration data there (DD-WRT has separate SquashFS/JFFS2 partitions for example).

I haven’t had time to take a serious look at it. Current NTV200 firmware updates are encrypted and I don’t have an NTV200 myself. However, Stewart posted a link to an older firmware version above, which is not encrypted, so that will be a good place to start looking. Besides extracting the file system from the firmware though, I haven’t done much with it.

Very nice article. Do you think there is a way to make a custom firmware update that will allow that box to play video from online websites like http://www.chooseandwatch.com/ or some other website that has link for online TVs?
If there is a way to modify the box to to play video from Windows Media server? The links are mms:// there are many web sites offering free online tv and this device will be great alternatives for people that want to watch it on their TVs instead of the computer monitors.

@Craig: I have a NeoTV300 and a NeoTV300SL (Max). I tried the reboot command as a test on my NeoTV300 and it did not work; I have not tried on the Max yet. If interested, I can reads/post the firmware version.

Can you confirm this still works after the latest updates?

Do I have to have a router with the proper SSID’s?
I did set one up with reboot as the name, but it still didn’t work. I’m just wondering as it relates to the rest of the commands.

It looks like Netgear has pushed out a new firmware version. I’m downloading it now to take a look.

Worst case scenario, it looks like tricking the NTV300 into downgrading the firmware should be pretty easy – it calls out to a hard-coded site to look for firmware updates, and none of the traffic is encrypted. Simple DNS spoof should take care of it.

And no, the SSID’s you specify don’t have to actually exist – at least they didn’t in the firmware version I examined here.

Hi Craig
How does this DNS spoofing work and how do you do it.
I just bought one of these boxes hooked it up and it updated the software. what is the step by step for downgrading the software on the neotv.i am not very tech savy but I am willing to learn.

Also, if one can read the firmware file systems, can’t one extract them and add/subtract things from them to create your own custom firmware? Possibly with DNS Spoofing to get it to do the right thing and go to a local server?

Yes, but one would have to reverse the format header in order to re-calculate any checksum fields. This also assumes that the firmware isn’t signed; I haven’t seen anything that leads me to believe that it is, but the other NTV models have signed firmware.

Hey Craig, it looks like .61 is out and this was back from .48. Have you tried this since the new software? I can’t seem to get the “mfg_test/enable” stuff to stick. After a reset it completely dumps the data.

BTW, with the .58 firmware, I was able to extract the squashfs image by using
dd if=NTV300B_V1.00.58NA.bin of=fred bs=1 iseek=4183248
unsquashfs fred

It looks like there’s usr/etc/sdk_config.conf file there. If this is more than just a reference, it might be a good vector of attack since we should be able to replace the squashfs image with our own (assuming we can figure out any checksums on the entire .bin blob) and have an injection attack to get the box to update itself.
SDK_CONFIG_FACTORY_TEST_MSG_ENABLE = 0
SDK_CONFIG_FACTORY_TEST_AUTO_DL_SCRIPT = 0
SDK_CONFIG_FACTORY_TEST_AUTO_DL_SERVER = http://192.168.0.1/
SDK_CONFIG_FACTORY_TEST_SCRIPT_FILENAME = factory_test.sh

Im still wondering what the benefits of the jailbreak are….like android you get root access to personalize the phone, and iphone you can tweak your system function….what does this jailbreak do ??? btw i just got this so thats why im curious

well thanks alot craig ,
i will see if i can manage to get it work somehow ..
i have tried to use firmware-mod-kit to extract and rebuild image of NTV300SL without any modification on filesystem , it calculated checksum of header with no problems ,, but it wasn’t an exact match of original .. still thinking if i should try to apply the generated firmware or not.

Craig: I apologize in advance for such an off topic question, but I’m getting nowhere on the Netgear forums and you obviously know your stuff.

I have the base model NTV300 and a recent firmware update added DLNA support which my box isn’t supposed to have. I think it was a mistake and now there is another firmware update pending that I haven’t run because I’m afraid it will “patch out” the new “My Media” channel which includes the DLNA sharing. It also includes the ability to browse USB, which my version doesn’t even have, another reason I think the feature was added in error.

Any idea how I can find out if the firmware with DLNA support was indeed intended for my box? Or to find out if the newest unapplied firmwmare update will wipe it out?

Now that I have it I don’t want to lose it. It actually works great … thanks.

One option is to get the latest firmware (a link to the latest firmware image can be found here), find and extract the SquashFS file system using binwalk/firmware-mod-kit, then look to see if there are any executables with the string ‘dlna’ in the name (I’m assuming the dlna binary will have the string ‘dlna’ in it). If so, then the new firmware probably has DLNA support (although it’s no guarantee).

Since you sound happy with the firmware you have, another option is to trick the NeoTV into thinking that there is no new firmware upgrade. The NeoTV’s check for firmware upgrades by requesting a URL from updates1.netgear.com. You could set up a fake DNS server on your network to black hole this domain name, or your router might support blocking web requests based on domain name or keywords. There is a more detailed write up on the firmware upgrade process on rayman’s blog.

Thanks for the idea ‘Craig’. I did one better. I setup a local web server and gave my router a static DNS mapping to point ‘updates1.netgear.com’ to to my web server.

My web server also has the same folder structure as netgear’s. I download an earlier version of the firmware. The lastone that had DLNA for me was 1.0.76NA. I downloaded and modified ‘fileinfo.xml’. I changed the ‘date’ field in the XML file
to one day higher than what was already there. Also, I only increased the DATE field in the XML file. I change the path to the target file to point to 1.076NA and change the “firmware version string to 1.0.77NA”
I then had the ntv300b poll for updates. It found one, and installed .. Bam. I now have DLNA back from 1.076NA.

Brian I just picked up a NTV for DNLA streaming but when setting up was forced into updating to 1.0.78NA which like you removed that service. Not an IT expert but think i can set up that same folder structure on my mac. by changing the version number was able to download http://updates1.netgear.com/ntv300b/us/gm/NTV300B_V1.0.76.bin still a bit unclear how to create that xml file and redirect the updater to a local server.
Thanks for any guidance.
Mike

Yeah only the NTV300SL has the usb port that would be an easy solution. Will look into your local bind9 server suggestion. If not then I can still return it and get the SL or a WD Live Media Player
Thanks eenofonn

I am currently on 1.1.12 and when i follow your process, it sees the update on my local server, but when i click update, it doesnt do anything, i am not sure how to find out what its doing without cracking it open and hitting the serial connection. Do you know if this process still works?

I lost my remote control and I am using my cellphone app to control it (wired internet) . I want to setup my wifi but without the original remote control it is impossible. The wifi menu activates only if the box is unplugged from the wired network. I guess they didn’t think this would happen right. What a poor design. Do you know any way to manually setup wifi using the android app through wired connection?

Yes, this apparently does just what you’d expect. I used a local DNS server to point that hostname at a local Linux machine, and then created a /ntv300sl/us/gm/web_cmd.sh script on that server. Lo and behold, it ran it on boot.

If you’re attempting to do this, I’ll assume you know how to set up the web server and the DNS configuration.

Rename it to ‘dropbear’ and drop it in the directory with web_cmd.sh. Reboot your NTV, wait a bit, and then you should be able to ssh root@ntv.ip.here with a password of “rooted” (set via the crypt hash in web_cmd.sh).

The init scripts check /mnt/ubi_boot/rc.ntv300 (on this particular device) and execute it if it exists. So, I used this to make the SSH config persistent.

Rob .. i got NTV300SL and updated to 1.0.76 , but the script u’ve mentioned was never requested by mine.
and i tried to listen over serial too to see if it shows up as a debugging , got nothing too ..
this is totally weired :/

to install this image :
1) get usb flash drive
2) make a directory on root of flash called “UPG”
3) copy the file 8653_linux_demo_dbg.bin to UPG ,
you should have something like this :
UPG/8653_linux_demo_dbg.bin
4) plug flash memory into NeoTV
5) power on NeoTV
6) It will ask you to update , accept it.
That’s it 😀

you can telnet to your neotv , and use “rooted” as password for root.
Netgear did an update over passwd file , and i couldn’t decrypt the root’s password yet .. so i thought i would use Rob’s one 😉

I have a quick question for you… I wish to change HDMI Output setting from HDMI Auto to a fixed value which is 720p. Unfortunately Netgear firmware does not have it enabled. Can you please suggest any method of changing it ?
So far I have downloaded custom firmware from Rayman on my NTV300SL.

I ended up playing with my neotv all night long last night in a fit of “hacker’s insomnia” as I’m calling it. I’m not exceptionally skilled with embedded linux or arm but I did come up with what I think is a crazy idea last night.

Is there a way to clone the live system to a file using dd or another tool so that you could use say qemu to emulate the system for more testing/development purposes.

It would also be nice if there was a wiki/forum where everyone interested in working on this project together could collaborate thought’s ideas etc.

Hi guys .can any of you help me i have mistakenly bought 3 neo tv 300 from the usa.My main goal was to view my slingbox on my tv.I was not aware that neo tv 300 max was required for this neither was i told at the ces show at the slingbox booth ,they only told me to get netgear neotv that is it.Now i got 3 neotv which are uselessly lying .can any of you help me to install the slingbox app in it thats all i want it to do,watch my slingbox.
Thanks in advance

Hey Guys, I am really really new to this whole media box stuff. I have been running XBMC on my computer but want to get it onto my tv. My dad picked me up a NeoTV NTV300 so I guess im wondering if I jailbreak it can I run XBMC or can I get it to use this widi thing I have read about in the higher end NTV300 boxes from some hack. Thanks in advance!

really cyberspace under these sort of cool, All of us perish simply too! That is abandoned in this interesting individual web is how really product my oh my!Considering that the seat, I think a huge answerability, simply you shouldn’t post, these

Anyone know how to remap the CUSTOM keys? (such as the ones for Netflix, Hulu, etc). I want to map one of the keys to another program that would be used more often than say VUDU for example. Maybe replace VUDU with Intel WiDi as a shortcut for example. I’ve tried snooping around, but couldn’t find anything. Looks like it uses LIRC for receiving remote control strokes, and there is a lirc_monitor that you can run to see the key sequences being received. But wasn’t able to track down where the actual mapping of the keys occurs. (typical lircd would just be in lircd.conf but looks like they’ve hard coded the key mapping into a binary somewhere).

Craig this is great. You did a great job. I have to ask, because I am new to this, can I add XBMC to the menu screen using this method. If so, how? Do I just add the Linux script from XBMCHUB.com or is there some other way? Thanks

Great info, I had my NTV300(not S or SL version) with no dlna client feature available, I downgrade firmware to 1.0.76NA, and it worked like a charm, now I have dlna support. Mine was already at latest firmware version, so downgrade to that low version is not a problem. But still wondering why dlna feature is not included in latest firmware !

Just curious if you would be able to make up a step by step on how to downgrade this? I would really like to have DLNA support on this device. I am not a novice by any means, but when it comes to things like this, I may need a little step by step.

I just tried this on the Neo NTV300SL with the latest firmware as of the date of this comment (1.1.50NA). Just using backticks did not work to inject system commands.
You have to escape the backticks for it to work on my device.

For example: to reboot my Neo I have to set the SSID to

\`reboot\`

I’ve worked through your script but creating the ‘enable’ file didn’t result in any change on the device. I’ll have a peek at the firmware files. Thanks for getting me started!

Very good idea, and seeing as i have one of these i gave it a shot with minimal success. Here is what i did and how far i got.

Using the quotes with “reboot” did not work, but $(reboot) however did work. I accesed the serial port and spawned the unfriendly shell. But i noticed a few things are missing, specifically the inetd binary. telnetd is present, but without the superserver it wont run. I overwrote the /etc/passwd using the ssid exploit to give root a blank password and typed “login” in the shell. Username: root, and it dropped me into a root shell. i copied utelnetd onto the device and was able to telnet in, but nothing persists across reboots. Seems everything i do in pretty much any directory gets reset on reboots. Any new files get erased, any file changes get reset, and i can’t seem to find any directory that persists. If someone could explain how i could possibly build a custom firmware or any other ideas i would be very grateful.

This still doesn’t work for fooling ntv300ui. It still detects that it’s not a MAX unit. It also doesn’t persist across reboots.

Would someone who has access to a S or SL unit please run the following and post the results here? This will retrieve the state of GPIO (it will not alter it). FYI, reading the high numbered GPIOs caused my unit to reset although it didn’t harm anything.

Also i did find one directorty that persists across reboots for me.
it is /cust_part_1
havent had much time to play with this, but i was able to create files in that directory that persisted across reboots, so i can execute scripts from the essid via the $() exploit, but i still havent found a way to execute something on boot.
have to run
$(cp /cust_part_1/passwd /etc) #copys a passwd file with a blank root password
$(sh) #spawns a non-interactive shell on the serial console
then in minicom i type “login” (i found that if you leave the screen on the one you type the essid in, it was less likely to drop random characters)
put root in as the user, and drops into shell. unfortunately typing login in blanks the screen on the tv so it cant be used once login is typed.
or i can execute a copy of utelnetd i have saved in the cust_part_1 directory and log in remotely through telnet and the regular screen stays up. though plugging it in to an ethernet cord after executing $(sh) tends to make connecting easier.

I picked on up for $25. I was curious if solder a USB port on to it, if I could access USB with out the Larger Model Firmware. Also Has anyone succsessfully merged the 300, 300S, 300SL firemwares to unlock features?

Dear.
I have a NEOTV 300 that was blocked during update.
My idea is to dowload a previous firmware version through the 4 pin serial port. My questions:
1) do you have the pinount of the 4 pin serial port?.
2) which version do you suggest to replace the actual ?
3) how can I dowload the new firmware into the NTV300?
Thank you!

Wondering if any new exploits have come up for the ntv300 running V2.1.86?
The “\`” results in fatal errors, thespoofing exploit seems to have stopped working with the md5 signatures in the fileinfo.XML.
I had some fun hacking the remote app and can trigger the missing channels but the mtkaps are missing and the host list removes the links to the missing swfs.
Wondering if a .tar exploit is an option and/or a curl command to load the missing MyMedia and DNLA apps or edit the host list to add the missing URLs.
Thanks

Hey, Craig.
I looked through the firmware of the Netgear WNR2200 I bought and it looks like it is based on OpenWrt. Interestingly they listed the telnet_enable script for Netgear Routers as one of thier GPL sources O.o.
They really made a nice GPL package (even all sources are downloaded, including a firmware build script!) which has a graphical menu config (they “borrowed” alot of the OpenWrt project tough).

But all in all, they seem to make a good work.
I will try exploiting it tough.