File Inclusion Prevention
Este módulo ha abordado diversas formas de detectar y explotar vulnerabilidades de inclusión de archivos, así como diferentes técnicas de evasión de seguridad y ejecución remota de código que podemos utilizar. Ahora que comprendemos cómo identificar vulnerabilidades de inclusión de archivos mediante pruebas de penetración, debemos aprender a corregirlas y reforzar nuestros sistemas para reducir la probabilidad de que se produzcan y minimizar su impacto en caso de que ocurran.
Prevención de inclusión de archivos
La medida más eficaz para reducir las vulnerabilidades de inclusión de archivos es evitar pasar cualquier entrada controlada por el usuario a las funciones o API de inclusión de archivos. La página debe poder cargar dinámicamente los recursos en el servidor, sin interacción alguna del usuario. Además, en la primera sección de este módulo, analizamos diferentes funciones que pueden utilizarse para incluir otros archivos en una página y mencionamos los privilegios de cada una. Siempre que se utilice alguna de estas funciones, debemos asegurarnos de que no se introduzca ninguna entrada del usuario directamente en ellas. Por supuesto, esta lista de funciones no es exhaustiva, por lo que, en general, debemos considerar cualquier función que pueda leer archivos.
En algunos casos, esto puede no ser factible, ya que podría requerir modificar la arquitectura completa de una aplicación web existente. En tales casos, conviene utilizar una lista blanca limitada de entradas de usuario permitidas y asociar cada entrada con el archivo que se va a cargar, manteniendo un valor predeterminado para el resto de las entradas. Si se trata de una aplicación web existente, podemos crear una lista blanca que contenga todas las rutas utilizadas en la interfaz de usuario y, a continuación, utilizarla para asociar la entrada del usuario. Dicha lista blanca puede tener diversas estructuras, como una tabla de base de datos que asocie identificadores con archivos, un case-matchscript que asocie nombres con archivos o incluso un mapa JSON estático con nombres y archivos que se pueden asociar.
Una vez implementado esto, la entrada del usuario no se introduce en la función, sino que se utilizan los archivos coincidentes en la función, lo que evita vulnerabilidades de inclusión de archivos.
Prevención del Path Trasversal
Si los atacantes logran controlar el directorio, pueden evadir la aplicación web y atacar algo con lo que estén más familiarizados o utilizar un recurso alternativo universal attack chain. Como hemos analizado a lo largo del módulo, el recorrido de directorios podría permitir a los atacantes realizar cualquiera de las siguientes acciones:
Lee
/etc/passwdy, potencialmente, encuentra claves SSH o conoce nombres de usuario válidos para un ataque de fuerza bruta contra contraseñas.Busque otros servicios en el servidor, como Tomcat, y lea el
tomcat-users.xmlarchivo.Descubra cookies de sesión PHP válidas y realice el secuestro de sesión.
Lea la configuración actual de la aplicación web y el código fuente.
La mejor manera de evitar el recorrido de directorios es usar la herramienta integrada de tu lenguaje de programación (o framework) para obtener solo el nombre del archivo. Por ejemplo, PHP tiene `filename` basename(), que lee la ruta y devuelve únicamente el nombre del archivo. Si solo se proporciona el nombre del archivo, devolverá solo eso. Si solo se proporciona la ruta, tratará lo que esté después de la barra diagonal final como el nombre del archivo. La desventaja de este método es que si la aplicación necesita acceder a algún directorio, no podrá hacerlo.
Si creas tu propia función para implementar este método, es posible que no estés considerando un caso extremo inusual. Por ejemplo, en tu terminal Bash, accede a tu directorio personal (cd ~) y ejecuta el comando cat .?/.*/.?/etc/passwd. Verás que Bash permite usar los comodines ` \` ?y `\` como argumentos . Ahora escribe ` php -l` para entrar en el intérprete de comandos de PHP y ejecuta el comando . Observarás que PHP no se comporta igual con los comodines; si reemplazas `\` y `\` por `\ `, el comando funcionará correctamente. Esto demuestra que existe un caso extremo con nuestra función anterior: si PHP ejecuta Bash con la función, un atacante podría eludir nuestra protección contra el recorrido de directorios. Si usamos funciones nativas del framework, es posible que otros usuarios detecten casos extremos como este y lo corrijan antes de que se explote en nuestra aplicación web.*.php -aecho file_get_contents('.?/.*/.?/etc/passwd');?*.system()
Además, podemos sanear la entrada del usuario para eliminar recursivamente cualquier intento de recorrer directorios, como se muestra a continuación:
while(substr_count($input, '../', 0)) {
$input = str_replace('../', '', $input);
};Como podemos ver, este código elimina ../subcadenas de forma recursiva, por lo que incluso si la cadena resultante ../la contiene, aún así la eliminaría, lo que evitaría algunas de las soluciones alternativas que intentamos en este módulo.
Configuración del servidor web
También se pueden utilizar diversas configuraciones para reducir el impacto de las vulnerabilidades de inclusión de archivos en caso de que se produzcan. Por ejemplo, conviene deshabilitar globalmente la inclusión de archivos remotos. En PHP, esto se consigue configurando `include` allow_url_fopeny ` allow_url_includeremote.include` en `Off`.
También suele ser posible restringir el acceso de las aplicaciones web a su directorio raíz, impidiendo que accedan a archivos no relacionados con la web. La forma más común de hacerlo actualmente es ejecutando la aplicación dentro de un directorio raíz Docker. Sin embargo, si esto no es posible, muchos lenguajes ofrecen mecanismos para impedir el acceso a archivos fuera del directorio raíz. En PHP, esto se logra añadiendo la línea correspondiente en el archivo php.ini. Además, conviene asegurarse de que ciertos módulos potencialmente peligrosos, como PHP Expect y mod_userdiropen_basedir = /var/www , estén deshabilitados .
Si se aplican estas configuraciones, se debería impedir el acceso a archivos fuera de la carpeta de la aplicación web, por lo que incluso si se identifica una vulnerabilidad LFI, su impacto se reduciría.
Cortafuegos de aplicaciones web (WAF)
La forma universal de reforzar la seguridad de las aplicaciones es utilizar un firewall de aplicaciones web (WAF), como ModSecurity ModSecurity. Al trabajar con WAF, lo más importante es evitar los falsos positivos y el bloqueo de solicitudes legítimas. ModSecurity minimiza los falsos positivos al ofrecer un permissivemodo que solo informa sobre las solicitudes que habría bloqueado. Esto permite a los responsables de seguridad ajustar las reglas para garantizar que no se bloquee ninguna solicitud legítima. Incluso si la organización no desea activar nunca el modo de bloqueo del WAF, el simple hecho de tenerlo en modo permisivo puede ser una señal de alerta temprana de que la aplicación está siendo atacada.
Finalmente, es importante recordar que el objetivo del fortalecimiento de la seguridad es dotar a la aplicación de una mayor protección externa, de modo que, cuando se produzca un ataque, los defensores tengan tiempo para reaccionar. Según el Informe M-Trends de FireEye de 2020 , el tiempo promedio que tardaba una empresa en detectar a los hackers era de 30 días. Con un fortalecimiento adecuado, los atacantes dejarán muchas más señales, y se espera que la organización detecte estos incidentes aún más rápidamente.
Es importante comprender que el objetivo del endurecimiento de seguridad no es hacer que el sistema sea invulnerable a los ataques, lo que significa que no se puede descuidar la monitorización de los registros en un sistema reforzado solo porque sea "seguro". Los sistemas reforzados deben someterse a pruebas continuas, especialmente después de que se publique una vulnerabilidad de día cero en una aplicación relacionada con el sistema (por ejemplo: Apache Struts, Rails, Django, etc.). En la mayoría de los casos, la vulnerabilidad de día cero funcionaría, pero gracias al endurecimiento de seguridad, puede generar registros únicos, lo que permite confirmar si se utilizó o no la vulnerabilidad contra el sistema.
Last updated