hyperion
hyperion
Bildquelle: honeybee

Roku TV für Ambilight gehackt – Reverse Engineering

Ammar Askar hat seinen Roku TV selbst gehackt, da er keine 250 € für eine Philips Hue Sync Box ausgeben wollte.

Der IT-Sicherheitsforscher Ammar Askar hat seinen Roku TV gerootet. Er wollte keine 250 € für eine Philips Hue Sync Box ausgeben, um die benötigten Farbinformationen an seine vorhandenen Philips Hue Lampen zu übertragen.

DIY Ambilight mit Hyperion

Bereits in der Vergangenheit hatte ich einen Artikel über Hyperion geschrieben. Dabei handelt es sich um eine Software, die es erlaubt, aus einem HDMI-Bildsignal die benötigten Farbinformationen zu gewinnen. Anschließend werden diese genutzt, um LEDs anzusteuern.

Normalerweise muss man das Bildsignal über ein HDMI-Kabel abgreifen. Dazu verwendet man in der Regel einfach einen HDMI-Splitter, der das Bildsignal doppelt und einen HDMI-USB-Grabber, damit das Bildsignal zum Beispiel von einem Raspberry Pi über Hyperion verarbeitet werden kann.

Nutzt man aber mehrere Geräte ohne dazwischengeschalteten AVR, ist das nicht mehr so einfach möglich. Wenn man nur einen Smart-TV ohne externen Zuspieler einsetzt, lässt sich das HDMI-Signal überhaupt nicht mehr abgreifen. Mit Ammars Hack könnte man die Bildsignale direkt im Roku TV abgreifen und somit wären HDMI-Splitter und Grabber auch unnötig. Gleiches gilt für die Philips Hue Sync Box.

Roku TV SDK und BrightScript

Roku TV setzt auf ein Linux basierendes Betriebssystem und stellt für eigene Apps (genannt Channels) ein Software-Development-Kit (SDK) bereit. Die Apps müssen in der von Roku entwickeln Scriptsprache BrightScript geschrieben werden. Ein solches Script wird auf dem TV anschließend über einen C-basierten Interpreter ausgeführt. Alternativ kann auch Coding direkt per Telnet an den Roku TV gesendet und ausgeführt werden.

Hack mit Datei-Lese-Exploit

BrightScript integriert diverse nützliche API Funktionen. Unter anderen eine, um Daten von einer URL zu lesen.

Brightscript Debugger> r = CreateObject(„roUrlTransfer“)
Brightscript Debugger> r.SetUrl(„http://example.com“)
Brightscript Debugger> ? r.GetToString()

Script welches den Inhalt http://example.com zurückliefert

Ammar Askar hatte den Verdacht, dass im Hintergrund libcurl verwendet wird. Dies bestätigte sich, da sich in der BrightScript Dokumentation ein Parameter, namens CURLOPT_SSL_VERIFYPEER, befindet. Libcurl kann nicht nur dazu verwendet werden, um Inhalte von Webseiten abzufragen, sondern auch von FTP, Gopher oder dem (lokalen) Dateisystem.

$ curl file:///etc/passwd
root:x:0:0:root:/root:/bin/bash

Abfrage von Dateiinhalten unter /etc/passwd per curl.

Anschließend hat Askar versucht /etc/passwd vom Dateisystem zu lesen, welches aber zunächst nicht funktionierte, da BrightScript die Eingaben filtert und so auch ein einfacher Path-Traversal-Angriff zunächst scheiterte. Dazu verwendet man bei einem Pfad zwei Punkte ../ um ins übergeordnete Verzeichnis zu wechseln

Brightscript Debugger> r.SetUrl(„file:///etc/passwd“)
*** ERROR: Missing or invalid PHY: ‚/etc/passwd‘

Brightscript Debugger> r.SetUrl(„file://pkg:/manifest“)
Brightscript Debugger> ? r.GetToString()
title=Hello World

Brightscript Debugger> ? r.GetUrl()
file:///tmp/plugin/GPAAAAX4Lckh/pkg:/manifest

Brightscript Debugger> r.SetUrl(„file://pkg:/../../../../etc/passwd“)
Brightscript Debugger> ? r.GetUrl()
file:///tmp/plugin/GPAAAAX4Lckh/pkg:/etc/passwd

Erste Versuche, Dateien vom Dateisystem zu Roku TV lesen

Indem er aber die Punkte URL-encodierte, konnte er diese Hürde nehmen und so den Filter überlisten. Das bedeutet, er kann so beliebige Dateien auf dem Gerät lesen. Mithilfe dieser Idee konnte er anschließend das komplette Dateisystem herunterladen, um weitere Informationen über seinen Roku TV zu sammeln.

Brightscript Debugger> r.SetUrl(„file://pkg:/%2E%2E/%2E%2E/%2E%2E/%2E%2E/etc/passwd“)
file:///tmp/plugin/GPAAAAX4Lckh/pkg:/%2E%2E/%2E%2E/%2E%2E/%2E%2E/etc/passwd
Brightscript Debugger> ? r.GetToString()
root:x:0:0:root:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:100:sync:/bin:/bin/sync
mail:x:8:8:mail:/var/spool/mail:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
operator:x:37:37:Operator:/var:/bin/sh
sshd:x:103:99:Operator:/var:/bin/sh
nobody:x:99:99:nobody:/home:/bin/sh
messagebus:x:102:102::/var/lib/dbus:/bin/false
default:x:500:500:Default non-root user:/home/default:/bin/sh
app:x:501:501:roku app:/home/default:/bin/sh

Proof of Concept zum Lesen beliebiger Dateien (hier /etc/passwd)

Hauptapp vom Roku TV hat versteckte NFS-Funktion

Beim Reverse Engineering der Hauptapplikation des Roku TV hat Ammar Askar eine verstecke NFS-Funktion entdeckt. Diese erlaubt es dem Roku TV, einen Channel direkt vom Dateisystem eines Servers abzurufen. Dies diente sicher dazu, die Entwicklung von Roku-Channels zu vereinfachen, damit der Entwickler nicht nach jeder Änderung seine BrightScripts manuell auf den TV schieben muss, sondern der TV diese direkt von Rechner des Entwicklers beziehen kann.

Knackpunkt dabei ist, dass NFS alle Funktionen, wie beispielsweise Symlinks unterstützt. Das bedeutet, dass sich so zum Beispiel das Root Verzeichnis des Betriebssystems des Roku TV einbinden lässt. Dies war für die weiteren Schritte von Ammar notwendig, da BrightScript es nur erlaubt, dass ein Channel innerhalb seines Paketverzeichnisses auf das Dateisystem schreiben darf. Diese Schutzfunktion lässt sich mit NFS und Symlinks umgehen.

ammar@nfs-server:/media/nfs$ ls -la .
drwxr-xr-x 5 root root 4096 Apr 23 12:13 .
drwxr-xr-x 3 root root 4096 Mar 24 06:53 ..
-rw-r–r– 1 root root 876 Apr 23 12:13 manifest
lrwxrwxrwx 1 root root 1 Mar 24 06:56 root -> /

NFS mit Symlinks auf dem Roku TV

Code Execution auf dem Roku TV

Nun lassen sich auf dem Roku TV Dateien lesen und schreiben (arbitrary read-write). Leider lässt sich die Hauptapplikation nicht einfach so ersetzen, da das Dateisystem nur lesend eingebunden ist. Einzig und alleine die Ordner /tmp und /nvram sind beschreibbar. Das /nvram Verzeichnis scheint zunächst interessant, weil dort Scripte abgelegt werden. Bedauerlicherweise werden diese Scripte nur im Entwicklermodus ausgeführt, der über die Kernelparameter des Bootloaders aktiviert werden müsste.

Später entdeckte Ammar aber noch ein Script namens S64wifi, welches die WLAN-Verbindung initialisiert und die Konfiguration von /nvram/udhcpd-p2p.conf liest. Das

UDHCPD_CONF=/lib/wlan/realtek/udhcpd-p2p.conf
[ -f /nvram/udhcpd-p2p.conf ] && UDHCPD_CONF=/nvram/udhcpd-p2p.conf
cp $UDHCPD_CONF /tmp/udhcpd-p2p.conf
echo „interface $P2PINTF“ >> /tmp/udhcpd-p2p.conf
udhcpd /tmp/udhcpd-p2p.conf

S64wifi Script

Udhcpd dient normalerweise als DHCP-Server für Wi-Fi Direct Verbindungen. In dessen Dokumentation findet sich eine nützliche Funktion. Diese erlaubt es immer dann ein Script auszuführen, wenn der DHCP Lease erneuert wird. In Kombination mit dem Parameter auto_time lässt sich so nun ein beliebiges Script beim Start des Roku TV ausführen. Ammar Askar platzierte dort ein Script, welches einen Telnetserver startet

#!/bin/sh

busybox telnetd -l /sbin/loginsh -p 1337

Script zum Starten eines Telnetservers

Beim ersten Test des Telnetservers stellete sich heraus, dass dieser mit Adminrechten läuft – Bingo!

$ telnet 192.168.1.69 1337
Trying 192.168.1.69…
Connected to 192.168.1.69.
Escape character is ‚^]‘.

WIFI DRIVER PATH: /lib/wlan/realtek
longview:/ # whoami
root

Telnet mit whoami

Entwicklung eines Screen Capture Tools für den Roku TV

Nach einigem Reverse Engineering fand Ammar heraus, dass die Bildverarbeitung beim Roku TV über die Bibliothek DirectFB läuft. Da DirectFB unter der LGPL steht, musste Roku den Quellcode dazu zur Verfügung stellen. Bei der Bibliothek handelt es sich um einen Fork von MStar. Diesem Fork sind auch nützliche Beispiele bei, die es ihm direkt erlaubte diese ohne großen Aufwand zu kompilieren.

Anschließend baute er sich daraus ein Tool, um die benötigten Farbdaten an den Bildrändern an seinen Laptop zu übertragen und diese Information dann an seine Hue-Lampen weiterzugeben.

Dabei konnte er das Bild nicht einfach an seinen Laptop übertragen, da der ganze Prozess so maximal nur 1–2 Bilder pro Sekunde verarbeiten konnte. Auch die Rohbilddaten in JPGs umzuwandeln brachte keine Besserung. Eine 4K Auflösung ist in diesem Fall viel zu hoch und wird für die spätere Verarbeitung auch überhaupt nicht benötigt. Ammars Lösung war anschließend nur die Bildinformationen an den Rändern seines Roku TV zu übertragen.

Er hat angekündigt, sein Coding auch nach einem Clean-Up für alle zur Verfügung zu stellen. Dieser ist mittlerweile auch, zumindest für den Root-Teil, auf GitHub zu finden.

Root mit neuer Firmware wieder blockiert

Die genannte Exploitkette funktioniert auf den meisten Roku TVs mit Realtek WiFi bis RokuOS 9.4.0 build 4200. Mit RokuOS v10 wurde NFS deaktiviert. Damit funktioniert der oben genannte Root nicht mehr.

Fazit: Wirkt ziemlich einfach, ist es aber nicht!

Beim Schreiben des Artikels konnte ich ein Stück meiner selbst wiederfinden. Es existiert ein technisches Problem, welches es zu lösen gilt. „Nur“ ein geschlossenes System steht einem im Wege, welches gehackt werden muss. Falls sich die Gelegenheit ergeben würde, wäre ein Gespräch mit Ammar Askar für mich sicher eine Konversation mit einem IT-Seelenverwandten.

Ich selbst habe so etwas Ähnliches schon mit einer China-Cam gemacht, um das Bild als JPG direkt davon abrufen zu können, anstatt die integrierte Cloud dafür nutzen zu müssen. Dazu war es nötig, die Kamera per UART zu rooten und auf dem Dateisystem Scripte abzulegen, die beim Start der Kamera gestartet werden. Um das JPG bereitzustellen, musste ich das passende SDK finden und in C ein kleines Programm schreiben.

Die Arbeit hinter einem solchen Projekt ist nicht zu unterschätzen. Auch ist es für Außenstehende nur schwer greifbar, wie viel Zeit ein solches Vorhaben benötigt. Vorher biegt man aber häufig falsch ab und landet in einer Sackgasse, wenn etwas nicht funktioniert. Kennt man den Weg anschließend, wirkt es einfach. Sicher hat hier Ammar viele Tage Arbeit in sein Roku TV Hacking Projekt gesteckt. Alleine sein Blogpost voller nützlicher Informationen hat sicher viele Stunden gekostet.

Habt ihr selber schon so etwas gemacht? Ich würde mich über Eure Kommentare freuen!

(*) Alle mit einem Stern gekennzeichneten Links sind Affiliate-Links. Wenn Du über diese Links Produkte oder Abonnements kaufst, erhält Tarnkappe.info eine kleine Provision. Dir entstehen keine zusätzlichen Kosten. Wenn Du die Redaktion anderweitig finanziell unterstützen möchtest, schau doch mal auf unserer Spendenseite oder in unserem Online-Shop vorbei.

Über

honeybee schreibt seit Ende 2020 für die Tarnkappe. Der Einstieg war ein Reverse Engineering Artikel über die Toniebox. Die Biene liebt es, Technik aller Art in ihre Bestandteile zu zerlegen. Schraubendreher und Lötkolben liegen immer in Reichweite. Themen wie Softwareentwicklung, Reverse Engineering, IT-Security und Hacking sind heiß geliebt.