💣Ataques a CGI - Shellshock
Última actualización
Última actualización
Una interfaz de puerta de enlace común (CGI) se utiliza para ayudar a un servidor web a representar páginas dinámicas y crear una respuesta personalizada para el usuario que realiza una solicitud a través de una aplicación web. Las aplicaciones CGI se utilizan principalmente para acceder a otras aplicaciones que se ejecutan en un servidor web. CGI es esencialmente un middleware entre servidores web, bases de datos externas y fuentes de información.
Los scripts y programas CGI se guardan en el directorio /CGI-bin
de un servidor web y se pueden escribir en C, C++, Java, PERL, etc. Los scripts CGI se ejecutan en el contexto de seguridad del servidor web. A menudo se utilizan para libros de visitas, formularios (como correo electrónico, comentarios, registro), listas de correo, blogs, etc. Estos scripts son independientes del lenguaje y se pueden escribir de forma muy sencilla para realizar tareas avanzadas mucho más fáciles que escribirlas utilizando lenguajes de programación del lado del servidor.
Los scripts/aplicaciones CGI se utilizan normalmente por algunas razones:
Si el servidor web debe interactuar dinámicamente con el usuario
Cuando un usuario envía datos al servidor web al completar un formulario, la aplicación CGI procesará los datos y devolverá el resultado al usuario a través del servidor web.
A continuación se puede ver una representación gráfica de cómo funciona CGI.
En términos generales, los pasos son los siguientes:
Se crea un directorio en el servidor web que contiene los scripts/aplicaciones CGI. Este directorio normalmente se denomina CGI-bin
.
El usuario de la aplicación web envía una solicitud al servidor a través de una URL, es decir, https://acme.com/cgi-bin/newchiscript.pl
El servidor ejecuta el script y pasa el resultado al cliente web.
Existen algunas desventajas en su uso: el programa CGI inicia un nuevo proceso para cada solicitud HTTP, lo que puede ocupar mucha memoria del servidor. Cada vez se abre una nueva conexión a la base de datos. Los datos no se pueden almacenar en caché entre cargas de páginas, lo que reduce la eficiencia. Sin embargo, los riesgos y las ineficiencias superan los beneficios, y CGI no se ha mantenido al día con los tiempos y no ha evolucionado para funcionar bien con las aplicaciones web modernas. Ha sido reemplazado por tecnologías más rápidas y seguras. Sin embargo, como pentesters, nos encontraremos de vez en cuando con aplicaciones web que aún usan CGI y, a menudo, lo veremos cuando nos encontremos con dispositivos integrados durante una evaluación.
Quizás el ataque CGI más conocido es el que explota la vulnerabilidad Shellshock (también conocida como "error de Bash") a través de CGI. La vulnerabilidad Shellshock ( CVE-2014-6271 ) se descubrió en 2014, es relativamente fácil de explotar y todavía se puede encontrar en la red (durante pruebas de penetración) de vez en cuando. Es un fallo de seguridad en el shell Bash (GNU Bash hasta la versión 4.3) que se puede utilizar para ejecutar comandos no intencionados utilizando variables de entorno. En el momento del descubrimiento, era un error de 25 años de antigüedad y una amenaza importante para las empresas de todo el mundo.
La vulnerabilidad Shellshock permite a un atacante explotar versiones antiguas de Bash que guardan variables de entorno de forma incorrecta. Normalmente, al guardar una función como variable, la función de shell se detiene donde el creador la define. Las versiones vulnerables de Bash permiten a un atacante ejecutar comandos del sistema operativo que se incluyen después de una función almacenada dentro de una variable de entorno. Veamos un ejemplo sencillo en el que definimos una variable de entorno e incluimos un comando malicioso después.
Cuando se asigna la variable anterior, Bash interpretará la parte y='() { :;};'
como una definición de función para una variable y
. La función no hace nada más que devolver un código de salida 0
, pero cuando se importa, ejecutará el comando echo vulnerable-shellshock
si la versión de Bash es vulnerable. Este (o cualquier otro comando, como un comando one-liner de reverse-shell) se ejecutará en el contexto del usuario del servidor web. La mayoría de las veces, este será un usuario como www-data
, y tendremos acceso al sistema, pero aún necesitaremos escalar privilegios. Ocasionalmente, tendremos mucha suerte y obtendremos acceso como el usuario root
si el servidor web se ejecuta en un contexto elevado.
Si el sistema no es vulnerable, solo se imprimirá "not vulnerable"
.
Este comportamiento ya no ocurre en un sistema parcheado, ya que Bash no ejecutará código después de importar una definición de función. Además, Bash ya no interpretará y=() {...}
como una definición de función. En su lugar, las definiciones de función dentro de las variables de entorno ahora deben tener el prefijo BASH_FUNC_
.
Veamos un ejemplo práctico para ver cómo nosotros, como pentesters, podemos encontrar y explotar esta falla.
Podemos buscar scripts CGI usando una herramienta como Gobuster
. Aquí encontramos uno, access.cgi
.
A continuación, podemos ejecutar cURL en el script y observar que no se nos muestra nada, por lo que quizás sea un script inactivo, pero aún así vale la pena explorarlo más a fondo.
Para comprobar la vulnerabilidad, podemos utilizar un cURL
comando sencillo o utilizar Burp Suite Repeater o Intruder para fuzzear el campo user-agent. Aquí podemos ver que /etc/passwd
se nos devuelve el contenido del archivo, lo que confirma la vulnerabilidad a través del campo user-agent.
Una vez confirmada la vulnerabilidad, podemos obtener acceso al reverse shell de muchas maneras. En este ejemplo, utilizamos una línea de comandos Bash simple y obtenemos una devolución de llamada en nuestro listener Netcat:
Desde aquí, podríamos empezar a buscar datos confidenciales o intentar aumentar los privilegios. Durante una prueba de penetración de la red, podríamos intentar usar este host para adentrarnos más en la red interna.
Esta entrada del blog contiene consejos útiles para mitigar la vulnerabilidad de Shellshock. La forma más rápida de solucionar la vulnerabilidad es actualizar la versión de Bash en el sistema afectado. Esto puede ser más complicado en sistemas Ubuntu/Debian que están al final de su vida útil, por lo que un administrador de sistemas puede tener que actualizar primero el administrador de paquetes. Con ciertos sistemas (es decir, dispositivos IoT que usan CGI), la actualización puede no ser posible. En estos casos, sería mejor primero asegurarse de que el sistema no esté expuesto a Internet y luego evaluar si el host puede ser desmantelado. Si es un host crítico y la organización decide aceptar el riesgo, una solución temporal podría ser bloquear el host con un firewall en la red interna lo mejor posible. Tenga en cuenta que esto es solo poner una tirita en una herida grande y la mejor medida de acción sería actualizar o desconectar el host.
Shellshock es una vulnerabilidad heredada que ya tiene casi una década. Pero el hecho de que sea antigua no significa que no nos la encontremos de vez en cuando. Si durante sus evaluaciones encuentra alguna aplicación web que utilice scripts CGI (especialmente dispositivos IoT), definitivamente vale la pena investigar siguiendo los pasos que se muestran en esta sección. ¡Puede que tenga un punto de apoyo relativamente simple esperándolo!
Enumera el host, explota la vulnerabilidad de Shellshock y envía el contenido del archivo flag.txt ubicado en el servidor.