Continuamos analizando las vulnerabilidades de los conmutadores industriales: ejecutamos código arbitrario sin contraseña



En Positive Research 2019, revisamos el Protocolo de gestión de conmutadores industriales Moxa. Esta vez, continuaremos con este tema y analizaremos en detalle la vulnerabilidad CVE-2018-10731 en los interruptores Phoenix Contact de los modelos de línea FL SWITCH 3xxx, FL SWITCH 4xxx y FL SWITCH 48xx identificados por nuestros expertos. Esta vulnerabilidad, detectada en la interfaz web del dispositivo, permite que se ejecute código arbitrario sin conocer las credenciales del dispositivo y tiene una calificación de 9 sobre 10 en la escala CVSS versión 3.

Primera vista


Los dispositivos mencionados anteriormente están ejecutando Linux, y puede usar la interfaz web para configurarlos. Al igual que con muchos otros dispositivos IoT, domésticos e industriales, la interfaz web consta de muchas aplicaciones CGI que procesan las solicitudes HTTP de los usuarios. En nuestro caso, las aplicaciones CGI utilizan activamente la biblioteca cgic, que facilita el trabajo con solicitudes HTTP, y las funciones de esta biblioteca están integradas en la biblioteca compartida libipinfusionweb.soubicada en el sistema de archivos del dispositivo.

Al procesar una solicitud HTTP, el servidor web pasa los datos de la solicitud del usuario a la aplicación CGI como un conjunto de variables de entorno. Su procesamiento inicial lo realiza la función de mainbiblioteca libipinfusionweb. A continuación, la función mainllama a la función de la cgiMainaplicación CGI, en la que tiene lugar el procesamiento posterior de la solicitud.



Figura 1. Procesamiento de una solicitud HTTP

En el curso de su trabajo, la función principal de la biblioteca libipinfusionwebllama a una función get_login_userque, en función de los valores de Cookie pasados, determina si el usuario ha pasado la autenticación en el sistema.



Figura 2. Fragmento de pseudocódigo de la

función principal La función get_login_userrecibe el valor del parámetro Cookie c_sessionutilizando la función cookies_get_valuey lo almacena en una variable local_e0. La variable en sí local_e0es una matriz de caracteres de un solo byte con una longitud de 0x80 y se encuentra a una distancia de 0xE0 desde el comienzo de la pila.



Figura 3. Fragmento del pseudocódigo de la función get_login_user

Sin embargo, en el código de la función cookies_get_valuese puede ver que el cgiCookieStringvalor del parámetro Cookie recibido por la función tiene una longitud máxima de 0x400 bytes.



Figura 4. Un fragmento del pseudocódigo de la función cookies_get_value.

Por lo tanto, al pasar un parámetro de Cookie de más de 0xE0 (224) caracteres, la función get_login_userguardará el valor de este parámetro en su pila, como resultado de lo cual local_e0se sobrescribirá toda la información en la pila que está detrás de la variable , incluida la dirección función de retorno.

Nota: Cuando una función llama a otra, la dirección de retorno se almacena en la pila. El control se transfiere a esta dirección cuando la función llamada finaliza su trabajo. En consecuencia, si reescribe esta dirección, puede obtener el control sobre el proceso de ejecución del programa. Por ejemplo, un atacante puede reemplazar esta dirección con la dirección de un código malicioso ubicado en el espacio de direcciones del programa.

Tenga en cuenta que la reescritura de la dirección de retorno se produce antes de que se verifique la autenticación, lo que permite aprovechar esta vulnerabilidad para un atacante que no conoce las credenciales del dispositivo.

Explotación


Examinamos varias opciones para demostrar la posibilidad de explotar esta vulnerabilidad. Lo más simple es escribir el código de la carga útil en la pila (0x400 - 0xE0 = 800 bytes restantes, es suficiente para el código) y reescribir la dirección de retorno con la dirección del código. Teóricamente, esta opción era posible, ya que el procesador del conmutador vulnerable no admite la función NX-bit (es decir, permite la ejecución de código ubicado en cualquier lugar, incluso en la pila), pero en la práctica tenía serias limitaciones.

El procesador de conmutador vulnerable tiene una arquitectura MIPS; Muchas de las instrucciones del procesador en esta arquitectura están codificadas en secuencias de bytes que contienen cero bytes. El contenido del búfer se escribe hasta el primer byte cero (debido al uso de la funciónstrcpy), por lo tanto, solo es necesario usar operandos que no contengan un byte nulo, lo cual es imposible, ya que cualquier carga útil usaría al menos varios de estos bytes.

Al construir la cadena ROP, nuevamente, tendríamos que enfrentar las restricciones del byte nulo: la dirección de los dispositivos ROP no debería contener ceros, lo que complica mucho su búsqueda. En general, solo podríamos usar un cero, copiado por la función strcpy. Esto impone una limitación en la creación de una cadena ROP completa, y además de esto, los dispositivos que necesitábamos eran extremadamente pocos. Sin embargo, durante las búsquedas en la biblioteca libipinfusionweb, se encontró el siguiente fragmento de código:



Figura 5. Un fragmento del código ejecutable de la biblioteca libipinfusionweb

Siempre que el contenido del registro $ s0 esté controlado, este fragmento de código le permite ejecutar un comando del sistema operativo utilizando una función mysystem(inicialmente, esta función no tenía nombre, pero le cambiamos el nombre, ya que es muy similar a la función del sistema en Linux).

Como estamos reescribiendo la dirección de retorno de la función get_login_user, esta función se ejecutará hasta el final. En el epílogo de la función get_login_user, puede ver que el valor del registro $ s0 se restaura desde el valor previamente guardado en la pila (en el desplazamiento 0xD8 desde la parte superior de la pila). Sin embargo, en este punto, esta área de la pila ya está bajo nuestro control, es decir, de hecho, podemos lograr el control sobre el contenido del registro $ s0 y así ejecutar comandos arbitrarios del sistema operativo utilizando la función mysystem.



Figura 6. Un fragmento del código ejecutable de la función get_login_user

Por lo tanto, para demostrar con éxito la explotación de esta vulnerabilidad, debemos enviar como parámetro una Cookie c_sessionlínea larga que contenga:

  • Comando de cadena del sistema operativo, que posteriormente se pasará a la función mysystem;
  • la dirección de este comando en la pila;
  • nueva dirección de retorno (dirección del fragmento de código que se muestra en la Fig. 5).

La carga útil final debería tener este aspecto:



Figura 7. Carga útil

En este punto, ya teníamos un shell en el dispositivo obtenido mediante una vulnerabilidad que necesitaba derechos de administrador para operar. Por lo tanto, pudimos obtener información adicional que nos ayudó a operar:

  • ASLR en el dispositivo en estudio fue deshabilitado; por lo tanto, las direcciones del gadget utilizado y los comandos del sistema operativo siempre serán los mismos.



Figura 8. Estado de ASLR en el dispositivo bajo investigación

  • El rango de direcciones de memoria en las que podría estar la pila. Para calcular la dirección exacta, revisamos todas las direcciones en este rango.

Como carga útil, implementamos la carga de un shell web, una aplicación CGI con los siguientes contenidos:

#!/bin/sh
eval $HTTP_CMD 2>&1

Dado que, de acuerdo con el protocolo CGI, el contenido de los encabezados HTTP se transmite a la aplicación CGI en forma de variables de entorno con los nombres HTTP_ <Nombre del encabezado>, este shell utilizará el comando evalpara ejecutar el contenido del encabezado HTTP CMD. La figura a continuación muestra el resultado de la operación y ejecución exitosas del comando ls usando el shell cargado.



Figura 9. El resultado de la operación y ejecución exitosas del comando ls

Conclusión


Hemos demostrado la capacidad de explotar esta vulnerabilidad. Como ya hemos mencionado, su funcionamiento no requiere el conocimiento de la contraseña y, por lo tanto, incluso puede ser realizada por un atacante no autenticado.

Hackear un conmutador de red industrial puede comprometer toda la producción. La violación de la interacción de la red puede afectar negativamente el proceso hasta que se detenga por completo.

La información sobre la vulnerabilidad y la PoC se transfirieron al proveedor que lanzó la versión de firmware corregida 1.34, y el identificador CVE-2018-10731 se asignó a la vulnerabilidad en sí.

Buscando una persona


Si desea hacer tales cosas, solo estamos buscando un especialista en nuestro equipo. Nos dedicamos al análisis de seguridad de los sistemas de control de procesos (grandes instalaciones industriales / de energía / transporte, etc.). En cada proyecto, buscamos formas de detener o interrumpir el funcionamiento de estos objetos. Cada vez encontramos muchas formas de influir en el proceso de fabricación, explorando hardware y software industrial, analizando protocolos de red patentados. Encontramos e informamos muchos tyrodeyev, escribimos informes (no según GOST) y hacemos mucho más. Cuando hay tiempo, hablamos en el IB y no solo en las conferencias. Enlace a la vacante: hh.ru/vacancy/36371389

Publicado por Vyacheslav Moskvin, Tecnologías positivas

All Articles