Las aplicaciones web modernas no se parecen en nada a lo que eran antes. El ancho de banda prácticamente ilimitado y el espacio de almacenamiento indefinido que ofrece la computación en nube.

Los microservicios que rodean la arquitectura monolítica y dividen las aplicaciones en capas en pequeños componentes independientes. Las aplicaciones de una sola página que cargan la mayoría de los recursos (incluidos los elementos DOM primarios) una vez por ciclo de aplicación, de modo que se puede utilizar el sitio y actualizar únicamente el contenido dinámico necesario.

Velocidad. Flexibilidad. Fácil integración de software. Compatibilidad cruzada. Rentabilidad. En resumen, las aplicaciones web modernas son potentes hasta la médula. Al mismo tiempo, también son fácilmente susceptibles de ser atacados a distancia y local file inclusion ataque. Pero, ¿qué es un local file inclusion ataque (LFI)?

¿Qué es LFI?

Para que te hagas una idea, las LFI son vulnerabilidades web que son posibles gracias a errores por parte de los programadores. Al introducir un descuido de seguridad en las aplicaciones web, los programadores descuidados permiten que usuarios no autorizados accedan a archivos, aprovechen la funcionalidad de descarga, naveguen por la información disponible y mucho más.

¿Cómo es esto posible por parte de los hackers? A través de la laguna jurídica de la “dinámica file inclusion”. Explotando estos mecanismos de inclusión que los desarrolladores implementan en la aplicación, los ciberdelincuentes pueden introducir un archivo extraño en la mezcla original. A partir de ahí, todo lo que queda por hacer es ejecutar un simple script malicioso. Una vez que el script ha hecho su trabajo, es mejor que pongas la alfombra de bienvenida, porque va a ser un espacio libre en la aplicación, y el anfitrión será cualquiera menos tú.

Pero, ¿qué hace que las aplicaciones web actuales sean tan susceptibles a una vulnerabilidad LFI? Buena pregunta.

El problema reside en todos los lenguajes de scripting del lado del servidor de la web que se precien. Más específicamente, con la parte en la que se basan en file inclusion para mantener el código de las aplicaciones web bonito y ordenado (así como mantenible). Aparte de eso, las file inclusion también permiten a las aplicaciones web leer archivos directamente desde el sistema de archivos, habilitar la funcionalidad de descarga, analizar archivos de configuración, y la lista continúa.

¿Dónde está el problema? El problema puede surgir, y la mayoría de las veces surgirá, del lado de los programadores. Cuando los mecanismos file inclusion no se implementan correctamente, los hackers experimentados no tendrán ningún problema en explotar las capacidades de inclusión de estos mecanismos. Al elaborar y ejecutar un local file inclusion ataque, los ciberdelincuentes pueden revelar información confidencial, inyectar un script de sitio cruzado (XSS) o desencadenar la ejecución remota de código (RCE).

¿Suena un poco amplio? Veamos entonces cómo son caso por caso.

Local File Inclusion Ejemplos

Dado que explotar una vulnerabilidad LFI es tan sencillo técnicamente como añadir un archivo extraño al sistema del objetivo, existen múltiples formas en que los hackers pueden hacerlo. Estos son los métodos más populares:

El caso del archivo PHP

Según las encuestas de Web Tech, nada menos que el 79,2% de los sitios utilizan PHP. Sí, el 79,2% de TODOS los sitios, has leído bien. Y PHP tiene sus ventajas, de eso no hay duda. Al mismo tiempo, el mismo lenguaje de programación también pone en peligro la mayoría de las aplicaciones web actuales.

Como sabes, los desarrolladores de sitios y aplicaciones web que utilizan PHP emplean estas dos funciones para incluir el contenido de un archivo PHP en otro:

  1. La función include()
  2. La función require().

Lo que separa a estas funciones es cómo responden a los problemas de carga de archivos. La primera función include señala una advertencia pero permite que el script continúe. La segunda, la función require, por otro lado, crea un error fatal, deteniendo así el script.

Entonces, ¿cómo sería un ataque de inclusión de archivos PHP? Algo parecido a esto:

Este es un trozo de código que sería vulnerable a un ataque LFI. Verás, cuando la entrada no está desinfectada correctamente, los atacantes no tendrán problemas para modificar la entrada (el ejemplo de abajo) y manipular la aplicación para acceder a archivos restringidos, directorios e información general a través de la directiva “../”. Esto es lo que se conoce como Directory Path Traversal:

En este caso, lo único que tuvo que hacer el ciberdelincuente fue sustituir “nombrearchivo.php” por “../../../etc/test.txt” en la URL de la ruta y, et voilà, pudo acceder al archivo de prueba. En esta fase, el intruso o intrusos podrían cargar un script malicioso en su servidor y acceder a ese script utilizando local file inclusion.

Para desglosarlo, hay cuatro pasos en este proceso:

  1. Los intrusos identifican un laboratorio web con una validación de entrada inadecuada y/o del navegador por parte de los usuarios de la aplicación.
  2. La cadena URL se modifica utilizando la directiva “../” para hacer posible el Directory Path Traversal.
  3. El archivo .php malicioso se carga en el servidor anfitrión a través de una puerta trasera para localizar el script utilizando el método path traversal.
  4. Al hacker se le permite ejecutar su script malicioso de forma descontrolada en la aplicación host debido a una validación inadecuada.

¿Cómo se puede evitar un ataque de este tipo?

Para empezar, puede crear una lista blanca con los parámetros de idioma aceptados. Cuando un método de entrada fuerte no es una opción, puede emplear el filtrado de entrada y la validación de ruta pasada. Con estos métodos puedes eliminar de la ecuación caracteres y patrones de caracteres no deseados.

Eso sí, para ello tendrá que prever todas las combinaciones problemáticas de caracteres. Por ello, una solución más práctica sería utilizar sentencias Switch/Case predefinidas. Con ellas, el sistema determinará automáticamente qué archivos pueden incluirse sin depender de los parámetros de URL y formulario para generar una ruta dinámicamente.

El caso de la página impresa

A veces, será necesario compartir la salida del archivo en varias páginas web (como ocurre, por ejemplo, con los archivos de cabecera). Este enfoque tiene más sentido cuando se desea que los cambios se reflejen en todas las páginas en las que se incluye el archivo. Estos archivos pueden ser archivos HTML planos que no necesitan ningún analizador en el servidor para interpretarlos. También pueden utilizarse para resaltar entradas de datos independientes, incluidos archivos de texto simples.

Digamos que tienes varios archivos .txt con textos de ayuda y te gustaría que estos archivos estuvieran disponibles a través de tu aplicación web. Con eso en mente, puedes hacerlos visibles a través de un enlace, no muy diferente a éste:

En este caso, el contenido del archivo de texto se imprime directamente en la página sin almacenar primero la información en una base de datos.

Entonces, ¿cómo puede esto conducir a una vulnerabilidad local file inclusion?

Cuando no se tiene un filtrado adecuado, los atacantes pueden cambiar fácilmente el enlace anterior por algo parecido a esto:

En consecuencia, pueden acceder a los hashes de las contraseñas dentro del archivo .htpasswd, y a todas las credenciales de usuario que este archivo suele contener. Usando estas credenciales, los ladrones digitales podrían acceder a las áreas restringidas del servidor y causar serios estragos allí. Para añadir más, los mismos hackers podrían incluso ser capaces de leer archivos de configuración ocultos que contienen información sensible (como contraseñas).

Alright, what’s the counterplay here?

Muy bien, ¿cuál es la contrapartida?

En lo que respecta a los archivos de páginas impresas, los contraataques más eficaces son los mismos que ejecutarías contra los archivos descargados. ¿Te preguntas cuáles son? Perfecto. Pero primero veamos en qué consiste este caso.

Descargar el caso Files

Hay archivos que los navegadores abren automáticamente cuando se accede a ellos, no muy distintos de los archivos PDF. Por eso, cuando se desea servir archivos de este tipo como descargas en lugar de mostrarlos en la ventana del navegador, se incluyen cabeceras adicionales, dando así instrucciones al navegador para que se encargue de ello.

Con una cabecera como Content-Disposition: attachment; filename=file.pdf en la solicitud, el navegador renuncia a la parte de “abrir” y descarga el archivo en su lugar.

Por poner un ejemplo, algunas empresas tienen folletos en formato PDF para que los visitantes del sitio puedan utilizar un enlace como éste para descargarlos:

¿Cómo puede esto crear una vulnerabilidad LFI?

Fácil, así es cómo. Para ser un poco más específicos, cuando no se sanea la petición, los atacantes pueden solicitar la descarga de los archivos sobre los que está construida la propia aplicación web, dándoles acceso al código fuente. Al hacerlo, pueden localizar otras vulnerabilidades de aplicaciones web, o “simplemente” leer el contenido de archivos sensibles.

Una mala noticia adicional es que los hackers pueden combinar este exploit con el método de cruce de directorios antes mencionado. Como resultado, la misma función podría permitirles leer el código fuente del archivo connection.php:

Y, suponiendo que estos hackers encuentren los valores de usuario de base de datos, host y contraseña (lo cual no es un escenario improbable), también podrán recoger la base de datos utilizando estas credenciales robadas. En este punto, los ciberdelincuentes tendrán los medios para ejecutar comandos de base de datos y comprometer la estructura del servidor (a menos que el usuario de la base de datos no tenga privilegios de escritura de archivos).

¿Qué hay que hacer para evitar que esto ocurra?

  • Guarda las rutas de los archivos en una base de datos y asigna ID individuales a cada una. De este modo, los usuarios sólo podrán ver el ID, por lo que no podrán ver ni cambiar la ruta del archivo.
  • Lista blanca de archivos verificados y protegidos. A partir de ahí, puedes ignorar cualquier otro nombre de archivo y ruta.
  • No coloque archivos en servidores web que pueden y, en la mayoría de los casos, se verán comprometidos. En su lugar, utilice bases de datos.
  • No ejecutes archivos en directorios específicos. En su lugar, asegúrate de que el servidor descarga automáticamente las cabeceras.

Ejemplos reales de LFI

Hemos visto a muchas plataformas valientes caer víctimas de un local file inclusion ataque. Y, se sorprendería, no son sólo algunos sitios de poca monta los que han sufrido antes un golpe de LFI. A saber:

El sitio web de RedHat. Aunque se abordó y solucionó hace casi una década, el sitio de RedHat tenía varios problemas de seguridad alrededor de 2013. Estos problemas permitieron a los hackers extraer la base de datos del sitio a través de Blind SQLi. La empresa también ha confirmado que el sitio era vulnerable a ataques LFI y XSS.
Weather.gov. Hace diez años, el grupo de hacktivistas KHS utilizó una vulnerabilidad LFI contra weather.gov y fue capaz de acceder y extraer información sensible perteneciente al Servicio Meteorológico Nacional. Por supuesto, al tratarse de un grupo hacktivista, los hackers de Kosovo hicieron pública esa información posteriormente.
Servidor multimedia de Whatsapp. El mismo año que se expuso RedHat, se descubrió que la interfaz del servidor multimedia de Whatsapp era vulnerable a Local File Inclusion transversales. Utilizando este punto débil, los ciberdelincuentes pudieron recopilar nombres de usuario a través de un archivo “/etc/passwd” y otros archivos confidenciales, incluidos archivos de registro como “/apache/logs/error.log” y “/apache/log/access.log”.

Conclusión

Las vulnerabilidades de Local File Inclusion no son ninguna broma. Algunas de las mayores plataformas del mundo han sido víctimas de ellas a lo largo de los años, y la lista sigue aumentando. Al mismo tiempo, mientras sigas las sugerencias anteriores y te mantengas alerta, deberías poder seguir trabajando indemne.