
Jailbreak remoto de MikroTik para v6.x.x
| / __ _ |/ | | | | | | | | | || | | ( | | ___ | | | || | | || | _ | / _ / _` | | | | || || | ) | || __/ (| | || _/|/ __|_,|
FOISted es un exploit para dos vulnerabilidades posteriores a la autenticación en el RouterOS de MikroTik. Puede usarse para hacer jailbreak de forma remota a RouterOS desde la versión 6.34 (2016) hasta la 6.49.6 (la última versión de la serie v6).
Este repositorio incluye un script de exploit para dispositivos que ejecutan x86. La vulnerabilidad también existe en otras versiones de dispositivos; escribir la ropchain queda como ejercicio para el lector :)
Para obtener más información, consulta nuestra publicación de blog sobre el funcionamiento interno de RouterOS: https://margin.re/blog/pulling-mikrotik-into-the-limelight.aspx
Automágico:
$ python3 exploit.py -H <router_ip> -u <username> -p <password>
Más tarde:
$ nc <router_ip> 1337
El script de exploit determinará la versión de RouterOS y desplegará la ropchain correcta automáticamente. Nota: actualmente solo se admite RouterOS x86.
Si tu versión no se identifica por algún motivo, puedes indicarla explícitamente con:
-v <version> # e.g. 6.49.6
Si estás ejecutando esto en versiones de RouterOS más recientes que la 6.49.6 (la más reciente en el momento del lanzamiento público), es posible que tu versión de RouterOS no esté en la base de datos de gadgets (./db). En su lugar, puedes pasar la ruta a /nova/bin/www y el script de exploit intentará automáticamente encontrar los gadgets adecuados para la ropchain:
-f /path/to/nova/bin/www
FOISted aprovecha dos vulnerabilidades en RouterOS v6 para permitir la ejecución remota de código. En esta sección repasamos algunos conocimientos previos sobre la IPC de RouterOS y analizamos las dos vulnerabilidades.
Nota: esta sección es principalmente una versión abreviada de nuestra publicación completa en el blog. ¡Definitivamente échale un vistazo para más detalles!
Dentro del RouterOS de MikroTik, los programas se comunican entre sí mediante un protocolo IPC personalizado.
Los paquetes de datos reales son Nova Messages (nv::message internamente). Estos existen en un formato pseudo-JSON (anterior a 6.38) y en un formato binario serializado:

Cada proceso tiene una dirección fija dentro del sistema RouterOS; por ejemplo, /nova/bin/user está en la dirección 13 y /nova/bin/www en la dirección 70. Además, cada programa puede registrar handlers que implementan una funcionalidad específica en un sub-namespace. Por ejemplo, /nova/bin/user tiene un handler en la dirección 4 que actúa como endpoint de "login" y realiza la autenticación para otros servicios:

La comunicación IPC es una parte crucial del funcionamiento de RouterOS. Se utiliza para:
Durante nuestros esfuerzos de ingeniería inversa, escribimos una herramienta interna de rastreo de mensajes que nos permite visualizar todos los mensajes intercambiados durante el funcionamiento del router.
En la siguiente demo, puedes ver todos los mensajes intercambiados mientras paginamos a través de la interfaz web: https://youtu.be/Em1hVWnbzQ4
La interfaz web de RouterOS está implementada por el binario /nova/bin/www. Sin embargo, páginas específicas pueden ser gestionadas por librerías "Servlet" separadas que implementan funcionalidad en librerías compartidas separadas.
Por ejemplo, el servlet jsproxy.p gestiona las solicitudes a /jsproxy y el servlet winbox.p gestiona las solicitudes a /winbox, etc.
Estos servlets son librerías que se cargan en /nova/bin/www la primera vez que se necesitan. Por ejemplo, la primera vez que cargamos /jsproxy, la librería jsproxy.p se cargará en el espacio de memoria.
Durante este proceso de carga de librerías, notamos tráfico interesante en el rastreador de mensajes:

Específicamente, encontramos un mensaje que se enviaba desde el binario www al handler #2 de www. Esto ya es sospechoso porque la IPC de RouterOS está pensada para la comunicación inter-procesos, no para la comunicación dentro del mismo proceso...
Además, notamos que dos de los argumentos parecían ser punteros virtuales (x86 de 32 bits), lo que despertó nuestro interés porque era muy inusual.
Al inspeccionar las funciones reales dentro del handler #2 de /nova/bin/www, encontramos una función llamada FoisHandler::cmdUnknown que se ejecuta cuando se reciben este tipo de mensajes.
Sorprendentemente, esta función extrae el parámetro 0x11 del mensaje y lo invoca como una función usando dos de los otros parámetros como argumentos.
Así que claramente, si podemos enviar un mensaje controlado que llegue a este handler, podemos invocar cualquier función que queramos. Y a partir de ahí, es bastante fácil hacer pivot a una ropchain y hacer algo más sofisticado.
Hay varias formas de enviar mensajes IPC internos como usuario de RouterOS. De hecho, todos los clientes externos te permiten enviar mensajes arbitrarios después de haberte autenticado:
8291) -- utilizado por el cliente winbox.exeEstas interfaces varían en la forma en que realizan el handshake de autenticación inicial, pero una vez autenticado, permiten al usuario hacer proxy de Nova Messages arbitrarios hacia el sistema interno. ¡Consulta nuestra publicación en el blog y repositorio para la ingeniería inversa de los protocolos criptográficos de Winbox y MAC Telnet!
En esta implementación del exploit, usamos el endpoint de WebFig como nuestro mecanismo principal de comunicación. Consulta webfig.py para ver nuestra implementación del cliente con ingeniería inversa.
Sin embargo, hay un problema cuando intentamos invocar nuestro endpoint vulnerable FoisHandler:
Cada handler en RouterOS puede definir una máscara de bits de "política" que especifica qué usuarios tienen permitido invocarlo. Resulta que FoisHandler tiene una política de 0x80000000, lo que indica solo acceso interno (es decir, mensajes que se originan desde otros procesos del sistema).
Como usuario administrador, la máscara de bits de permisos máxima que podemos establecer con la GUI es solo 0x7fffe, lo cual no es suficiente.
Esto nos lleva a nuestro segundo bug: una escalada de privilegios de admin a "super-admin".
Mientras que la GUI solo nos permite establecer una máscara de bits de permisos de 0x7fffe, internamente en realidad solo envía un mensaje IPC con uno de los campos que contiene el valor de la máscara de bits:

Así que podemos simplemente forjar nuestro propio mensaje con el valor de la máscara de bits de permisos establecido a 0xffffffff!
Una vez que hacemos esto, tenemos acceso sin restricciones para golpear cualquier endpoint del sistema!
Nuestro exploit comienza subiendo dos archivos al sistema a través de FTP:
stage2: contiene un spawner de reverse shell que escucha en el puerto 1337busybox: nos proporciona un entorno de shell adecuadoNuestro exploit luego realiza la escalada de privilegios para permitirnos golpear el endpoint FoisHandler.
Finalmente, enviamos un mensaje manipulado para hacer pivot a una ropchain incrustada en el mensaje. La ropchain calcula la dirección de chmod y execve en uClibc y realiza:
chmod 0777 stage2execve stage2Una vez que stage2 está en ejecución, puedes conectarte al puerto 1337 y obtener una shell!
No, ambas vulnerabilidades requieren credenciales de administrador para explotarse.
Las vulnerabilidades existen desde al menos la 6.27 (el software más antiguo que pudimos descargar) hasta la v6 más reciente: 6.49.6. La interfaz web fue refactorizada en RouterOS v7 y el handler vulnerable se eliminó por completo. Nuestro POC está escrito para x86.
El script de exploit funciona (¡probado!) contra todas las versiones de RouterOS desde la 6.34 hasta la 6.49.6.