Path Traversal
En esta sección veremos la famosa vulnerabilidad conocida como path traversal, ¿que es?, ¿cómo se explota? ¿en que consiste? Y como se remedia, con ayuda de los laboratorios ofrecidos por Portswigger.
Last updated
En esta sección veremos la famosa vulnerabilidad conocida como path traversal, ¿que es?, ¿cómo se explota? ¿en que consiste? Y como se remedia, con ayuda de los laboratorios ofrecidos por Portswigger.
Last updated
En esta sección veremos todo acerca del camino recorrido, dentro de las paginas web, ya antes lo había estudiado pero sin mucho detalle, ahora vamos a ver en profundidad esto.
Es cierto que las paginas web a día de hoy se protegen mucho más que en el pasado y es por ello que muchas sitios web ya vienen protegidos contra ataques del tipo SQL injection, Cookies, authentication, bypass 2FA etc. y sobre todo también Path traversal y en esta ocasión lo veremos.
Entonces veremos:
Que es un path traversal o recorrido de camino.
Como sortear y atacar sitios web por este modo de ataque.
Como prevenir este tipo de vulnerabilidad en los sitios web.
El path traversal también se conoce como recorrido de directorios, donde se pueden listar directorios diversos que tiene un aplicativo web alojados en el servidor que es el que ejecuta la aplicación, los directorios que se pueden encontrar pueden ser diversos tales como:
Códigos y datos de aplicación.
Credenciales para Sistemas Backend
Archivos sensibles del Sistema Operativo
Y esto puede ser grave porque en ciertos casos el atacante (yo) puedo tomar y modificar ciertos archivos arbitrarios que se pueden desplegar del servidor cambiando la logica de ciertos archivos para cambiar en algunos casos el comportamiento de la aplicacion haciendo que pueda tomar total control.
El ../../ es el directorio root como ya sabemos, donde puede estar etc/passwd or etc/passwords, etc…
Además cabe aclarar que en los sistemas operativos UNIX systems, el Etc/passwd es el directorio estandar donde se guardan ciertas credenciales de users del SO
El ../ es más simple podemos encontrar el directorio var con las imagenes dentro de www/
Existe el archivo de inicialización de ciertos archivos que se hace llamar como win.ini, donde hay variedad de diversos archivos o directorios los cuales se inicializan en cuanto el SO inicia.
La línea que proporcioné del archivo /etc/passwd
tiene el siguiente formato:
Vamos a analizar cada uno de los campos:
Nombre de usuario (carlos
): Este es el nombre de inicio de sesión del usuario. En tu ejemplo, el nombre de usuario es "carlos".
Contraseña (x
): Al igual que en el ejemplo anterior, el campo de contraseña se establece en "x", indicando que la contraseña está almacenada de forma segura en otro lugar.
ID de usuario (12002
): Este es el número único que identifica al usuario en el sistema. En tu ejemplo, el ID de usuario es "12002".
ID de grupo principal (12002
): Este es el ID de grupo principal al que pertenece el usuario. En este caso, el usuario "carlos" pertenece al grupo con ID "12002".
Descripción del usuario ((ninguna)
): Este campo está vacío, indicando que no hay una descripción específica proporcionada para el usuario.
Directorio de inicio (/home/carlos
): Este es el directorio inicial o directorio de inicio del usuario. Cuando el usuario "carlos" inicia sesión, se coloca automáticamente en este directorio. En tu ejemplo, el directorio de inicio es "/home/carlos".
Shell del usuario (/bin/bash
): Este es el programa que se ejecuta cuando el usuario inicia sesión. En este caso, el shell es "/bin/bash", que es el shell de Bash.
En resumen, la línea representa al usuario "carlos" en el sistema. Su ID de usuario es 12002, pertenece al grupo principal con ID 12002, su directorio de inicio es "/home/carlos", y el shell predeterminado es Bash ("/bin/bash"). La contraseña real no se almacena directamente en este archivo, ya que el campo de contraseña se establece en "x".
/etc/passwd
contiene información básica de los usuarios del sistema (nombre de usuario, UID, GID, etc.), pero no guarda las contraseñas directamente. En su lugar, contiene un marcador (generalmente x
o *
) para indicar que las contraseñas se encuentran en otro archivo más seguro.
/etc/shadow
es donde realmente se almacenan las contraseñas, en forma de hashes. Este archivo es accesible solo por el usuario root para evitar accesos no autorizados y proteger la seguridad de las contraseñas.
El sistema de autenticación revisa /etc/shadow
para verificar las contraseñas al inicio de sesión, comparando el hash ingresado con el almacenado.
Podemos imaginar una aplicación que tenga diversos posts con imagenes, podemos ver la imagen que se carga de un post x, desde html del tipo:
Bueno, ¿y esta como lo podemos ver desde un recorrido de caminos path traversal?
Supongamos que la ruta donde está la imagen 218.png está dentro del directorio www/images/218.png
ahora, para devolver una imagen, la aplicación agrega el nombre de archivo solicitado a este directorio base y utiliza una API del sistema de archivos para leer el contenido del archivo. En otras palabras, la aplicación lee la siguiente ruta de archivo:
En este caso suponemos que la aplicación no implementa defensas contra los path traversal así que, como consecuencía uno de atacante puede obtener la ruta más importante de directorios del server que podría ser /etc/passwd/
→
https://insecure-website.com/loadImage?filename=../../../etc/passwd
Esto hace que la aplicación lea desde la siguiente ruta de archivo:
Así es como se leería la ruta del archivo, sin embargo podemos tomar otras lecturas también de otros servers como en windows por ejemplo:
Ahi lo tenemos, es claro que se puede navegar entre directorios en windows tanto como “../” pero también podriamos del tipo “..\” ambos son equivalentes y validos.
Ahora bien vamos a ver el primer laboratorio para probar como sería un recorrido de camino y ver que tal:
A veces las aplicaciones digamos que si implementan defensas para los ataques de recorrido de directorios o path traversal, sin embargo muchas veces no tienen en cuenta las formas en las cuales se pueden saltar u omitir estas defensas, en esta ocasión veremos una de ellas, la cual es:
Mantener una dirección absoluta raiz del directorio, por ejemplo:
http://sindominio.com/ejemplo/imagenes/loadImage?filename=>)=/etc/passwd/
Y digamos que en cierta manera esta es una forma de saltar u omitir esta defensa que las paginas mantienen.
Vamos a resolver un laboratorio de ejemplo →
También podemos llegar a hacer recorridos de caminos anidados sin recursividad directamente, en este caso lo hacemos de esta forma, vamos a ver:
…./ /
….\ /
Y estas secuencias así vuelven a secuencias transversales simples cuando se elimina la secuencia interna, osea que en resumen se interpretan de la misma forma que la secuencia transversal clasica.
A veces basta simplemente con codificar la secuencia transversal para bypassear la seguridad de la aplicación web, porque pasa mucho que las aplicaciones a veces intentan proteger la url a ataques path traversal, el problema es que uno puede codificar la secuencia transveral y de esa forma la pagina si la lee como si nada normal.
Por ejemplo a veces realmente para poder acceder nosotros a un archivo especifico como puede ser passwd, necesitamos el directorio de base para poder acceder por ejm que podría ser var/www/images
por ejm.
Aqui podemos ver como ya tenemos el directorio base para poder acceder a la imagen, sin embargo lo que no tienen en cuenta los desarrolladores es que nosotros como atacantes ya no están dando un indicio una parte para termina la secuencia transversal, en este caso solo sería añadir lo restante que es etc/passwd
Así y lo resolvimos.
A veces se necesita o se requiere que el nombre de un archivo tenga una extensión especifica como .png por ejm, entonces en ese caso si nosotros queremos hacer un path traversal que nos tome el passwd
se supone que la aplicación no nos dejaría porque solo acepta que el final termine con una extensión especifica, pues bueno hay una forma de omitir ello.
Para este caso lo que podemos hacer es añadir el %00
que es un byte nulo
para terminar la ruta del archivo antes que la extensión requerida, ¿me hago entender?
Entonces en este caso podemos añadir eso a nuestro path traversal que hace que solo tengamos nuestro path traversal y entonces de esa forma validamos el path traversal sin que haya obligatoriamente una extensión al final de la ruta.
Ejm: filename=../../../etc/passwd%00.png
La forma más eficaz de evitar esto es haciendo que la entrada proporcionada por el usuario no entre en contacto directo con la API del sistema de archivos, lo mejor en esta via es evitar entrada por parte del usuario a las API del sistema de archivos, y si no es posible evitar esto, hacer lo siguiente: (Se recomienda utilizar dos capas de defensa para evitar ataques)
Valide la entrada del usuario antes de procesarla. Lo ideal es comparar la entrada del usuario con una lista blanca de valores permitidos. Si eso no es posible, verifique que la entrada contenga solo contenido permitido, como caracteres alfanuméricos únicamente.
Después de validar la entrada proporcionada, agregue la entrada al directorio base y use una API del sistema de archivos de la plataforma para canonicalizar la ruta. Verifique que la ruta canonicalizada comience con el directorio base esperado.
Aqui muestro un ejemplo de código Java simple para validar la ruta canónica de un archivo según la entrada del usuario:
Canonicalizar una ruta significa convertirla a su forma estándar o absoluta, eliminando cualquier ambigüedad o redundancia en el camino especificado. Este proceso incluye:
Eliminar referencias relativas, como .
(el directorio actual) y ..
(el directorio padre).
Convertir una ruta relativa en absoluta, usando la ubicación actual como base si es necesario.
Resolver enlaces simbólicos (symlinks), de forma que la ruta final apunte al verdadero destino en el sistema de archivos.
Por ejemplo, si tienes la ruta ./docs/../files/./images
, la versión canonicalizada sería /home/usuario/files/images
, asumiendo que estás en /home/usuario
.
Eso es todo por path traversal. :)
Tenemos una pagina y en vez de pasar el path traversal directamente lo que hacemos es pasarle la dirección raiz absoluta así: