¿Qué es el cruce de directorio?

El cruce o salto de directorio, también conocido como «path traversal» (e identificado con CWE-22), es una vulnerabilidad de aplicación web que permite a los atacantes acceder a archivos no deseados en un sistema de archivos subyacente. Según cómo y dónde se produzca el salto, esto podría permitir a un atacante leer o escribir archivos arbitrarios en el servidor web, lo que posiblemente permitiría al atacante leer datos sensibles o archivos, modificar datos de la aplicación o tomar el control completo del servidor web.

Las vulnerabilidades de salto se describen normalmente en función de si permiten leer archivos o escribir archivos. En los siguientes apartados mostraremos el impacto que puede tener cada una.

Salto de directorio que permite leer archivos arbitrarios

Piensa en una aplicación que permite a un usuario almacenar fotos y recuperarlas más tarde con una petición GET usando un parámetro de nombre de archivo para especificar qué archivo recuperar. Si la aplicación no incluye protecciones frente al salto de directorio y crea la ruta del archivo usando el parámetro de nombre de archivo proporcionado, podría ser posible recuperar archivos arbitrarios del servidor web subyacente. La figura n.º 1 muestra esta secuencia en la práctica:

Si bien la aplicación es vulnerable ante el salto descrito, sigue habiendo limitaciones que hay que tener en cuenta, como los permisos de la aplicación. Por ejemplo, si se aplica el principio del mínimo privilegio, que restringe el acceso de la aplicación al servidor web, sus permisos pueden limitar los archivos a los que puede acceder el atacante aprovechándose de la vulnerabilidad. Este es uno de los motivos por los que las cargas útiles de salto suelen utilizar /etc/passwd como objetivo, y es que el archivo debe ser legible para todos los usuarios. Hay otras formas de aislar y limitar el acceso a la aplicación que repasaremos más a fondo en la sección de prevención.

Salto de directorio que permite escribir archivos arbitrarios

Vuelve a pensar en esa misma aplicación de almacenamiento de fotos, pero ahora permite al usuario dar nombre a cada una de las fotos que almacena. Al guardar el archivo en el disco, la aplicación utiliza el nombre proporcionado para crear la ruta del archivo de la foto. A menos que haya suficientes protecciones, un atacante puede añadir secuencias de salto (p. ej., ../) al nombre proporcionado, controlando en qué directorio se almacena el archivo. 

Aunque esto pueda parecer inofensivo, ya que solo se está almacenando una foto, hay formas de seguir aprovechando la vulnerabilidad. Si no se valida el tipo de archivo (p. ej., JPEG, PNG), un atacante podría cargar cualquier tipo de archivo, lo que daría lugar a varios escenarios de explotación diferentes, como:

  • Añadir la clave pública del atacante al archivo authorized_keys de un usuario (p. ej., /root/.ssh/authorized_keys) para obtener acceso persistente

  • Sobrescribir archivos de la aplicación para modificar el comportamiento de la aplicación

  • Cargar una shell web dentro de la raíz web

  • Provocar una denegación de servicio sobrescribiendo archivos del sistema necesarios

  • Cargar archivos ejecutables (p. ej., malware, ransomware)

Dependiendo del nivel de acceso con el que cuente la aplicación, un salto de directorio con escritura en un archivo arbitrario puede tener un efecto devastador.

Ejemplos reales de salto de directorio

Aclarados los conceptos básicos del salto de directorio, veamos cómo se ha aprovechado esta vulnerabilidad en el mundo real en los últimos tiempos.

CVE-2023-2825: salto de directorio en Gitlab

En la versión 16.0.0 de Gitlab, existe una vulnerabilidad de salto de directorio que permite leer archivos arbitrarios. Subir un archivo como adjunto a un Issue en una instalación predeterminada de Gitlab hace que Gitlab almacene el archivo en una ruta de 10 directorios con un patrón como el que se muestra a continuación:

/var/opt/gitlab/gitlab-rails/uploads/@hashed/<directory>/<directory>/<directory>/<directory>/<filename>

Después de la carga, Gitlab también proporciona un punto de conexión para recuperar el archivo en cuestión:

/<repo-name>/uploads/<file-id>/<filename>

En una petición a ese endpoint, Gitlab no sanea ni valida el parámetro filename, lo que permite un ataque de salto de directorio. Para aprovechar el salto, el repositorio debe estar anidado dentro de al menos 5 grupos, y el número de grupos se correlaciona directamente con la cantidad de directorios que puedes recorrer mediante la vulnerabilidad. 

En una instalación estándar, esto significa que se debe anidar el repositorio en 11 grupos para poder llegar a la raíz del sistema de archivos. En este caso, una carga útil de ataque para recuperar el archivo /etc/passwd sería algo así:

GET /Group-1/Group-2/Group-3/Group-4/Group-5/Group-6/Group-7/Group-8/Group-9/Group-10/Group-11/<repo-name>/uploads/<file-id>/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd

Los atacantes no autenticados solo pueden aprovechar la vulnerabilidad si un repositorio público cumple el requisito de los grupos anidados. Es poco probable que esto ocurra, por lo que es más probable que la vulnerabilidad la aproveche un usuario autenticado con privilegios para crear grupos anidados y repositorios que cumplan los requisitos de explotación. Una cadena de aprovechar completa puede crear primero los grupos y el repositorio necesarios, cargar un archivo y, a continuación, aprovechar el recorrido transversal para leer archivos arbitrarios, como se muestra en la POC aquí.

Vulnerabilidad y exposición comunes-2022-48362: salto de directorio en Desktop Central de ManageEngine

En compilaciones de ManageEngine Desktop Central anteriores a 10.1.2127.1, un salto de directorio en la funcionalidad de carga de archivos permitía escribir archivos arbitrarios manipulando el parámetro «computerName» (o algunos otros) para incluir secuencias de salto. 

Cuando se descubrió, esta vulnerabilidad se explotaba activamente y se combinaba con una omisión de autenticación (CVE-2021-44515) para permitir la ejecución remota de código. Para ser breves, nos centraremos en la parte de la explotación correspondiente al recorrido de ruta, ya que permite la escritura de un archivo y elude una validación poco rigurosa. 

En una función llamada «doPost», Desktop Central maneja varios parámetros como parte de la carga de un archivo, entre ellos «computerName» y «filename». De esta función surgen dos vulnerabilidades que conducen a un salto de directorio exitoso que permite escribir archivos:

  1. Solo se comprueba si el parámetro filename contiene secuencias de recorrido. Otros parámetros, como «domainName», «computerName» o «customerId», se usan para crear la ruta absoluta del archivo, pero no se comprueba si contienen secuencias de recorrido. «computerName» es el último parámetro utilizado en la cadena concatenada, por lo que sería el lugar ideal para introducir una secuencia de recorrido, ya que no se le añadirá contenido adicional.

  2. La carga de archivos permite archivos con extensiones zip, 7z y gz. A simple vista, esto puede parecer seguro. Sin embargo, como Desktop Central es una aplicación Java y los archivos JAR se crean sobre el formato zip, esto permite la ejecución remota de código. Al cargar un archivo zip en el directorio C:\Program Files\DesktopCentral_Server\lib y forzar un reinicio, un atacante avezado puede sobrescribir archivos de clase en la aplicación para incluir su propio código y lograr la ejecución de código. 

Esta vulnerabilidad pone de relieve el grave impacto que puede permitir una vulnerabilidad de salto de directorio, al tiempo que muestra cómo una prevención incompleta puede permitir involuntariamente el salto de directorio. 

Salto de directorio desde el punto de vista de los WAF

El salto de directorio es una de las técnicas de ataque más habituales, como destacamos en nuestro Informe de amenazas y efecto red del segundo trimestre de 2023. 

Esto puede deberse a varios motivos, entre ellos la gravedad del impacto si tiene éxito o el tamaño de las listas de cargas útiles que pueden utilizar los atacantes y los escáneres. Por ejemplo, un fragmento de una de las listas de salto de directorio de PayloadsAllTheThings intenta leer el mismo archivo con distintos niveles de salto, como se muestra a continuación:

../../../../../../../../../etc/passwd
../../../../../../../../etc/passwd
../../../../../../../etc/passwd
../../../../../../etc/passwd
../../../../../etc/passwd
../../../../etc/passwd
../../../etc/passwd

En la mayoría de los casos, es probable que un atacante no sepa dónde se encuentra la aplicación en el sistema de archivos al probar una vulnerabilidad de salto de directorio. Sin embargo, las aplicaciones no irán más allá de la raíz del sistema (es decir, /), por lo que los atacantes utilizan secuencias más largas de «../» para asegurarse de que se alcance la raíz, al tiempo que incluyen también secuencias más cortas por si las secuencias más largas se bloquean o interrumpen la funcionalidad de la aplicación.

Otros tipos de ataques, como el Cross-Site Scripting (XSS), pueden usar cargas útiles políglotas que combinan múltiples técnicas en una sola carga útil. Esto lleva a que los atacantes y los escáneres envíen muchas más cargas útiles para probar el traversal que al probar XSS. Nuestro archivo de ejemplo de PayloadsAllTheThings contiene 140 cargas útiles, en comparación con su archivo XSS_Polyglots, que tiene 16. El archivo de cargas útiles más grande para traversal en PayloadsAllTheThings tiene más de 21 000 entradas, en comparación con el más grande para XSS con más de 600, SQLi con más de 400 (aunque debe asumirse que esto sería mayor en la práctica si se desconoce el tipo de base de datos, ya que habría que probar varios tipos) y más de 400 para la inyección de comandos del sistema operativo

Aunque el tamaño de las listas de cargas útiles de salto ofrece una hipótesis para la técnica de ataque de salto ampliamente observada, la gravedad del impacto también puede hacer que la técnica se utilice con más frecuencia. , como se demuestra en el análisis anterior de Vulnerabilidad y exposición comunes-2022-48362, que permitió la ejecución remota de código y se sabía que se explotaba en el momento de su descubrimiento.

Prevención de vulnerabilidades de salto de directorio

Existen varias estrategias que pueden utilizarse para prevenir las vulnerabilidades de traversal, como cambios de diseño para evitar crear rutas de archivos con entrada del usuario, la validación estricta de la entrada, el uso de la canonización de rutas y la limitación del acceso de la aplicación. A continuación, veremos cada una de ellas.

Prevenir la creación de rutas de archivo con entrada del usuario

En vez de usar la entrada del usuario para crear la ruta del archivo, considera usar un identificador o nombre correspondiente del archivo para hacer referencia al archivo. A continuación, asigna los identificadores de archivo a la ruta de almacenamiento correspondiente. Cuando un usuario solicite este archivo o cargue un archivo, solo podrá controlar su id, lo que impide que el usuario acceda en ningún momento al contenido utilizado para crear la ruta del archivo. Esto elimina por completo la posibilidad de un salto de directorio, ya que la entrada del usuario ya no se usa para crear la ruta del archivo recuperado.

Validación estricta de la entrada del usuario

La validación estricta no es lo mismo que el saneamiento. En vez de sanear la entrada intentando eliminar las secuencias de salto (como «../»), que pueden eludirse de innumerables maneras, valida que la entrada del usuario solo contenga el contenido esperado y rechaza todo lo que no supere la validación estricta. Ejemplos de validación que pueden ayudar a impedir el salto de directorio:

  • Validar que un nombre de archivo solo contiene valores alfanuméricos

  • Validar que haya un solo carácter «.» en el nombre de archivo proporcionado

  • Validar que no se incluyan caracteres no deseados en la entrada proporcionada (p. ej., /, \\)

  • Validar el tipo de archivo de un archivo cargado (no por la extensión, que se puede burlar fácilmente)

Utiliza funcionalidades del lenguaje de canonización de rutas para una validación estricta

La canonización de rutas básicamente acorta la ruta del archivo a su ruta real, eliminando de forma efectiva enlaces simbólicos, secuencias ../ y otro contenido simbólico. Después de obtener una ruta canónica, puedes verificar que siga empezando por el directorio base previsto (p. ej., uploads/photos/). Algunos ejemplos de funciones para obtener una ruta canónica son:

  • Java: getCanonicalPath

  • PHP: realpath

  • C: realpath

  • ASP.NET: GetFullPath

Limitar el acceso a la aplicación

En general, una aplicación solo debe tener acceso a archivos y directorios a los que necesita acceder para funcionar correctamente. Así, en algunos casos de salto de directorio, esto ayuda a limitar las consecuencias de la vulnerabilidad si se descubre. Por ejemplo, una aplicación web no debería ejecutarse nunca bajo el usuario root y, en la medida de lo posible, debería estar restringida a acceder solo a los archivos que necesita para servir la aplicación.

Resumen

El cruce de directorios, también conocido como «path traversal», es una vulnerabilidad de aplicación web que permite a los atacantes acceder a archivos no previstos en un sistema de archivos subyacente. Dependiendo de la vulnerabilidad del salto de directorio, el atacante podría llegar a leer datos sensibles o archivos, modificar datos de aplicaciones o tomar el control completo del servidor web. Las vulnerabilidades de salto pueden acarrear graves consecuencias y, como hemos visto en los ejemplos reales y los datos del WAF de última generación, son un importante vector de ataque. Sin embargo, las aplicaciones pueden prevenir las vulnerabilidades de recorrido de ruta siguiendo las soluciones que hemos descrito. Si tienes dificultades a la hora de impedir el salto de directorio o utilizas un producto que ha sufrido estas vulnerabilidades en el pasado, consulta el WAF de última generación de Fastly para protegerte frente a estos y otros ataques.

¿Listo para empezar?

Ponte en contacto con nosotros