cd ~/blog

~/vulns/lfi-local-file-inclusion.md

LFI (Local File Inclusion)

web 25-08-2025
webLFI

~3 min de lectura


1. Descripción técnica del ataque

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=contact

el servidor ejecuta:

include("contact.php");

Pero si el atacante manipula la URL:

http://example.com/index.php?page=../../../../etc/passwd

el servidor intentará incluir:

include("../../../../etc/passwd.php");

Incluso si .php no está presente o si include() permite incluir archivos sin extensión, el atacante puede leer archivos locales del sistema (por ejemplo /etc/passwd, /var/www/html/config.php, etc.), dependiendo de la configuración de PHP y el sistema operativo.

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) con log poisoning.
    • Archivos subidos al servidor.
      Entonces puede ejecutar PHP malicioso y obtener shell remota.
  • 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. Historia y evolución

  • Años 2000s: LFI era extremadamente común en aplicaciones PHP con estructuras dinámicas de include() o require().

  • 2007–2010: se publicaron numerosas pruebas de concepto de LFI combinadas con log poisoning, permitiendo RCE sin necesidad de subir archivos.

  • 2013: OWASP comienza a enfatizar LFI como una variante crítica de vulnerabilidades de inclusión de archivos (File Inclusion).

  • 2017–actualidad: aunque muchos frameworks modernos evitan include() dinámicos, aún existen casos en aplicaciones legacy o en sistemas CMS mal configurados.

4. Factores que la hacen posible

  1. El parámetro de entrada del usuario controla el nombre o ruta de un archivo.
    Por ejemplo: ?page=, ?template=, ?lang=, etc.

  2. La aplicación usa funciones peligrosas sin validación adecuada, como:

    • include()
    • require()
    • include_once()
    • require_once()
    • file_get_contents()
    • fopen()
  3. Falta de sanitización o uso de listas blancas para limitar qué archivos pueden cargarse.

  4. Configuración insegura del servidor o del lenguaje, como:

    • allow_url_include = On
    • display_errors = On
    • Permisos de lectura amplios en el sistema de archivos.

5. Detección

  • Manual:
    Probar rutas relativas en parámetros como:
    ?page=../../../../etc/passwd ?lang=../../../../windows/win.ini

Observar 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.

6. Mitigación

  1. Nunca incluir archivos basados directamente en parámetros de usuario.

  2. Usar listas blancas (whitelist) de archivos válidos:

$allowed = ['home', 'about', 'contact'];
if (in_array($_GET['page'], $allowed)) {
    include($_GET['page'] . '.php');
}
  1. 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.
  2. Deshabilitar funciones peligrosas si no son necesarias:

    • En php.ini:
disable_functions = include, require, ...
  1. Configurar correctamente el servidor:
    • allow_url_include = Off
    • display_errors = Off en producción.

7. Ejemplo de explotación real

Si una aplicación tiene:

<?php include($_GET['file']); ?>

y el atacante accede a:

http://vulnerable.site/index.php?file=/etc/passwd

La 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.


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
    • CWE-552 – Files or Directories Accessible to External Parties

9. Resumen

LFI es una vulnerabilidad clásica en aplicaciones web, que permite incluir o leer archivos locales del servidor. Puede derivar en robo de información sensible o incluso ejecución de código si se combina con técnicas como log poisoning. Aunque muchos frameworks modernos la mitigan, aún es frecuente en sistemas legacy o aplicaciones personalizadas sin validación estricta de parámetros.

// relacionados