Recently the 2025 picoCTF competition was held from the 7th of March to the 17th, and with it came a lot of new and interesting challenges. Today i am taking a look at a challenge from the Web Exploitation category called SSTI1, made by VENAX.
If we look at the hint the challenge gives us, it says the following: Server Side Template Injection.
Let's ask the internet what a Server Side Template Injection is.
SSTI (Server Side Template Injection) is a vulnerability that occurs when an
attacker can inject malicious code into a template that is then executed on
the server.
Pretty simple explanation. Let us now take a look at the website the challenge provides us.
We can see a simple website with a form on it. If we write something on the form and click the Ok button, what we wrote down is then displayed on the page.
Based on what we know from the hint and what we have seen so far, we can assume that we should be able to do a Server Side Template Injection.
What happens if we try writteing down some html code on the form?
<h1>Test 1</h1> <br> <h3>Test 2</h3>
We can see that the HTML Code was executed sucessfully! Maybe we can try running some PHP code.
<?php echo execute("ls") ?>
As we can see, nothing shows up on the website. If we take a look with the inspector, we can see that php arguments get commented out, the forms contents are probably passed through a filter it seems.
Maybe there is another way for us to execute arguments. Let us search on the Internet.
After researching a bit, i found a page which explains different ways such a vulnerability can be exploited.(PayloadsAllTheThings)
... different web frameworks make use of different template engines. (Jinja2 for Python, Twig for PHP, or FreeMarker for Java)
If we try the {{7*7}} payload, the following output is shown on the site.
This is a payload used to identify the Jinja2 template engine.
Now that we know how to execute code remotely, we can look up a payload.
I found this one by Gus Ralph (OnSecurity).
{{request.application.__globals__.__builtins__.__import__('os').popen('ls').read()}}
The following jinja2 command, referring to already available python librarie os, makes use of the popen and read commands to run and catch a the response of a command, in this case, the ls command.
Success! We can now run commands on the target mashine!
As we can see on the previous picture, on the same page folder a file called "flag" is found.
If we now run the "cat flag" command on the target, we get to see the following output.
And now we have our flag!
If you took the time to read until the end, thank you so much.
I hope this walktrough helped you understand this challenge.
Stay tuned for more picoCTF walktroughs!