
Jailbreak remoto MikroTik per v6.x.x
______ ____ _____ _____ _ _
| ____/ __ \_ _|/ ____| | | |
| |__ | | | || | | (___ | |_ ___ __| |
| __|| | | || | \___ \| __/ _ \/ _` |
| | | |__| || |_ ____) | || __/ (_| |
|_| \____/_____|_____/ \__\___|\__,_|
FOISted è un exploit per due vulnerabilità post-autenticazione in RouterOS di MikroTik. Può essere usato per effettuare il jailbreak remoto di RouterOS dalla versione 6.34 (2016) alla 6.49.6 (ultima release v6).
Questo repository include uno script di exploit per dispositivi x86. La vulnerabilità esiste anche su altre versioni di dispositivi; scrivere la ropchain è lasciato come esercizio al lettore :)
Per maggiori informazioni, dai un'occhiata al nostro post sul blog relativo agli internals di RouterOS: https://margin.re/blog/pulling-mikrotik-into-the-limelight.aspx
Automagico:
$ python3 exploit.py -H <router_ip> -u <username> -p <password>
Poi, successivamente:
$ nc <router_ip> 1337
Lo script di exploit determinerà la versione di RouterOS e distribuirà automaticamente la ropchain corretta. Nota: attualmente è supportato solo RouterOS x86.
Se la tua versione non viene identificata per qualche motivo, puoi passarla esplicitamente con:
-v <version> # es. 6.49.6
Se lo stai eseguendo su versioni di RouterOS più recenti della 6.49.6 (l'ultima al momento della pubblicazione pubblica), la tua versione di RouterOS potrebbe non essere nel database dei gadget (./db). Puoi invece passare il percorso a /nova/bin/www e lo script di exploit proverà automaticamente a trovare i gadget giusti per la ropchain:
-f /path/to/nova/bin/www
FOISted sfrutta due vulnerabilità in RouterOS v6 per consentire l'esecuzione remota di codice. In questa sezione esaminiamo alcune conoscenze di base sull'IPC di RouterOS e discutiamo le due vulnerabilità.
Nota: questa sezione è per lo più una versione abbreviata del nostro post completo sul blog. Dai sicuramente un'occhiata per maggiori dettagli!
All'interno di RouterOS di MikroTik, i programmi comunicano tra loro usando un protocollo IPC personalizzato.
I pacchetti di dati effettivi sono Nova Message (nv::message internamente). Questi esistono in un formato pseudo-JSON (pre 6.38) e in un formato binario serializzato:

Ogni processo ha un indirizzo fisso all'interno del sistema RouterOS; ad esempio /nova/bin/user è all'indirizzo 13 e /nova/bin/www è all'indirizzo 70. Inoltre, ogni programma può registrare handler che implementano alcune funzionalità specifiche in un sotto-namespace. Ad esempio, /nova/bin/user ha un handler all'indirizzo 4 che funge da endpoint di "login" e esegue l'autenticazione per altri servizi:

La comunicazione IPC è una parte cruciale del funzionamento di RouterOS. Viene usata per:
Durante i nostri sforzi di reverse engineering, abbiamo scritto uno strumento interno di tracciamento dei messaggi che ci permette di visualizzare tutti i messaggi scambiati durante il funzionamento del router.
Nella demo seguente, puoi vedere tutti i messaggi scambiati mentre si scorrono le pagine dell'interfaccia web: https://youtu.be/Em1hVWnbzQ4
L'interfaccia web di RouterOS è implementata dal binario /nova/bin/www. Tuttavia, pagine specifiche potrebbero essere gestite da librerie "Servlet" separate che implementano funzionalità in librerie condivise separate.
Ad esempio, la servlet jsproxy.p gestisce le richieste a /jsproxy e la servlet winbox.p gestisce le richieste a /winbox, ecc...
Queste servlet sono librerie che vengono caricate in /nova/bin/www la prima volta che sono necessarie. Ad esempio, la prima volta che carichiamo /jsproxy, la libreria jsproxy.p verrà caricata nello spazio di memoria.
Durante questo processo di caricamento delle librerie, abbiamo notato un traffico interessante nel tracer dei messaggi:

Nello specifico, abbiamo trovato un messaggio che veniva inviato dal binario www all'handler #2 di www. Questo è già sospetto perché l'IPC di RouterOS è pensato per la comunicazione inter-processo, non per la comunicazione all'interno dello stesso processo...
Inoltre, abbiamo notato che due degli argomenti sembravano puntatori virtuali (x86 a 32 bit), cosa che ha suscitato il nostro interesse perché era molto insolita.
Ispezionando le funzioni reali all'interno dell'handler #2 di /nova/bin/www, troviamo una funzione chiamata FoisHandler::cmdUnknown che viene eseguita quando vengono ricevuti questi tipi di messaggi.
Sorprendentemente, questa funzione estrae il parametro 0x11 dal messaggio e lo invoca come funzione usando due degli altri parametri come argomenti!
Quindi, chiaramente, se possiamo inviare un messaggio controllato che raggiunge questo handler, possiamo invocare qualsiasi funzione vogliamo. E da lì, è abbastanza facile passare a una ropchain e fare qualcosa di più sofisticato.
Ci sono diversi modi per inviare messaggi IPC interni come utente di RouterOS. Infatti, tutti i client esterni ti permettono di inviare messaggi arbitrari dopo che ti sei autenticato:
8291) -- usato dal client winbox.exeQueste interfacce variano nel modo in cui eseguono l'handshake di autenticazione iniziale, ma una volta autenticate, consentono a un utente di inoltrare messaggi Nova arbitrari nel sistema interno. Vedi il nostro post sul blog e il repository per il reverse engineering dei protocolli crittografici di Winbox e MAC Telnet!
In questa implementazione dell'exploit, usiamo l'endpoint WebFig come meccanismo principale di comunicazione. Vedi webfig.py per la nostra implementazione client sottoposta a reverse engineering.
Tuttavia, c'è un problema quando proviamo a invocare il nostro endpoint vulnerabile FoisHandler:
Ogni handler in RouterOS può definire una bitmask "policy" che specifica quali utenti possono invocarlo. Risulta che FoisHandler ha una policy di 0x80000000 che indica solo accesso interno (cioè messaggi provenienti da altri processi di sistema).
Come utente admin, la bitmask di permessi massima che possiamo impostare con la GUI è solo 0x7fffe, che non è sufficiente.
Questo ci porta al nostro secondo bug: un privilege escalation da admin a "super-admin."
Mentre la GUI ci permette solo di impostare una bitmask di permessi di 0x7fffe, internamente sta in realtà solo inviando un messaggio IPC con uno dei campi contenente il valore della bitmask:

Quindi possiamo semplicemente falsificare il nostro messaggio con il valore della bitmask dei permessi impostato a 0xffffffff!
Una volta fatto questo, abbiamo accesso illimitato per raggiungere qualsiasi endpoint nel sistema!
Il nostro exploit inizia caricando due file sul sistema tramite FTP:
stage2: contiene uno spawner di reverse shell in ascolto sulla porta 1337busybox: ci fornisce un ambiente shell adeguatoIl nostro exploit esegue poi il privilege escalation per permetterci di raggiungere l'endpoint FoisHandler.
Infine inviamo un messaggio appositamente costruito per passare a una ropchain incorporata nel messaggio. La ropchain calcola l'indirizzo di chmod e execve in uClibc ed esegue:
chmod 0777 stage2execve stage2Una volta che stage2 è in esecuzione, puoi connetterti alla porta 1337 e ottenere una shell!
No, entrambe queste vulnerabilità richiedono credenziali admin per essere sfruttate.
Le vulnerabilità esistono da almeno la 6.27 (il software più vecchio che siamo riusciti a scaricare) fino alla v6 più recente: 6.49.6. L'interfaccia web è stata rifattorizzata in RouterOS v7 e l'handler vulnerabile è stato rimosso completamente. Il nostro POC è scritto per x86.
Lo script di exploit funziona (testato!) contro ogni versione di RouterOS dalla 6.34 alla 6.49.6.