Los motores de plantillas se utilizan ampliamente en aplicaciones web para combinar HTML y datos y generar visualizaciones. Por ejemplo, se utilizan en el backend para incrustar nombres de usuario, contenido de publicaciones, etc. en HTML.
los valores de entrada del usuario se incluyen directamente en dicho procesamiento de plantillas , se puede evaluar toda la sintaxis de la plantilla. Esta vulnerabilidad se conoce como "SSTI (inyección de plantillas del lado del servidor)".
Si se produce una SSTI, dependiendo del tipo de motor de plantillas, existe el riesgo de que pueda provocar el acceso a variables internas o, en el peor de los casos, la ejecución arbitraria de comandos del sistema operativo (RCE). En particular, en sistemas basados en Python, Jinja2
y Mako
tienen una implementación vulnerable, pueden convertirse en una puerta de entrada conveniente para los atacantes.
Mako
el tema de esta verificación , es uno de los motores de plantillas comúnmente utilizados en Python, pero también es propenso a incrustar accidentalmente la entrada del usuario directamente
Veremos un ejemplo concreto para ver cómo se puede explotar esta vulnerabilidad en una aplicación real.
📹: ¡También puedes ver cómo se hace en la práctica en YouTube!
- ¡La sensación de escritura nítida exclusiva del sistema capacitivo sin contacto!
- ¡El primer dispositivo inalámbrico de REALFORCE! ¡También disponible con conexión por cable!
- A diferencia del HHKB, la distribución del teclado japonés no tiene peculiaridades y es fácil de usar para cualquiera.
- Equipado con una rueda para el pulgar, ¡el desplazamiento horizontal es muy fácil!
- ¡También tiene un excelente rendimiento de reducción de ruido, lo que lo hace silencioso y cómodo!
- ¡El desplazamiento se puede cambiar entre el modo de alta velocidad y el modo de trinquete!
Acerca de HackTheBox
Esta vez, utilizamos HackTheBox (HTB) para verificar vulnerabilidades.
HackTheBox es una plataforma práctica de CTF donde los participantes pueden practicar en diversas áreas de seguridad, incluyendo aplicaciones web, servidores y redes.
Su principal ventaja es que los participantes pueden aprender accediendo a las máquinas y aplicaciones que serán atacadas y poniéndose manos a la obra.
es una de las categorías de desafío que se ofrecía anteriormente en HackTheBox y actualmente solo es accesible para usuarios con un plan VIP o superior
También hay máquinas y desafíos en una variedad de categorías, incluidas Web, Reversing, Pwn y Forensics, para que puedas abordarlos en un nivel que se adapte a ti.
Si quieres perfeccionar seriamente tus habilidades con HackTheBox, asegúrate al plan VIP y aprovechar al máximo las máquinas y los desafíos anteriores.
👉 Visita el sitio web oficial de HackTheBox aquí
👉 Para obtener información detallada sobre cómo registrarse en HackTheBox y las diferencias entre los planes, haga clic aquí.

Resumen del desafío: Spookifier
El desafío que abordamos esta vez, " Spookifier está clasificado en la categoría Web de HackTheBox está configurado en MUY FÁCIL
A primera vista, la aplicación es muy sencilla: un servicio web que simplemente convierte y muestra el texto en diferentes estilos de fuente al introducirlo. A primera vista, no parece presentar vulnerabilidades de seguridad.
Sin embargo, la aplicación el motor de plantillas Python "Mako", y la cadena ingresada por el usuario se evaluó directamente dentro de la plantilla.
Esta falla de diseño puede llevar a la inyección de plantillas del lado del servidor (SSTI) y, en última instancia, a la ejecución de comandos arbitrarios (RCE)
👉 https://app.hackthebox.com/challenges/Spookifier
Puntos de desafío
- Tecnologías utilizadas: Python, Flask, Mako
- Comportamiento notable: la entrada se muestra en múltiples fuentes
- Vector de ataque: Entrada no saneada en la plantilla → SSTI
- Objetivo: recuperar banderas de
/flag.txt
De esta manera, detrás de la funcionalidad que parece segura en la superficie una debilidad en el proceso de evaluación de plantillas , y la estructura permite experimentar un "patrón típico de SSTI a RCE".
Hacking en la práctica: de SSTI a RCE
A partir de aquí, probaremos la aplicación y buscaremos vulnerabilidades.
Si la plantilla se maneja de forma descuidada, podría convertirse en una puerta de entrada para un ataque.
Verificaremos la validez de la SSTI y, en última instancia, buscaremos RCE.
Exploración 1: Primero prueba la aplicación
Primero, acceda a la aplicación de destino y verifique qué funciones tiene y qué entrada acepta
La pantalla tiene un formulario de entrada simple y parece tener solo la función de "ingresar texto, convertirlo a una fuente decorada y mostrarlo".
La apariencia y la estructura son muy simples, sin funciones de autenticación ni enrutamiento complejo.

Es importante destacar la cadena introducida por el usuario se procesa de alguna manera y se muestra como una plantilla .
Parece que, durante el proceso de visualización en múltiples fuentes, la cadena está siendo manipulada por un motor de plantillas.

Verifiqué la información de la solicitud usando devtools, pero no parece haber ninguna información significativa allí.

Reconocimiento 2: Identificación del motor de plantillas a partir del código fuente
Al investigar vulnerabilidades en aplicaciones web reales, rara vez se tiene acceso al código fuente.
Las pruebas de penetración y las recompensas por errores se basan en pruebas de caja negra (observación del comportamiento desde el exterior).
Por lo tanto, normalmente comprobamos la presencia de un motor de plantillas y si existen vulnerabilidades a través del siguiente proceso.
- En el campo de texto, pruebe alguna sintaxis de plantilla común como
${7*7}
,{{7*7}}
,<%= 7*7 %>
- el resultado muestra
49
o7*7
- Cualquier error de plantilla o resultado de evaluación inusual puede proporcionar pistas al motor de plantillas.
- Infiera el motor de plantilla utilizado a partir de su salida y comportamiento (Mako, Jinja2, Twig, etc.)
Esta vez, el código fuente se proporcionó como un desafío especial destinado a aprender sobre las vulnerabilidades,
lo que me permitió examinar directamente la estructura interna y comprender rápidamente cómo funciona el procesamiento de plantillas.
En el código fuente proporcionado, puede encontrar la siguiente descripción de representación de la plantilla:
desde mako.template importar Plantilla ... devolver Plantilla(resultado).render()
Esta oración muestra claramente que
Mako se utiliza como motor de plantillas Mako es un motor de plantillas de Python, y la sintaxis ${...}
se evalúa directamente como una expresión de Python, lo que supone un riesgo de SSTI (inyección de plantilla del lado del servidor)
intentará evaluar ${}
en la entrada del usuario
Ahora que sabemos que Mako se utiliza como motor de plantillas, el siguiente paso a verificar es
${}
en la cadena ingresada por el usuario se evalúa realmente como una expresión de plantilla , que es el primer paso para determinar si existe SSTI (inyección de plantilla del lado del servidor).
intente ingresar la sintaxis de plantilla básica de Mako, ${7*7},
${7*7}
Si el motor de plantilla evalúa esta entrada como una expresión, debería generar el número
49.
Por el contrario, si no se evalúa y se trata como una cadena, simplemente se mostrará en la pantalla como ${7*7}
Cuando lo envié, apareció el siguiente mensaje en la pantalla:

El resultado 49
el ${7*7}
ingresado por el usuario ha sido evaluado por el motor de plantillas (Mako).
En otras palabras, Mako procesa la entrada del usuario como una plantilla y se confirmó que SSTI estaba en vigor.
Intrusión: Verificar RCE ⇒ Intenta ver hasta dónde puedes ejecutarlo desde la fórmula de plantilla
Con SSTI confirmado, nuestro próximo objetivo fue claro:
ver si podíamos aprovechar las expresiones de plantilla para ejecutar código arbitrario en el lado del servidor (RCE)
Confirmación de ejecución del comando
Primero, probemos si podemos ejecutar un comando del sistema operativo desde una expresión de plantilla.
Para comprobarlo, usaremos el sencillo comando whoami
${__import__('os').popen('whoami').read()}
Cuando envié esta fórmula, obtuve el siguiente resultado:

El resultado de la ejecución de whoami
muestra root
lo que confirma que cualquier comando del sistema operativo se puede ejecutar a través de una expresión de plantilla y que el comando se ejecuta con privilegios de root
En este punto, está claro que existe una vulnerabilidad de ejecución remota de código (RCE), que permite a un atacante ejecutar comandos con privilegios elevados
Comprobando la lectura del archivo
Ahora que sabemos que podemos ejecutar comandos, podemos comprobar
si podemos leer algún archivo Un ejemplo típico /etc/passwd
, común en entornos Linux.
${open('/etc/passwd').read()}
La salida incluía información del usuario, como:

Este resultado muestra que
es posible llamar a open()
de Python , lo que le brinda control total sobre las operaciones de lectura en el servidor.
Ejecución: Búsqueda y obtención de banderas
Hasta ahora, a través de la inyección de plantillas
- Ejecución de código Python
- Ejecutar comandos del sistema operativo
- Lectura arbitraria de archivos
Esto significa que se ha logrado una ejecución remota de código (RCE) completa .
El siguiente paso encontrar el archivo de bandera de destino y recuperar su contenido .
Encuentra la ubicación del archivo de la bandera
Primero, veamos el contenido del directorio raíz /
y veamos qué directorios y archivos hay allí.
${__import__('os').listdir('/')}

Como puedes ver, está bien si puedes encontrar el archivo deseado ( flag.txt
), pero si no puedes encontrarlo, tendrás que buscar más profundamente en home
o root
Leyendo la bandera
Si la búsqueda encuentra un archivo como /flag.txt
open()
para recuperar su contenido:
${open('/flag.txt').read()}
Cuando ejecuté esta expresión, obtuve el siguiente resultado:

Obtuvimos
la bandera, que era el objetivo final del desafío HackTheBox Gracias a este proceso, pudimos comprender mejor hasta qué punto se puede explotar la vulnerabilidad SSTI mediante pruebas reales.
¿Por qué se produjo esta vulnerabilidad? Cómo usar las plantillas de forma segura
La causa principal de esta vulnerabilidad (SSTI → RCE) el uso inapropiado del motor de plantillas
En particular, el lado de Python construyó dinámicamente cadenas de plantillas que contienen la entrada del usuario , lo que conduce a la inyección de plantilla (SSTI) y eventual ejecución remota de código (RCE).
Solución: No pase cadenas dinámicas a las plantillas
Uno de los patrones típicos en los que ocurre SSTI (inyección de plantilla del lado del servidor)
cuando se construye una cadena en Python y luego se evalúa como una plantilla .
Crear cadenas de plantilla usando str.format()
, como en el código a continuación,
def generate_render(fuentes_convertidas): resultado = '''<tr><td> {0}</td></tr><tr><td> {1}</td></tr><tr><td> {2}</td></tr><tr><td> {3}</td></tr> '''.format(*converted_fonts) devuelve Plantilla(resultado).render()
Por ejemplo, turned_fonts
contiene la siguiente entrada de usuario:
${__import__('os').popen('id').read()}
Pasar esta plantilla a Mako crea una vulnerabilidad grave Mako evaluará ${...}
Uso seguro: Separar la estructura de la plantilla de los datos
Para evitar este problema, es importante
separar la estructura de la plantilla de la entrada del usuario (variables) Puedes solucionarlo de forma segura pasando variables explícitamente a render()
, como se muestra a continuación:
def generate_render(fuentes_convertidas): plantilla = '''<tr><td> ${font1}</td></tr><tr><td> ${font2}</td></tr><tr><td> ${font3}</td></tr><tr><td> ${font4}</td></tr> ''' return Template(plantilla).render( fuente1=fuentes_convertidas[0], fuente2=fuentes_convertidas[1], fuente3=fuentes_convertidas[2], fuente4=fuentes_convertidas[3] )
Con este método, font1
a font4
contienen ${}
, Mako las tratará como cadenas normales y no las evaluará como expresiones de plantilla.

${...}
de Mako evalúa expresiones dentro de plantillas
y, si la entrada del usuario se pasa textualmente, existe el riesgo de ejecución del código.
Por otro lado, si se pasan variables explícitamente mediante
Template(...).render(var=value)
En este caso, var }
puede usarse sin problemas como marcador de posición en la plantilla , pero no se ejecutará como código.
Resumen: Las SSTI son vulnerabilidades causadas por "hábitos de uso".
En este desafío "Spookifier", el manejo inadecuado de las plantillas Mako
nos permitió explotar una vulnerabilidad que condujo a la inyección de plantillas del lado del servidor (SSTI) y, en última instancia, a la ejecución remota de código (RCE).
Estas vulnerabilidades se deben a
errores de implementación de los desarrolladores, Son especialmente peligrosas cuando las cadenas de plantilla se construyen dinámicamente.
Para utilizar motores de plantillas de forma segura:
- Separe siempre las plantillas y los datos (variables)
- Pasar variables como marcadores de posición y no evaluar expresiones
- No pase entradas no confiables directamente a las plantillas
Con solo seguir estos principios básicos se pueden prevenir muchas infecciones de transmisión sexual.
👉 Para obtener información detallada sobre cómo registrarse en HackTheBox y las diferencias entre los planes, haga clic aquí.
