Server-side Template Injection

SSTI

Featured image

La inyección de plantillas del lado del servidor (SSTI) ocurre cuando un atacante logra insertar código dentro de una plantilla que luego es procesada por el servidor. Esto permite que el código malicioso se ejecute durante el renderizado, pudiendo comprometer por completo el sistema. La vulnerabilidad surge cuando la aplicación inserta directamente la entrada del usuario en la plantilla antes de renderizarla, o cuando el mismo contenido renderizado se vuelve a procesar, provocando que la entrada del usuario sea tratada como parte del código de plantilla.

Identificación

Para poder confirmar la vulnerabilidad se debe provocar un mensaje de error en la aplicación web con el siguiente payload.

${{<%[%'"}}%\. 

Tras identificar la posible vulnerabilidad, se debe determinar el motor de plantilla utilizado por la aplicación web a través de la siguiente tabla.

ssti7

Payloads

Ejemplo

Explotación de Twig

Para este caso tenemos ciertas funciones internas para obtener más información e incluso obtener acceso al sistema.

Divulgación de información

Con la función _self es posible obtener más información de la plantilla.

{{ _self }}

Local File Inclusion

El marco web PHP Symfony define filtros Twig adicionales y uno de estos filtros es file_excerpt que permite leer archivos locales del sistema.

{{ "/etc/passwd"|file_excerpt(1,-1) }}

Ejecución remota de comandos (RCE)

Para lograr la ejecución remota de código, podemos utilizar una función incorporada de PHP como system. Podemos pasar un argumento a esta función usando filter.

{{ ['id'] | filter('system') }}

Explotación de Jinja

Jinja es un motor de plantillas utilizado en frameworks de Python como Flask o Django. En este tipo de vulnerabilidad, el atacante puede aprovechar que Jinja permite acceder a bibliotecas ya importadas por la aplicación, tanto de forma directa como indirecta, e incluso importar nuevas mediante la instrucción import, lo que amplía su capacidad para ejecutar código malicioso en el servidor.

Divulgación de información

Es posible obtener información interna sobre el sistema, incluidos detalles de configuración e incluso el código fuente de la aplicación web.

{{ config.items() }}

También podemos obtener información sobre las funciones integradas disponibles en el código fuente.

{{ self.__init__.__globals__.__builtins__ }}

Local File Inclusion

Para explotar esta vulnerabilidad debemos utilizar la función incorporada de Python open en conjunto con __builtins__.

{{ self.__init__.__globals__.__builtins__.open("/etc/passwd").read() }}

Ejecución remota de comandos (RCE)

Para lograr la ejecución remota de comandos debemos utilizar funciones proporcionadas por el módulo os, system o popen.

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}

Se recomienda la herramienta automatizada SSTImap.

Recomendaciones

Para prevenir vulnerabilidades SSTI, es fundamental garantizar que la entrada del usuario nunca se inserte directamente en las plantillas antes del proceso de renderizado. Se debe validar y sanear toda entrada, evitando que contenga caracteres o estructuras que puedan ser interpretadas como código. Además, los datos del usuario deben pasar únicamente como valores de contexto y no como parte del código de plantilla. Es recomendable utilizar motores de plantillas configurados con opciones de seguridad activadas, eliminar funciones peligrosas como eval o import, y aislar el entorno de ejecución mediante contenedores o entornos separados.