
MikroTik Remote Jailbreak für v6.x.x
| / __ _ |/ | | | | | | | | | || | | ( | | ___ | | | || | | || | _ | / _ / _` | | | | || || | ) | || __/ (| | || _/|/ __|_,|
FOISted ist ein Exploit für zwei Schwachstellen nach der Authentifizierung in MikroTiks RouterOS. Er kann verwendet werden, um RouterOS-Versionen von 6.34 (2016) bis 6.49.6 (aktuellste v6-Version) remote zu jailbreaken.
Dieses Repository enthält ein Exploit-Skript für Geräte mit x86-Architektur. Die Schwachstelle existiert auch auf anderen Geräteversionen; das Schreiben der Ropchain bleibt als Übung für den Leser übrig :)
Weitere Informationen findest du in unserem Blogbeitrag über RouterOS-Interna: https://margin.re/blog/pulling-mikrotik-into-the-limelight.aspx
Automatisch:
$ python3 exploit.py -H <router_ip> -u <username> -p <password>
Danach:
$ nc <router_ip> 1337
Das Exploit-Skript ermittelt die RouterOS-Version und setzt automatisch die richtige Ropchain ein. Hinweis: Derzeit wird nur x86-RouterOS unterstützt.
Falls deine Version aus irgendeinem Grund nicht erkannt wird, kannst du sie explizit angeben mit:
-v <version> # z. B. 6.49.6
Wenn du dies auf neueren RouterOS-Versionen als 6.49.6 (zum Zeitpunkt der öffentlichen Veröffentlichung neueste) ausführst, ist deine RouterOS-Version möglicherweise nicht in der Gadget-Datenbank (./db). Du kannst stattdessen den Pfad zu /nova/bin/www übergeben, und das Exploit-Skript versucht automatisch, die richtigen Gadgets für die Ropchain zu finden:
-f /path/to/nova/bin/www
FOISted nutzt zwei Schwachstellen in RouterOS v6 aus, um Remote-Codeausführung zu ermöglichen. In diesem Abschnitt gehen wir auf einige Hintergrundkenntnisse über RouterOS-IPC ein und besprechen die beiden Schwachstellen.
Hinweis: Dieser Abschnitt ist größtenteils eine gekürzte Fassung unseres vollständigen Blogbeitrags. Schau dort unbedingt für weitere Details vorbei!
Innerhalb von MikroTiks RouterOS kommunizieren Programme über ein eigenes IPC-Protokoll miteinander.
Die eigentlichen Datenpakete sind Nova Messages (intern nv::message). Diese existieren in einem Pseudo-JSON-Format (vor 6.38) und einem serialisierten Binärformat:

Jeder Prozess hat eine feste Adresse im RouterOS-System; zum Beispiel befindet sich /nova/bin/user an Adresse 13 und /nova/bin/www an Adresse 70. Zusätzlich kann jedes Programm Handler registrieren, die bestimmte Funktionen in einem Unternamespace implementieren. Beispielsweise hat /nova/bin/user einen Handler an Adresse 4, der als "Login"-Endpunkt fungiert und die Authentifizierung für andere Dienste durchführt:

IPC-Kommunikation ist ein entscheidender Bestandteil des RouterOS-Betriebs. Sie wird verwendet, um:
Während unserer Reverse-Engineering-Arbeiten haben wir ein internes Message-Tracer-Tool geschrieben, mit dem wir alle Nachrichten visualisieren können, die während des Betriebs des Routers ausgetauscht werden.
In der folgenden Demo kannst du alle Nachrichten sehen, die ausgetauscht werden, während wir durch die Weboberfläche blättern: https://youtu.be/Em1hVWnbzQ4
Die RouterOS-Weboberfläche wird durch die Binärdatei /nova/bin/www implementiert. Bestimmte Seiten können jedoch von separaten "Servlet"-Bibliotheken verarbeitet werden, die Funktionen in separaten gemeinsam genutzten Bibliotheken implementieren.
Zum Beispiel verarbeitet das Servlet jsproxy.p Anfragen an /jsproxy und das Servlet winbox.p Anfragen an /winbox, usw....
Diese Servlets sind Bibliotheken, die beim ersten Mal, wenn sie benötigt werden, in /nova/bin/www geladen werden. Zum Beispiel wird beim ersten Laden von /jsproxy die Bibliothek jsproxy.p in den Speicherbereich geladen.
Während dieses Bibliotheksladevorgangs bemerkten wir interessanten Datenverkehr im Message-Tracer:

Konkret fanden wir eine Nachricht, die von der www-Binärdatei an Handler #2 von www gesendet wurde. Das ist bereits verdächtig, da RouterOS-IPC für die Inter-Prozess-Kommunikation gedacht ist, nicht für die Kommunikation innerhalb desselben Prozesses...
Zusätzlich bemerkten wir, dass zwei der Argumente scheinbar virtuelle Zeiger (32-Bit-x86) waren, was unser Interesse weckte, da es sehr ungewöhnlich war.
Bei der Untersuchung der tatsächlichen Funktionen in Handler #2 von /nova/bin/www finden wir eine Funktion namens FoisHandler::cmdUnknown, die ausgeführt wird, wenn diese Arten von Nachrichten empfangen werden.
Erstaunlicherweise zieht diese Funktion den Parameter 0x11 aus der Nachricht und ruft ihn als Funktion auf, wobei zwei der anderen Parameter als Argumente verwendet werden!
Es ist also klar: Wenn wir eine kontrollierte Nachricht senden können, die diesen Handler erreicht, können wir jede beliebige Funktion aufrufen. Und von dort aus ist es ziemlich einfach, in eine Ropchain überzugehen und etwas Raffinierteres zu tun.
Als Benutzer von RouterOS gibt es mehrere Möglichkeiten, interne IPC-Nachrichten zu senden. Tatsächlich erlauben alle externen Clients, nach der Authentifizierung beliebige Nachrichten zu senden:
8291) -- verwendet vom Client winbox.exeDiese Schnittstellen unterscheiden sich in der Art und Weise, wie sie den anfänglichen Authentifizierungs-Handshake durchführen, erlauben einem Benutzer jedoch nach der Authentifizierung, beliebige Nova Messages per Proxy in das interne System einzuschleusen. Siehe unseren Blogbeitrag und unser Repository zum Reverse-Engineering der kryptografischen Protokolle von Winbox und MAC Telnet!
In dieser Exploit-Implementierung verwenden wir den WebFig-Endpunkt als unseren primären Kommunikationsmechanismus. Siehe webfig.py für unsere reverse-engineerte Client-Implementierung.
Allerdings gibt es ein Problem, wenn wir versuchen, unseren verwundbaren FoisHandler-Endpunkt aufzurufen:
Jeder Handler in RouterOS kann eine "Policy"-Bitmaske definieren, die festlegt, welche Benutzer ihn aufrufen dürfen. Es stellt sich heraus, dass FoisHandler eine Policy von 0x80000000 hat, die nur internen Zugriff anzeigt (d. h. Nachrichten, die von anderen Systemprozessen stammen).
Als Admin-Benutzer ist die maximale Berechtigungs-Bitmaske, die wir über die GUI setzen können, nur 0x7fffe, was nicht ausreicht.
Das bringt uns zu unserem zweiten Bug: einer Privilegieneskalation von Admin zu "Super-Admin".
Während die GUI uns nur erlaubt, eine Berechtigungs-Bitmaske von 0x7fffe zu setzen, sendet sie intern tatsächlich nur eine IPC-Nachricht, bei der eines der Felder den Bitmaskenwert enthält: