In diesem Blogartikel werden wir auf die Details einer mittlerweile als CVE-2024-33898 bekannten Schwachstelle eingehen, die wir im April 2024 identifiziert haben. Es handelt sich dabei um eine unauthenticated Remote Code Execution im Frontend des Axiros Auto Configuration Servers (ACS) in den Versionen 4.3.2 und 5.0.0. Die Schwachstelle wurde mittlerweile in Zusammenarbeit mit Axiros behoben, weitere Details dazu finden sich hierzu auf der Website des Herstellers.
Bevor wir uns mit den technischen Details der Schwachstelle beschäftigen, beginnen wir mit einer Beschreibung des Produkts selbst.
Der Auto Configuration Server
Axiros beschreibt das Produkt dabei als weltweit eingesetzte „herstellerunabhängige Geräteprovisionierungssoftware“ für Customer Premise Equipment (CPE) CPEs sind Modems, Router oder ähnliche Geräte, die ein Internetprovider an seine Kunden sendet. Konkret wird der ACS also beispielsweise von Internetprovidern eingesetzt, um die CPEs ihrer Kunden zu konfigurieren und zu verwalten. Die Kommunikation zwischen ACS und den Routern erfolgt dann beispielsweise per TR-069, einem Protokoll des Broadband-Forums von 2004. Die Interaktion kann dabei vereinfacht so dargestellt werden (Quelle):
Prinzipiell werden die CPE Geräte also von einem Auto Configuration Server per TR-069 gewartet. Zu den Fernwartungsmöglichkeiten des ACS zählt dabei aber nicht nur das Diagnostizieren von Internetproblemen einzelner Router, sondern auch das automatische Einspielen von Firmwareupdates. Dies erfolgt dabei parallel auf mehreren zehn- bis hunderttausenden Routern. Es ist daher offensichtlich, dass der ACS aus Sicherheitsperspektive ein besonders schützenswertes Ziel darstellt: wird des ACS kompromittiert, könnten beispielsweise durch ein bösartiges Firmwareupdate sämtliche verbundenen Router kompromittiert werden.
Würde ein Angreifer Zugriff auf den Router erhalten, vervielfacht sich die mögliche Angriffsoberfläche: sämtlich Geräte des lokalen Netzes, beispielsweise Handys, Drucker, Computer, vielleicht sogar die Überwachungskamera oder ein Network-attached Storage (NAS), werden sichtbar und können angegriffen werden. Darüber hinaus befindet sich der Router natürlicherweise in einer Man-in-the-Middle Position, was eine Vielzahl weiterer Angriffsmöglichkeiten eröffnet. Er könnte beispielsweise ungesicherten Netzwerkverkehr mitlesen, so Passwörter einsehen oder Phishing-Websites einspielen. Neben der Ausnutzung der besonderen Funktion des Routers könnte man auch einfach nur Kryptowährungen schürfen, flächendeckend das Internet „ausschalten“ oder andere Systeme per DDoS angreifen, wie dies in der Vergangenheit bereits durch Botnets erfolgte.
Ansicht eines Users
Um ein Gefühl für Einsatzweise und Mächtigkeit von AXESS 5, dem Frontend des Auto Configuration Server zu bekommen, sollen vorerst ein paar ausgewählte Features vorgestellt werden. Die erste Abbildung zeigt die Benutzeroberfläche eines angemeldeten Admin-Nutzers.
Dies entspricht in etwa der Ansicht eines Level 2 oder Level 3 Support Mitarbeiters, den primären Nutzern dieses Systems. Oben links sieht man, dass ca. 72.000 Geräte registriert worden sind, also eine nicht unerheblich Menge. Unten links sieht man jedoch, dass es nur einige wenige Geräte gibt, die online sind. Da es sich um ein Screenshot eines Testsystems handelt, ist das nicht weiter ungewöhnlich.
Nun gibt es für den Supportmitarbeiter auch die Möglichkeit, einzelne Gerät auszuwählen, in diesem Beispiel eine FRITZ!Box 6660 Cable:
Man sieht bereits einige Geräteinformationen, wie die IP-Adressen oder den Softwarestand. Unter Quick Actions findet sich die Möglichkeit den Router zurückzusetzen oder neuzustarten. Ähnlich findet sich in der Anwendung auch die Möglichkeit durch Firmware-Jobs direkt auf großen Mengen an Routern auf einmal zu operieren, um so beispielsweise für alle Router auf einmal ein Firmware-Upgrade einzuspielen:
CVE-2024-33898
Nach dieser kleinen Einführung zu Routern, einem ACS und groben Funktionsumfangs von AXESS 5, soll in diesem Abschnitt nun auf die mit einem CVSS Wert von 9.8 bewertete Schwachstelle CVE-2024-33898 eingegangen werden. Dafür beginnen wir kurz mit der Suche nach der Schwachstelle, gefolgt von einer Beschreibung der Schwachstelle selbst, bevor wir dann auf eine Möglichkeit der Codeausführung eingehen werden.
Suche nach der Schwachstelle
In diesem Abschnitt sollen lediglich die letztendlich zielführenden Punkte eingegangen werden, die zur Identifikation der Schwachstelle geführt haben.
Erweiterbare API
Ein Feature in der AXESS 5, das nur für Administratoren zugänglich ist, ist die „erweiterbare“ API. Hier ist es mittels eines web-basierten Dateimanagers möglich, die mit Flask gebaute API durch eigene Python-Dateien zu erweitern und anzupassen. Der Dateimanager zeigt dabei standardmäßig folgende Inhalte:
Die Ordnerstruktur kann dabei direkt auf API-Pfade abgebildet werden, beispielsweise würde ein autorisierter Administrator über {Host}/live/check
die im Screenshot ganz unten abgebildete Datei check.py
ausführen können. Außerdem können über den grünen Add New
-Button auch neue Python-Dateien hinzugefügt werden, die sich dann ebenfalls über die entsprechende URL als neuer API-Endpunkt ansprechen lassen.
Offensichtlich wirkte die erweiterbare API für einen Pentester äußerst interessant, da ohne große Umwege direkt eigener Python Code ausgeführt werden konnte. Außerdem stellte sich heraus, dass der ausgeführte Code nicht in einer Sandbox, sondern direkt auf Betriebssystemebene ausgeführt wurde. Der nächste Schritt war es also die API um eine Webshell zu erweitern und so den Server selbst und auch den Quellcode näher zu inspizieren
Da die Anwendung selbst aber sehr umfangreich ist, sie beinhaltet ca. 3000
verschiedene Python Dateien, konnte der Code nicht vollständig analysiert werden. Stattdessen wurde er bei interessante Beobachtungen im Verhalten des Servers stichprobenartig untersucht.
So auch bei einer SQL-Injection in ebendieser erweiterbaren API unter /live/
, für welche wir den gesamten Ausführungsfluss nachvollziehen wollten. Dabei wurde auch der Authentifizierungs- und Autorisierungsmechanismus untersucht. Der vorgesehene Ablauf für einen authentifizierten und autorisierten Zugriff auf einen API-Endpunkt lässt sich dabei in etwa so beschreiben: der Nutzer meldet sich zuerst mit einem der unterstützten Anmeldeverfahren an. Im einfachsten Fall ist das die Angabe von Nutzername und Passwort. Bei erfolgreicher Authentifizierung werden dem Nutzer dann je nach Zugehörigkeit die eingerichteten Rollen zugewiesen, beispielsweise die eines Level-2-Supportmitarbeiters. Je nach Rolle ergibt sich eine vordefinierte Menge an Zugriffsberechtigungen, die letztendlich vorgeben, ob der Nutzer den angeforderten API-Endpunkt ansprechen darf oder nicht. Bei Analyse dieses Autorisierungsvorganges im „AXUserManager“ hat ein interessantes Code-Fragment in einer Wrapperfunktion unser Interesse geweckt:
Wahrscheinlich mit dem Hintergedanken, dass sich Nutzer unabhängig von ihrer Rollenzugehörigkeit abmelden können sollten, werden alle API-Anfragen an URLs mit Suffix logout.html
als grundsätzlich autorisiert betrachtet. Alle anderen Anfragen müssen aber einer genaueren Untersuchung durch das Access Control Management geprüft werden, was hier in der letzten Zeile als self.AXAccessControl.authorize(...)
geschieht.
Dieses Verhalten ist jedoch verwundbar, da sich der Suffix logout.html
als GET Parameter an beliebige URLs anhängen lässt und diese Funktion somit immer True
zurückgibt: die Autorisierung ist erfolgreich!
Mit Hilfe des Suffixes ?logout.html
müssten API Endpunkte also völlig unabhängig von den zugeordneten Rollen und Berechtigungen aufrufbar sein, wenn vorher keine Filterung URL durch die Anwendung selbst vorgenommen wird. Die einzige andere Voraussetzung hierfür ist, dass der Nutzer bereits angemeldet ist. Es muss ein SimpleUser
-Objekt existierten (siehe Kommentar der Funktion). Da es weiter keine Möglichkeit einer Selbstregistrierung gibt, könnte die Schwachstelle also nur von vorhandenen Accounts ausgenutzt werden. Das mindert aber bereits das Gefährdungspotenzial, da so nur angestellte Support Mitarbeiter und Admins Zugriff erhalten.
Im weiteren Verlauf der Analyse wurde fiel jedoch auf, dass Anfragen ohne angemeldeten Nutzer, den sogenannten nobody
-Nutzer zugeordnet bekommen (Zeile 215). Dies, bevor die verwundbare Funktion authorize
aufgerufen wird.
Diesem Nutzer ist lediglich die Rolle Anonymous
zugeordnet, die selbst über keinerlei Zugriffsberechtigungen verfügt. Trotzdem gilt die Authentifizierung als gültig. Wird die Anfrage URL von der Anwendung also nicht weiter gefiltert, können selbst nicht angemeldete Angreifer beliebige Anfragen autorisieren lassen.
Verifizierung der Schwachstelle
Als nächster Schritt sollte diese im Quellcode identifizierte Schwachstelle in der Praxis nachgewiesen werden. Besonders geeignet ist hierfür der API-Endpunkt /live/AXCustomerSupportPortal/acl_users/authorise
der erweiterbaren API, da er Informationen über den aktuell angemeldeten Nutzer ausgibt. In diesem ersten Beispiel für die vorgesehene Verwendung verfügen wir über eine gültige Nutzersitzung, die sich per Cookie ausweist. Der Endpunkt kann dann einfach per HTTP-POST-Anfrage angesprochen werden:
Auf diese Anfrage erhalten wir ausführliche Informationen zu unserer Session:
Die Anwendung identifiziert uns per Session-Cookie demnach als authentifizierter Nutzer nside
, dem die Rollen Authenticated
und Manager
zugewiesen sind. Letztere entspricht hierbei einer Administrator-Rolle, welche benötigt wird, um auf diesen Endpunkt zugreifen zu können. Daher ist der Wert von "Allowed"
wahr.
Lässt man nun den Session-Cookie weg und ändert die Anfrage zu
wird die Anfrage als unautorisiert eingestuft und leitet wie vorgesehen zum Login weiter:
Um nun die Ausnutzbarkeit der Schwachstelle zu überprüfen, muss man der Anfrage nur noch den GET-Parameter logout.html
anhängen:
Jetzt antwortet die Anwendung mit:
Es ist also möglich den Endpunkt ohne vorherigen Login anzusprechen! Eigentlich müsste die Session für mit "Allowed": false
bewertet werden, da die Rolle "Anonymous"
nicht autorisiert ist diesen API-Endpunkt aufzurufen. Aufgrund der Schwachstelle wird die Anfrage aber direkt als "Allowed": true
bewertet.
Exploit Chain
Der nächste Schritt ist nun diesen Authentication-Bypass zu einer Remote-Code-Execution-Primitive auszubauen. Dafür bietet sich der Weg über das Hochladen einer Python-Datei an. Theoretisch müsste das trivial über den zum Add New
-Button gehörigen API-Endpunkt möglich sein. Leider war gerade dieser von der Schwachstelle nicht betroffen, da der hierfür verwendete Endpunkt nicht in der erweiterbaren API angesiedelt ist. Allerdings konnte in der erweiterbaren API selbst eine andere Möglichkeit für einen erfolgreichen Dateiupload identifiziert werden. Er findet sich unter /live/CPEManager/Scenarios/csvlog
. Dieser Endpunkt ist für das Schreiben von Log-Zeilen in eine CSV-Datei gedacht. Allerdings lassen sich über die Parameter filename
beliebige Dateien angeben, die wenn nötig, auch erstellt werden. Über den Parameter string
lässt sich die gewünschte CSV-Log-Zeile angeben. Auf diese Weise wollen wir jetzt folgende Python Web Shell erstellen:
Wird diese Datei dann im Browser geöffnet, wird sie von Flask als legitimer Endpunkt interpretiert und ausgeführt. Im Detail wird hier der HTTP-Parameter cmd
über das subprocess
-Modul vom Betriebssystem ausgeführt und die resultierende Ausgabe zurückgegeben. Diese Datei wurde anschließend URL-kodiert und an den csvlog
-Endpunkt geschickt. Die Anfrage um diese Python-Datei unter live/NSIDE/shell.py
abzulegen, war:
Diese Shell kann dann mit beliebigen Befehlen ausgeführt werden, hier ein Beispiel um den Linux Befehl id
auszuführen:
Völlig unauthentifizierte Nutzer können also Python-Dateien hochladen und ausführen, und somit beliebige Befehle auf dem System auszuführen, die sogar mit root-Rechten ausgeführt werden. Dieser Angriff führt also unmittelbar zur vollständigen Kompromittierung des unterliegenden Betriebssystems! In einem zweiten Schritt könnte nun also das zuvor beschriebene theoretische Szenario von massenhaftem Ausrollen bösartiger Firmware durchgeführt werden. Das wiederum wäre dann ein erster Schritt für sämtliche in der Einleitung beschriebenen weiterführenden Angriffsszenarien.
Was können Anwender jetzt tun?
Besteht Grund zur Sorge? Nein. Ungeachtet der Tatsache, dass man als Endanwender und Routerbetreiber nur wenig tun kann (außer TR-069 abzuschalten), wurde die beschriebene Schwachstelle in enger Absprache mit dem Hersteller Axiros bereits im April in den Versionen 4.3.2 und 5.0.3 behoben. Insbesondere sollte AXESS 5 nur in besonders abgesicherten Netzen ansprechbar sein, also nicht aus dem Internet.
Als präventive Maßnahme empfiehlt sich im Allgemeinen für den Einsatz sicherheitsrelevanter Systeme natürlich auch die Durchführung eines Penetrationstests.
NSIDE kann Sie bei der Evaluierung der Sicherheit von Software mit folgenden Dienstleistungen unterstützen:
- Penetrationstests von Webanwendungen und CPE Geräten (bspw. Routern)
- Sicherheitsanalyse von Gesamtsystemen und Netzwerken
- Angriffssimulationen auf Unternehmensnetzwerke