1. Descripción técnica
Un LFI (Local File Inclusion), ocurre cuando una aplicación web permite que el usuario controle (total o parcialmente) la ruta de un archivo que el servidor incluye o lee, sin una validación adecuada.
Esto permite a un atacante incluir archivos locales del sistema de archivos del servidor dentro de la respuesta HTTP.
Ejemplo típico en PHP:
<?php
$page = $_GET['page'];
include($page . ".php");
?>Si la URL es:
http://example.com/index.php?page=contactel servidor ejecuta:
include("contact.php");Pero si el atacante manipula la URL:
http://example.com/index.php?page=../../../../etc/passwdel servidor intentará incluir:
include("../../../../etc/passwd.php");Con este fragmento exacto, el sufijo añadido forma /etc/passwd.php, por lo que la petición no demuestra que /etc/passwd sea legible. La explotación requiere evitar o satisfacer ese sufijo, encontrar un archivo compatible o alcanzar una implementación que use directamente la ruta controlada. Cuando la ruta llega sin esa restricción a include(), require() o una función de lectura, puede exponer archivos locales accesibles para la cuenta del servicio.
2. Impacto de la vulnerabilidad
Dependiendo del contexto, los efectos de una LFI pueden incluir:
Lectura de archivos sensibles del sistema (LFI clásico):
Permite acceder a archivos como:/etc/passwd(usuarios del sistema)/var/www/html/config.php(credenciales de base de datos)C:\Windows\win.ini(en Windows)
Ejecución remota de código (RCE):
Si el atacante logra incluir archivos que contienen código controlado por él, como:- Logs de Apache (
/var/log/apache2/access.log) conlog poisoning. - Archivos subidos al servidor.
Entonces puede ejecutar PHP malicioso y obtener shell remota.
- Logs de Apache (
Enumeración de estructura de archivos:
El error resultante (404, warning, fatal error, etc.) puede ayudar a descubrir rutas reales del sistema o nombres de archivos.
3. Condiciones necesarias
El parámetro de entrada del usuario controla el nombre o ruta de un archivo.
Por ejemplo:?page=,?template=,?lang=, etc.La aplicación usa funciones peligrosas sin validación adecuada, como:
include()require()include_once()require_once()file_get_contents()fopen()
Falta de sanitización o uso de listas blancas para limitar qué archivos pueden cargarse.
Configuración insegura del servidor o del lenguaje, como:
allow_url_include = Ondisplay_errors = On- Permisos de lectura amplios en el sistema de archivos.
4. Validación y detección
- Manual:
Probar rutas relativas en parámetros como:
?page=../../../../etc/passwd ?lang=../../../../windows/win.iniObservar si el contenido del archivo aparece en la respuesta o si se genera un error revelador.
- Automatizada:
Herramientas como:- Burp Suite (Scanner)
- wfuzz
- dirb / gobuster
- LFI-brute
pueden automatizar la inyección de rutas comunes y observar respuestas.
5. Mitigación
Nunca incluir archivos basados directamente en parámetros de usuario.
Usar listas blancas (whitelist) de archivos válidos:
$allowed = ['home', 'about', 'contact'];
if (in_array($_GET['page'], $allowed)) {
include($_GET['page'] . '.php');
}Sanitizar y normalizar la ruta para evitar el uso de
../(traversal):- Eliminar
../,%2e%2e/, etc. - Usar
realpath()y verificar que el archivo esté dentro de un directorio permitido.
- Eliminar
Configurar correctamente el servidor:
allow_url_include = Offdisplay_errors = Offen producción.
6. Ejemplo conceptual
Si una aplicación tiene:
<?php include($_GET['file']); ?>y el atacante accede a:
http://vulnerable.site/index.php?file=/etc/passwdLa respuesta puede contener:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...Esto constituye divulgación de información crítica, pues permite conocer los usuarios del sistema, rutas y más.
7. Explotación documentada
Los writeups muestran varias consecuencias del mismo control de ruta. La lectura directa de archivos aparece, entre otros, en 062-jabita, 103-drippingblues, 117-runas, 121-p4l4nc4 y 04-brain. La combinación con Log Poisoning se documenta en 033-medusa, 063-teacher, 064-thewall, 098-driftingblues-03, 118-tripladvisor y 32-lower5. 106-quick-2, 013-blackhat-2 y 30-loweb convierten una inclusión interpretada por PHP en RCE mediante PHP Filter Chains RCE. Cada variante necesita condiciones adicionales y una LFI aislada no demuestra RCE.
8. Clasificación
Tipo: Inyección / File Inclusion
OWASP Top 10 (2017): Relacionada con A1 – Injection y A5 – Broken Access Control.
CWE:
- CWE-98: Improper Control of Filename for Include/Require Statement in PHP Program
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory