Imagina que estás diseñando tu nueva web con toda la ilusión, utilizando todas esas plantillas que te ahorran tiempo y hacen que todo se vea bonito y ordenado.
Usas un motor de plantillas para mostrar dinámicamente los datos. Todo perfecto, ¿no? Pues no tanto, porque si no tienes cuidado, los atacantes pueden colarse por ahà y jugar con tu servidor como si fuese su patio de recreo. ¡Bienvenido al mundo del Server-Side Template Injection (SSTI)!
Básicamente, SSTI ocurre cuando los datos que ingresan los usuarios (sÃ, esos mismos que deberÃan ser inofensivos) se inyectan en las plantillas sin la debida validación. Y no hablo de cambiar el color de un botón. No, no, hablo de que un atacante podrÃa meter código malicioso en el motor de plantillas, que luego se ejecuta en tu servidor, consiguiendo asà el control total de tu máquina.
¿Cómo funciona?
Muchos motores de plantillas, como Jinja2 en Python o Twig en PHP, permiten ejecutar lógica compleja: bucles, condiciones, funciones, etc. Todo maravilloso, hasta que alguien decide explotar esta funcionalidad con fines maliciosos. Por ejemplo, un atacante podrÃa inyectar comandos que el servidor ejecuta, logrando acceso a información sensible, control del servidor o, en el peor de los casos, ejecutar código remoto. ¡Boom!
¿Qué puedes hacer para no caer en esta trampa?
Primero, como siempre en la seguridad, valida y escapa todos los datos de entrada. No confÃes en nada ni en nadie (ni siquiera en ese formulario tan inofensivo que has puesto en tu web). Además, ten mucho cuidado con las configuraciones de los motores de plantillas. Si puedes, usa plantillas que no permitan ejecutar código directamente.
En resumen, SSTI es ese ataque que convierte tus plantillas en una puerta trasera para los atacantes. Pero si sigues las buenas prácticas, puedes evitar que te conviertan en su próxima vÃctima. ¡Asà que mantén todo bajo control y no bajes la guardia!
Explotando la vulnerabilidad paso a paso
Para entender mejor esta vulnerabilidad he creado una guÃa paso a paso en la que podremos explotarla juntos, asà que vamos al lio!
Empezamos creando y arrancando el contenedor aplicando port forwarding en el puerto 8089.
Una vez montado el contenedor, si nos dirigimos a localhost por el puerto 8089 ya podemos ver la web del contenedor. Nos permite ingresar con cualquier usuario como válido sin contraseña.
Para reconocer la tecnologÃas con las cuales esta construida esta web vamos a utilizar la herramienta WhatWeb, cambiando localhost por la IP para que nos funcione el comando.
En el output del comando podemos apreciar que esta corriendo Python en su versión 3.9.13
Cuando nos encontremos ante esta situación podemos probar a poner llaves en el campo `{{}}` e indicarle `7*7` quedando en total `{{7*7}}` si en la respuesta vemos la solución a esa operación matemática es que es vulnerable a SSTI y podemos buscar maneras de inyectar comandos.Dado que es un laboratorio construido para entrenar en esta vulnerabilidad, efectivamente, vemos que nos devuelve la respuesta.
Todas estas vulnerabilidades y sus payloads podemos encontrarlas en PayloadAllTheThings ( https://github.com/swisskyrepo/PayloadsAllTheThings ) Una web que recomiendo mucho tener en favoritos.
Dado que WhatWeb nos ha devuelto que está python corriendo por detrás, una vez dentro del repositorio de SSTI vamos a python y podemos ver que hay un montón de payloads organizados por categorÃas, explotando vulnerabilidades en el lenguaje de plantillas Jinja.
Para este ejemplo vamos a mirar los payloads de inyecciones básicas.
Vamos a utilizar una linea que encontramos en esta web en el apartado de leer archivos remotos, que presuntamente nos permite leer el archivo `/etc/passwd` de la máquina vÃctima.
Pero nos devuelve un error, ese payload no nos ha funcionado. Vamos a probar con este otro pero cambiando `/tmp/flag` por `/etc/passwd` :
{{ config.items()[4][1].__class__.__mro__[2].__subclasses__()[40]("/tmp/flag").read() }}
Aunque tampoco funciona, dejo esto escrito como recordatorio de que es muy importante ir probando estos payloads prediseñados y modificándolos a nuestras necesidades.
Vamos a probar ahora con este otro:
{{ get_flashed_messages.__globals__.__builtins__.open("/etc/passwd").read() }}
... Y bingo ! Nos muestra el archivo /etc/passwd.
Personalmente he probado con `/etc/hosts` y también lo muestra!
Hice `Ctrl+U` para ver el código fuente de la página, tu también puedes hacerlo y te resultará mas cómodo ver el output de los payloads... por ahora, por que se trata de ejecutar comandos de forma remota no ? (RCE)
Vamos a ello ! En la misma web podemos encontrar un payload para tratar de ejecutar el comando id.
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
Y efectivamente funciona. Ya estamos inyectando comandos en la máquina vÃctima, y además somos root !
Para ganar acceso a la máquina y ejecutar comandos desde nuestra propia consola, podrÃamos ponernos en escucha con la herramienta NetCat por el puerto 443:
Ahora, en nuestro payload, solo debemos sustituir "id" por el clasico "oneliner" para obtener una reverse shell, con nuestra ip de atacante y por el mismo puerto que estamos escuchando por Netcat:
Y como podrás ver, ya estamos ejecutando comandos de forma remota desde nuestra propia terminal !
Es una vulnerabilidad ciertamente critica, dado que permite al atacante tomar el control total de la máquina.
Como habrás comprobado, SSTI es un ataque que convierte tus plantillas en una puerta trasera para los atacantes. Pero si sigues las buenas prácticas, puedes evitar que te conviertan en su próxima vÃctima. ¡Asà que mantén todo bajo control y no bajes la guardia!
Espero que te hayas divertido explotando el laboratorio, a mi personalmente me parece una vulnerabilidad muy divertida de explotar !
Nos vemos en la siguiente entrada ;)



