Bugs in your TV
As part of our research into the Internet of Things (IoT), we were asked to look at the current generation of Smart TVs and see whether they posed any new issues when used in the home or office. In particular, the latest sets come with built-in cameras (for use with video chat applications, plus new features, such as gesture recognition), so we decided to see whether these could be exploited in any way.
Look Mum, I’m on the telly!
Or ‘in’ the telly, to be precise. The first step in our investigation was to find out how the smart features were implemented on the sets. The particular brand of TV that we looked at had been previously researched by NCC Group’s iSEC Partners, so I was able to reach out to our trans-global team of Cyber-Security Experts™, and get a brain dump from one of the researchers.
It turned out that, not only did the TVs all run a variant of Linux, but that the manufacturer actually released a large proportion of their source code. The availability of the code, coupled with a fairly active jailbreaking community, meant that I had a few quick wins to begin with. It’s possible to install a suite of applications onto the TV that provide basic networking services, such as telnet and FTP (SSH is also listed as being available but logging in isn’t possible, for reasons I’ll come to later).
Once on the TV, it was time to do a little bit of light host-reviewing. As it’s an embedded device, very little hardening has been performed, and the majority of processes and services were running as root. Due to the hardware constraints of the device, the majority of the file system was mounted read-only, and this explained the difficulty of logging in over SSH: the device provided the “ash” shell (as part of Busybox), but this wasn’t listed as an allowed shell in /etc/shells. Unfortunately, /etc/ was mounted read-only, and the ‘shells’ file didn’t already exist, so it wasn’t possible to mount an alternative file in its place.
The host review continued – a quick look over the list of running processes suggested that a lot of the smart features, such as the app hub, and various apps themselves, were running as WebKit processes. Looking at the available documentation confirmed that this was the case; developers could implement apps as “webpages with benefits”, which allowed them limited access to the TV’s hardware. At first blush, this looked like an easy win: write an app that recorded the camera and then run it in the background. Sadly, while apps could access the camera, they couldn’t record from it (or stream from it, or modify its output). It wasn’t really apparent why anyone would want to access it in in the first place, given such limited capabilities. Some built-in apps were able to record from the camera, however, so we took a look at launching these in the background and seeing whether we could capture their output.
Another look at the process tree showed that all TV functions were spawned by a single giant executable. A 160Mb executable to be exact. And one that crashed IDA after a few hours of attempting to load it (Hopper had the good grace to give up pretty much instantly). Our efforts at trying to get our own processes to run were unsuccessful, so we tried to hijack the currently running ones. An nmap of the device showed that the TV was running an X server but that it was firewalled off. Much grepping of config files followed, to see whether firewall settings could be found and tweaked. When these searches failed to yield any results, a matter-of-fact display of pragmatism was necessary: we just turned the firewall off. Sadly, the X server was denying all attempts to connect to it, and a look at its launch script showed that its config options were hardcoded into its binary. It was possible to launch a new instance of X, without any host restrictions, though this required killing the existing server, which in turn required killing the monster executable, which then removed all smart functionality from the TV. Deciding that this would be something that the user would pick up on, we moved on to look at yet another approach: native binaries.
Here be Dragons
Ever heard the phrase, “cross-compiling is easy”? If anyone says that to you, then do not look into their eyes, for escaping the darkness in them would require Dinah Glass-like levels of willpower.
Cross-compiling is a strange mirror-world, a map of which would appear patched together from descriptions of archipelagos and mythical dangers: the Land of Lost Includes, the Miasma of Symlinks, the Chroot Waterspout, and the Tsunami of Missing Symbols. A strange meta-world, where scripts configure scripts that generate configurations for scripts that make… something. Sometimes.
Fragments of notes from wikis, half-finished thoughts on forums, unanswered Stack Exchange questions – these will be your guides and companions on your travels through this land. As you journey further across the desert, you will suddenly feel a sensation of weightlessness. A calmness, and feeling of transcendence, as enlightenment slowly washes over you, only occasionally punctured by the need to thump things with a wrench until they just bloody work.
Having emerged from the abyss, the possibilities now appear endless. In order to get a demo up and running, we attempted to get a basic screen-grabbing program compiled. The endless possibilities took on a second dimension, as we stared at the seemingly bottomless pit of dependencies. The program required X libraries, which required image libraries, which required format libraries, which required yet more libraries. In the end, however, we were presented with a statically linked binary that would capture the current X screen to disk. Except that it didn’t, for some reason. So we compiled VNC instead.
VNC was surprisingly easy to get working and dutifully popped up the app hub menu system. We watched the user select the camera app and high-fived as the GUI elements were mirrored to our screens. But that was all that was sent. The video feed was apparently avoiding the X server entirely, so we were left looking at a screen as black as the disappointment in our hearts.
Some more hunting on the filesystem discovered that the camera was being mounted as a Video4Linux device. A couple of quick Google searches turned up some sample code, including someone who had written a picture taking app that ran on the Beaglebone Black. This seemed like the solution we should have tried all along, so we set about getting any one of the many apps to run. All seemed fine (barring a slight misunderstanding with glibc and some inline assembly): the apps compiled easily enough and all dependencies were met. Unfortunately, the device refused to be recognised. Regardless of the program used to access the camera, on the first run we would get an error that the device could not be found and on the second run the program would hang.
Cue a few panicked days and a shipping in (well, training in) of one of our Linux kernel contributors. Once again, however, we were defeated, and with only 24 hours left before the big presentation, we decided to see whether we could get the microphone to cooperate where the camera refused to.
The microphone was actually mounted as a USB device, so no special drivers were being used. We were able to compile up a basic audio recording program, and a simple init script that would SCP audio snippets to a remote server. It was a last ditch attempt, held together by the mystic force of the whole team crossing their fingers, but it held up on the big day and survived journalist scrutiny the day after.
We now had a TV that, as soon as it was switched on, would start recording audio from the room and could send it to any computer we chose. Needless to say, this generated a bit of attention, given that not many people pay a second thought to what a TV is up to.
The project once again demonstrated that newer devices are now computers in all but name and can ultimately run similar programs to more traditional computing devices. The security and capabilities of these devices should therefore be taken as seriously as any other computing device, especially given the implicit trust they have gained by being (quite literally in some cases) part of the furniture for so long.
Want to Learn More? Why not read our whitepaper: Security of Things: An Implementers’ Guide to Cyber-Security for Internet of Things Devices and Beyond
Published date:  21 May 2014
Written by:  Felix Ingram