In this blog, we are going to discuss on Server-Side Template Injection (SSTI) vulnerability and its exploitation.

Before directly getting into the details of SSTI and exploitation, let us first see what templates are and why they are used in modern web applications.

What is template and its use?

A Web template is a system that comprises the template engine, data stream, and template resource as specified by the template language. The main work of this template is to automatically generate custom or dynamic web pages based on the supplied input parameter or values.

The template engine generates data in useful content-type like in HTML and using programming language features such as conditional statements and loops helps in output manipulation.

After processing user-supplied data, this data will be directly inserted into a predefined template like an HTML page having all the styles and functionality.

Many developers use this feature of web templates in various content management systems, web applications, etc.

Basic working of web templates

Fig: 1.0 Basic working of web templates

Template engines differ based on the programming language which is being used in the framework. Some of the popular template engines used in building web applications are,

  • Twig- PHP based template engine.
  • Jinja2- Python based template engine used in frameworks like Django.
  • Mako- Python based template engine.
  • ERB- Ruby based template engine.
  • Freemarker- JAVA based template engine for dynamic web page generation.

 

What is Server-Side Template Injection Vulnerability?

Server-side template injection is when an attacker can use native template syntax to inject a malicious payload into a template as an input, which is then executed server-side.

Template engines are designed to generate web pages by combining fixed templates with dynamic data. Server-side template injection vulnerability occurs when a user input is concatenated directly into a template, rather than passed in as data which is properly validated and sanitized.

Server-side template injection attack scenario

Fig: 2.0 Server-side template injection attack scenario

 

How to test for Server-Side Template Injection (SSTI) Vulnerability?

To test for server-side template injection vulnerability

  • Simplest initial approach would be to try fuzzing the template by injecting a sequence of special characters commonly used in template expressions, such as ${{<%[%'”}}%\ .

 

  • While fuzzing for Server-side template injection vulnerability if an error related to template is encountered then there is a possibility of Server-side template injection.

 

  • Next step is to identify which template engine is being used. This can be easily done using below mentioned flow chart (Fig:3.0) by trying different payloads and deciding whether there is a possibility if that template engine is being used.

E.g.

  • If payload {{ 7*7 }} gives response as 49 try to use {{ 7*’7’ }} payload . If it properly executes then it will show 7 printed 7 times i.e., 7777777.
  • Thismeans that the template engine used in the application will be either Jinja2 or Twig.
  • Similarly,<%= 7*7 %> if this payload gives response of the mentioned mathematical operation as 49, then the template used might be ERB template engine which uses ruby programming language.

 

  • Another way to identify/guess template engine is identifying which programming language and web application framework is used for the development purpose.

E.g.

  • If PHP is used for backend, then It might use template engine like SMARTY,Twig, etc.

 

  • Once the used template engine has been successfully identified, the next step would be to go through documentation of that template engine.

 

  • Documentation always has enough information regarding template engine and how to make proper use of it.

 

  • Check in the documentation if there is any method or function which could be used to fetch critical information or execute system related commands. If yes, then the severity of this vulnerability would be critical.

 

How to identify which template engine is used?

To identify which template engine is used in target application there are few key points to keep in mind.

  1. It is easy to identify template engine used in the target application based on the content management system and web application framework.

E.g.

  • Django framework used in development of modern and dynamic application make use of mostly Jinja2 template engine.
  • Ruby on rails framework uses ERB as its main template engine for rendering views.
  • Net framework mostly make use of razor as its template engine.

 

  1. Another way of identifying template engine is to check which programming language is used in the back end like PHP, JAVA, Python etc.

E.g.

  • If the application is making use of JAVA as a back-end programming language, then there is high probability that they might be making use of velocity,free-maker template engine for generating dynamic content.
  • If python is used then it may be using MAKO, Jinja2, and Tornado etc. as its template engine.

 

  1. Most easy way is to try fuzzing on the parameters which might be vulnerable. Below shown flow chart (Fig: 3.0)depicts how one can start with fuzzing approach.
  • It starts with basic payload to check if the mathematical operation is executing.
  • If yes, proceed with the rightside shown for further clarity on template engine identification.
  • If no, then follow left side to check for other possibilities of template engines.

Using all the above-mentioned tricks and techniques, it becomes easy for identification of template engine.

After template engine has been identified successfully, the next step would be to check if there is any way to exploit this vulnerability with maximum impact by making use of template engine documentation.

Flow Chart showing all the template engine detection payloads

Fig: 3.0 Flow Chart showing all the template engine detection payloads

 

Exploitation Scenario’s for Server-side template injection Vulnerability

 

In this section we will be discussing about the exploitation of server-side template injection vulnerability. For demonstration purpose we will be using burp web-security academy lab.

This demo application has a blog functionality where a user can comment on the existing blogs. Also, in user profile section user can choose which name he wants to display when commented on a blog post.

  • Select preferred name and click on save.

Application functionality to update name

Fig:4.0 Application functionality to update name

  • Capture this request in burp suite and send it to repeater.

Request sent to repeater

Fig:4.1 Request sent to repeater

  • Now add simple template injection payload in blog-post-author-display parameterand forward the request.

Payload:}}{{7*7}}

inserting simple payload

Fig: 4.2 inserting simple payload

  • Click on follow redirect and refresh your browser.

Response after pressing follow redirect

Fig: 4.3 Response after pressing follow redirect

  • Now go to home section and add a new comment on existing blog post. SSTI payload should execute and give result as your username followed by 49 after adding comment.

Payload executed successfully

Fig:4.4 Payload executed successfully

Now to further exploit this vulnerability first we need to identify which template engine is used in this application.

  • Try fuzzing this parameter with special characters which might throw an error disclosing information regarding template engine.

Insert special characters to generate error message

Fig: 4.5 Insert special characters to generate error message

  • As we can see this application is making use of tornado template engine. This template engine makesuse of python as its core programming language.

Disclosing template engine information

Fig: 4.6 Disclosing template engine information

Now by referring documentation of this template engine we can import system related module in python like OS, system etc. to perform command injection.

In tornado template engine to import a python module following syntax is used.

{%  importmodule_name %}

And to execute a statement following syntax is used:

{{ expression }}

For achieving remote code execution using all the available information, the final payload will be:

{% import os%}{{os.system(‘cat /etc/passwd’)}}

In above payload, first python module osis imported in a syntax mentioned above. After that using expression evaluation syntax we make use of system method available inosmodule to run system commands.

Payload for remote code execution submitted

Fig:4.7 Payload for remote code execution submitted

Payload executes, showing content of /etc/passwd file

Fig:4.8 Payload executes, showing content of /etc/passwd file

 

Mitigation

  • One of the simplest ways to avoid introducing server-side template injection vulnerabilities is to always use a “logic-less” template engine, such as Mustache.
  • Use sandbox environment to execute code where dangerous modules will not make much damage.
  • Proper validation and sanitization of user input by removing unwanted characters before using them in template. This reduces the possibility of this vulnerability.

 

References

https://portswigger.net/web-security/server-side-template-injection

https://www.we45.com/blog/server-side-template-injection-a-crash-course-

https://0x1.gitlab.io/web-security/Server-Side-Template-Injection/

 

Author,

Gaurish Kauthankar

Attack & Pentest Team

Varutra Consulting Pvt. Ltd.