
Analysis and PoC for CVE-2018-14847, MikroTik RouterOS Winbox information disclosure vulnerability allowing unauthenticated read access to the credential database.
Nicht authentifizierter Path-Traversal im Winbox-Protokoll von MikroTik, der Admin-Anmeldeinformationen aus /flash/rw/store/user.dat preisgibt
CVE-2018-14847 ist eine Path-Traversal-Schwachstelle in MikroTik RouterOS, die das Winbox-Verwaltungsprotokoll (TCP-Port 8291) betrifft. Ein nicht authentifizierter entfernter Angreifer kann beliebige Dateien aus dem Dateisystem des Routers lesen, einschließlich der Benutzerdatenbank /flash/rw/store/user.dat, in der Passwörter mit einem schwachen statischen XOR-Schlüssel verschlüsselt gespeichert sind.
Die Schwachstelle wurde ursprünglich von Jacob Baines (Tenable) im Juli 2018 durch den By the Way Exploit veröffentlicht. Dieses Repository enthält eine eigenständige Python3-Neuimplementierung mit vollständiger Protokolldokumentation.
| Kanal | Versionen |
|---|
| Longterm | 6.30.1 - 6.40.7 |
| Stable | 6.29 - 6.42 |
| Beta | 6.29rc1 - 6.43rc3 |
MikroTik hat diese Schwachstelle im April 2018 behoben. Geräte, die eine ältere RouterOS-Version als die korrigierten Versionen ausführen, bleiben verwundbar.
Winbox ist MikroTiks proprietäres binäres Verwaltungsprotokoll, das auf TCP-Port 8291 läuft. Frames sind wie folgt aufgebaut:
[total_len - 2][0x01][0x00][total_len - 4]["M2"][fields...]
Der 4-Byte-Header kodiert die gesamte Framegröße. Es ist kein standardmäßiges Little-Endian-u16 – jedes Byte kodiert total_length - 2 und total_length - 4 unabhängig.
Feldkodierung innerhalb jedes Frames:
| Typ-Byte | Bedeutung | Wert |
|---|---|---|
| 0xff | Erweiterter Feldmarker | gefolgt von field_id und Wert |
| 0x09 | u8-Integer | 1 Byte |
| 0x21 | String | 1-Byte-Längenpräfix + Daten |
| 0x88 | Antwort-erwartet-Marker | kein Wert |
| 0xfe | Erweiterte Feld-ID | 3-Byte-ID + Typ + Wert |
Der Dateisystem-Handler befindet sich am Endpunkt (sys=5, handler=0) und stellt drei relevante Befehle bereit:
Der Winbox-Dateisystem-Handler bereinigt den Pfad, der an den Befehl zum Öffnen der Datei übergeben wird, nicht. Durch Einbetten von '/////./../'-Sequenzen kann ein Angreifer die Sandbox-Grenze umgehen und das Root-Dateisystem erreichen:
/////./..//////./..//////./../flash/rw/store/user.dat
Jedes '/////./../'-Segment (10 Bytes) geht eine Verzeichnisebene nach oben. Drei Segmente erreichen das Root-Verzeichnis, woraufhin flash/rw/store/user.dat die RouterOS-Benutzerdatenbank ist. Die Anfrage erfordert keine Authentifizierung.
Der Exploit sendet zwei Frames:
user.dat ist eine Sequenz von nv::message-Datensätzen. Jeder Datensatz wird von einem 2-Byte-LE-Längenfeld eingeleitet und beginnt mit den Magic-Bytes M2. Felder in jedem Datensatz verwenden eine 3-Byte-LE-Feld-ID:
| Feld-ID | Typ | Bedeutung |
|---|
| 0x01 | String | Benutzername |
| 0x02 | u8 | Gruppe - 3 = voller Administratorzugriff |
| 0x11 | String | verschlüsseltes Passwort (leer, wenn nicht gesetzt) |
Passwörter werden mit einem statischen XOR-Schlüssel verschlüsselt, der aus einem fest codierten Salt abgeleitet wird, das in RouterOS einkompiliert ist:
key = MD5(username + "283i4jfkai3389")
password = XOR(encrypted_pass[i], key[i % len(key)]) until null byte
Das bedeutet, dass jede user.dat, die von einem betroffenen Gerät extrahiert wurde, offline ohne Brute-Force entschlüsselt werden kann.
Nachdem der Angreifer das Admin-Passwort erhalten hat, kann er sich über Winbox authentifizieren und mit dem create-file-Befehl zwei Dateien schreiben, die den versteckten Entwickler-Login aktivieren:
/pckg/option aktiviert das Option-Paket
/flash/nova/etc/devel-login aktiviert den devel-Benutzer
Sobald diese Dateien vorhanden sind, stellt der Router eine BusyBox-Root-Shell über Telnet und SSH unter dem Benutzer devel bereit, wobei das Admin-Passwort verwendet wird.
Telnet muss zuerst verbunden werden, damit SSH bei einigen RouterOS-Versionen funktioniert.
Exploit_CVE_2018_14847.py ist ein eigenständiger Python3-Exploit ohne externe Abhängigkeiten. Er implementiert das Winbox-Binärprotokoll von Grund auf und führt Folgendes aus:
# Standard-Port 8291
python3 Exploit_CVE_2018_14847.py 192.168.1.10
# Benutzerdefinierter Port
python3 Exploit_CVE_2018_14847.py 192.168.1.10 8291
Post-Exploitation – Entwickler-Backdoor-Shell:
# Telnet (zuerst verbinden)
telnet -l devel 192.168.1.10
# SSH (nach Telnet-Sitzung)
ssh -oHostKeyAlgorithms=+ssh-dss [email protected]