
Proof-of-Concept-Exploit für CVE-2020-12124, das den Wavlink-AC1200-Router angreift und eine nicht authentifizierte Befehlsinjektion sowie einen Stack-Pufferüberlauf in CGI-Schnittstellen demonstriert.
ursprünglich auf https://www.klogixsecurity.com/scorpion-labs-blog/anatomy-of-an-iot-exploit-from-hands-on-to-rce
von David E. Baker, veröffentlicht am 1. Juni 2023
Dieser Aufsatz befasst sich mit der Firmware des Wavlink Wireless-AC1200 Gigabit Routers ab Juni 2020. Die hier diskutierten Schwachstellen wurden möglicherweise vom Hersteller gepatcht oder auch nicht, aber dies ist ein Fall von Schwachstellenforschung, bei dem die Reise selbst die Belohnung darstellt, nicht das Ergebnis. Der Autor führte diese Forschung vor der öffentlichen Offenlegung der Schwachstellen durch, jedoch nachdem sie von anderen Forschern unabhängig entdeckt und dem Hersteller gemeldet worden waren.
Der Hersteller stellt die Firmware für seine Produkte im Support-Bereich seiner Website zur Verfügung; dies ist eine gängige Methode, um IoT-Firmware zu erhalten und eine hilfreiche Alternative zum Extrahieren aus dem Gerätespeicher. Die Firmware ist unverschlüsselt, sodass sie leicht mit binwalk extrahiert werden kann. Die dynamische Analyse wurde mit Zugriff auf ein physisches Exemplar des Geräts durchgeführt, die statische Analyse mit Ghidra.
Die Weboberfläche des Wavlink Wireless-AC1200 Gigabit Routers verfügt über mehrere anfällige Endpunkte, die das uneingeschränkte Kopieren von benutzerbereitgestellten Daten auf den Anwendungsstack oder sogar direkt in die Befehlszeile ermöglichen, um beliebige Befehle auszuführen.
Erste Scans des Geräts deuten darauf hin, dass die einzige exponierte Ressource die administrative Webkonsole war, die authentifizierten Benutzern auf der LAN-Schnittstelle über HTTP auf TCP-Port 80 zugänglich ist. Das Gerät kann weitere Dienste anbieten, diese sind jedoch standardmäßig nicht aktiviert. Daher konzentriert sich diese Untersuchung ausschließlich auf die Weboberfläche.
Ein nmap-Scan des Exemplargeräts zeigt nur die lauschende Weboberfläche.
Die üblichen Tests – wie die typischen Befehlsinjektionen auf Diagnosetafeln von Geräten, die eine Befehlseinschleusung in den Parametern eines Ping- oder traceroute-Befehls erlauben – brachten keine sofort interessanten Ergebnisse, was enttäuschend war.
Verwaltungsoptionen nach Authentifizierung im administrativen Webpanel. „USB-Speicher“ ist als zweite Option zu sehen.
Die erste (letztendlich ausnutzbare) Schnittstelle, die hier untersucht wurde, befand sich im Panel „USB-Speicher“, das im obigen Screenshot als zweite Option zu sehen ist. Das Gerät verfügt über einen USB-Anschluss neben seinen 802.2-Ethernet-Steckern, was darauf hindeutet, dass es NAS-Funktionalität (Network-Attached Storage) bieten könnte.
Ein Foto der Rückseite des tatsächlichen Exemplars, das die USB-Verfügbarkeit zeigt.
Ein einfaches Prinzip in der Schwachstellenforschung ist: Je mehr Komponenten ein Codeabschnitt umfasst und je mehr bewegliche Teile er hat, desto wahrscheinlicher ist es, dass ausnutzbarer Code in der Nähe lauert. Das Vorhandensein von NAS-Fähigkeiten ist vielversprechend, da es auf Code hinweist, der gleichzeitig mit der Softwareebene, der Hardwareebene und der angeschlossenen Peripherie (dem USB-Speicher selbst) interagiert.
Die Verwaltungsoberfläche für die USB-Speicherkonsole ist unten dargestellt. Allein das Vorhandensein des Feldes „Arbeitsgruppe“ ist vielversprechend, da dies darauf hindeutet, dass dieser WLAN-Router möglicherweise sogar über SMB (Server Message Block) zu interagieren versucht – eine große Herausforderung für einen IoT-Router. Ich kann nicht zählen, wie oft ich gesehen habe, dass benutzereingegebene Daten direkt als Argument an die Unix-Funktion smbpasswd an die Befehlszeile übergeben wurden.
USB-Speicheroptionen, die authentifizierten Benutzern zur Verfügung stehen.
Erste Versuche, diese Einstellungen zu manipulieren, schlugen fehl, da das Gerät kein USB-Laufwerk erkannte, wie unten zu sehen.
Konfigurationsänderungen an USB-Speicheroptionen werden nicht gespeichert, es sei denn, ein entsprechend formatiertes Laufwerk wird manuell in den USB-Anschluss des Geräts eingesteckt.
Sobald jedoch ein korrekt formatiertes Laufwerk eingesteckt war, erlaubte das Gerät die Festlegung eines FTP-Benutzernamens und -Passworts. Wie vermutet, übergab es diese benutzereingegebenen Daten an die Befehlszeile:
Eine Befehlsinjektion im Feld „Passwort“ ermöglicht den ersten Shell-Zugriff direkt auf das Betriebssystem des Geräts.
Obwohl interessant, ist es schwierig, sich über diese Schwachstelle übermäßig zu freuen: Sie erfordert nicht nur authentifizierten Zugriff auf die administrative Schnittstelle des Geräts, sondern auch physischen Zugriff auf das Gerät, um dessen USB-Laufwerk zu manipulieren. Der obige Exploit ermöglicht es einem Forscher, mit den einzelnen Betriebssystemkomponenten zu interagieren (und sie für Reverse-Engineering-Zwecke zu extrahieren).
Das Gerät war ein BusyBox-zentriertes Linux-System mit einer Weboberfläche, die von Lighttpd betrieben wurde. Die CGI-Funktionalität (Common Gateway Interface) wurde durch einzelne Binärdateien in /etc_ro/lighttpd/www/cgi-bin/ bereitgestellt, wobei Webanfragen an CGI-URIs diese Binärdateien direkt starteten. Ein kurzer Blick auf nas.cgi in Ghidra zeigt die Befehlsinjektion in Zeile 38 unten, die ein benutzereingegebenes Passwort direkt an die Funktion do_system übergibt (die selbst nur ein Wrapper um den Standard-Libc-Systemaufruf ist).
Benutzereingabe wird in Zeile 38 als Argument an das Skript chpasswd.sh in die Befehlszeile eingefügt, was zu einer Befehlsinjektion und Shell-Zugriff direkt auf das Betriebssystem des Geräts führt.
Ein Durchsuchen des /cgi-bin/-Verzeichnisses reduziert die Aufgabe, einen interessanteren Exploit zu finden, auf die Auflistung der CGI-Schnittstellen, die dem Benutzer zur Verfügung stehen, wie unten gezeigt:
Eine erschöpfende Liste der auf dem Gerät verfügbaren CGI-Binärdateien, direkt aus der Shell entnommen, die durch den in diesem Abschnitt beschriebenen Exploit eingerichtet wurde. Benutzereingabe wird in Zeile 38 als Argument an das Skript chpasswd.sh in die Befehlszeile eingefügt, was zu einer Befehlsinjektion und Shell-Zugriff direkt auf das Betriebssystem des Geräts führt.