Ataque a un cliente FTP: MGET y mucho más de lo que esperabas
4 de abril de 2018
0 minutos de lecturaIntroducción
A menudo escuchamos sobre vulnerabilidades en clientes HTTP, como los navegadores web, que suelen ser explotadas por contenido web malicioso. Esto no es nada nuevo. Pero ¿sabías que los propios clientes FTP también pueden tener vulnerabilidades que se pueden explotar? Los servidores maliciosos a los que se conectan los clientes pueden atacarlos.
En esta publicación, mostraré una interesante vulnerabilidad de recorrido de rutas que identificamos y divulgamos de forma responsable a varios proveedores afectados en noviembre de 2017. Esta vulnerabilidad puede afectar varias aplicaciones y bibliotecas, y permitir que un servidor FTP malicioso cree o sobrescriba archivos en cualquier lugar del sistema de archivos local. Como verás en los detalles a continuación, esta vulnerabilidad se debe a la falta de validación y afecta no solo a los clientes FTP, sino también a muchas otras aplicaciones y bibliotecas de diversos ecosistemas, como Java, npm y otros.
La vulnerabilidad
Bien, ¡veamos el problema! Queremos programar una función que descargue el contenido de una carpeta FTP remota a una carpeta local. Como la mayoría ya sabemos, el protocolo FTP no ofrece un comando para descargar una carpeta, pero podemos combinar varios comandos para lograrlo.
Podemos hacer lo siguiente:
Enumerar todos los archivos de la carpeta remota (comandos FTP
LISToNLST)Para cada archivo de la lista anterior: descargarlo y guardarlo en una carpeta local (comandos FTP
GEToMGET)
Un ejemplo de código Java que realiza esta operación con la biblioteca Apache commons-net podría verse así:
El código anterior recorre cada archivo que devuelve el servidor y lo descarga en una carpeta de destino local. Por ejemplo, si el primer archivo de la carpeta remota se llama passwd y nuestra carpeta de destino local es /var/data/sync/, el archivo terminaría descargándose en /var/data/sync/passwd.
Pero ¿qué ocurre si el servidor FTP se vuelve malicioso y, en lugar de responder al comando LIST con passwd, devuelve ../../../../etc/passwd como nombre de archivo? El código anterior terminaría colocando el archivo en /var/data/sync/../../../../etc/passwd y, en la práctica, sobrescribiría /etc/passwd con el archivo recién descargado.
Podrías decir que ../../../../etc/passwd no es un nombre de archivo válido, y tienes razón. Pero el RFC no dice que no lo sea. Técnicamente, no toma partido sobre el sistema de archivos y deja que el cliente y el servidor lo resuelvan por su cuenta. Por ejemplo, una respuesta de un servidor FTP basado en Windows a un comando LIST podría verse así:
En cambio, una respuesta de uno basado en Unix se ve así:
De hecho, existen muchos otros formatos de sistemas de archivos. Aquí tienes una lista de los que admite la biblioteca apache commons-net:
Por lo general, los clientes FTP no validan los nombres de archivo: los devuelven tal cual para que los desarrolladores los validen. No hace falta decir que esta validación suele pasarse por alto. Esto es muy evidente al revisar proyectos alojados en github o distintos sitios con fragmentos y ejemplos de código, como StackOverflow y CodeJava.
Estudio de caso: Apache HIVE
Apache Hive es un proyecto de software de almacén de datos basado en Apache Hadoop que permite resumir, consultar y analizar datos. Hive ofrece una interfaz similar a SQL para consultar datos almacenados en diversas bases de datos y sistemas de archivos integrados con Hadoop. Entre otras funciones, permite copiar datos de servidores FTP mediante el comando COPY-FROM-FTP.
Al revisar el código, encontramos la llamada retrieveFileList().
Dentro de la función retrieveFileList, vemos que el nombre de archivo que devuelve el servidor se agrega al nombre del directorio sin ninguna validación (name = dir + name;). El archivo se agrega a una cola para descargarlo más tarde.
Más adelante, en el hilo de descarga, se extrae el archivo de la cola y se descarga del servidor.
Un posible ataque consiste en sobrescribir el archivo authorized_keys de SSH del usuario root para poder iniciar sesión como root más adelante. Supongamos que una instancia de Apache Hive se conecta a nuestro servidor FTP para descargar datos de comerciantes a diario. Para llevar a cabo este ataque, modificaríamos nuestro servidor FTP para enviar al cliente nombres de archivo maliciosos con recorrido de rutas. Por ejemplo, podríamos responder a un comando LIST con ../../../../../../../home/root/.ssh/authorized_keys.
Cuando Hive ejecuta esta instrucción (suponiendo que se ejecuta como root), el archivo authorized_keys de SSH de root se sobrescribe con uno que conoce el atacante.
La vulnerabilidad anterior se divulgó de forma responsable a Apache Foundation. Cronología:
Fecha | Evento |
|---|---|
2/11/2017 | El equipo de investigación de seguridad de Snyk descubrió la vulnerabilidad. |
8/11/2017 | Se informó a la fundación la lista de productos Apache afectados. |
5/2/2018 | Apache nos informó que planeaba lanzar una versión corregida antes de fines de febrero. |
4/4/2018 | Se publicó la entrada. |
Los detalles también se publicaron en la base de datos CVE el 4/4/2018 para el proyecto Apache Hive.CVE-2018-1315: la instrucción «COPY FROM FTP» de HPL/SQL puede escribir en cualquier ubicación si el servidor FTP está comprometido:
Gravedad: Moderada
Proveedor: The Apache Software Foundation
Versiones afectadas: Hive 2.1.0 a 2.3.2
Descripción: Cuando se ejecuta la instrucción «COPY FROM FTP» mediante la extensión HPL/SQL de Hive, un servidor FTP comprometido o malicioso puede hacer que el archivo se escriba en una ubicación arbitraria del clúster desde el que se ejecuta el comando. Esto se debe a que el código del cliente FTP de HPL/SQL no verifica la ubicación de destino del código descargado. Esto no afecta a los usuarios hivecli ni hiveserver2, ya que hplsql es un script de línea de comandos independiente que debe invocarse de otra manera.
Mitigación: Los usuarios de HPL/SQL con Hive 2.1.0 a 2.3.2 deben actualizar a la versión 2.3.3. Otra opción es desactivar el uso de HPL/SQL por otros medios.
Resumen
Hemos explicado cómo una vulnerabilidad presente en algunas aplicaciones y bibliotecas cliente FTP se debe a que los datos del servidor FTP no se validan correctamente. En el pasado se han encontrado problemas similares. Por ejemplo, en 2002, Steve Christey, ingeniero principal de seguridad de la información en MITRE, descubrió que el problema afectaba a varios clientes FTP, incluido el cliente FTP nativo de Linux y wget.
Validar las entradas es esencial, y no solo por motivos de seguridad. Como desarrollador, es muy fácil pensar en cómo usaría nuestras API una persona promedio, pero también es importante prever las entradas inesperadas que podrían provenir de atacantes. Al procesar listas de directorios de servidores FTP, asegúrate de validarlas y bloquear los nombres de archivo que comiencen con / o contengan ...
Empieza con Capture the Flag
Aprende a resolver desafíos de Capture the Flag viendo nuestro taller virtual introductorio a pedido.