Basic server-side template injection (code context) | Dec 23, 2022
Introduction
Welcome to my another writeup! In this Portswigger Labs lab, you’ll learn: Basic server-side template injection (code context)! Without further ado, let’s dive in.
- Overall difficulty for me (From 1-10 stars): ★☆☆☆☆☆☆☆☆☆
Background
This lab is vulnerable to server-side template injection due to the way it unsafely uses a Tornado template. To solve the lab, review the Tornado documentation to discover how to execute arbitrary code, then delete the morale.txt
file from Carlos’s home directory.
You can log in to your own account using the following credentials: wiener:peter
Exploitation
Home page:
First, let’s detect is there any Server-Side Template Injection vulnerability.
Post comment:
Based on my experience, some comments functionality in a web page, it might be using some template engine to render users’ comment.
Let’s try to fuzz that via Burp Suite!
Nope. I don’t think it’s vulnerable to SSTI.
Let’s login as user wiener
:
In here, we can pick our preferred name.
Let’s try to submit it:
When we clicked Submit
button, it’ll send a POST request to /my-account/change-blog-post-author-display
, with parameter blog-post-author-display
and csrf
.
Let’s try to post a comment in one of those blog posts:
As you can see, when we posted a new comment, our name will be rendered via the template!
Since the username can be controlled by an attacker, it might vulnerable to SSTI.
The template code might be:
blog-post-author-display = getQueryParameter('blog-post-author-display')
engine.render("Hello \{\{"+blog-post-author-display+"\}\}", data)
If in that case, we can just close the template syntax: }}
.
Let’s try it:
It worked!
Let’s do some maths:
user.name}}-SSTI payload…{{7*7}}
Note: The payload is URL encoded.
Nice!
Next, we need to which template engine is using.
To do so, we can trigger an error:
{{trigger_error}}
In the error message, it’s displaying a template engine called tornado
, which is written in Python!
After Identified the template engine, we can go to the exploitation session!
In the Tornado documentation, we can import modules:
Since I’m quite familiar with Python, I knew that we can import a module called os
, which allows us to execute OS commands!
Payload:
{\% import os \%}{{os.system(“cmd_here”)}}
Nice! Let’s delete morale.txt
file:
{\% import os \%}{{os.system(“ls”)}}
{\% import os \%}{{os.system(“rm morale.txt”)}}
We did it!
What we’ve learned:
- Basic server-side template injection (code context)