BOOK THIS SPACE FOR AD
ARTICLE ADIn this blog post, we’ll dive into Server-Side Template Injection (SSTI) vulnerabilities by exploring a practical lab exercise provided by PortSwigger. SSTI is a powerful and dangerous vulnerability that allows attackers to execute arbitrary code on a server by injecting malicious templates. In this guide, we’ll demonstrate how to identify the vulnerability, craft a custom exploit, and gain control over the target system.
To begin, let’s check the settings to see which functions are available by logging in with the credentials: username wiener and password peter.
As you can see, there are three functions available, but we’ll be concentrating on the second and third ones.
Let’s attempt to identify the SSTI vulnerability. Start by modifying the “Preferred name” field while keeping Burp Suite’s interception enabled, then examine the captured request.
As you can see, there are two distinct parameters, but we’ll be focusing on the first one, “blog-post-author-display.”
Based on the value user.name, it appears to be referencing a variable pointing to the username. Let's attempt injecting a simple payload to check if it's vulnerable to injection.
I’ll inject the payload without the curly brackets since they aren’t present in the request, suggesting that the brackets might be utilized on the back-end.
After sending the request, nothing changed in my account’s settings. However, if you notice the parameter name, the payload actually gets executed in the “name” section of the post’s comments.
Now, let’s navigate to any post, submit a comment, and check how it appears to see the result of our payload.
Success! As you can see, we received the result 64, which confirms that 8*8 was correctly evaluated.
Now, let’s figure out how we can proceed to achieve the objective of deleting Carlos’s SSH private key.
Now that we’ve confirmed the SSTI vulnerability, let’s identify the template engine by intentionally causing an error. I’ll change the “Preferred name” to something that could trigger an exception. For instance, I’ll change it to the object user to intentionally cause an error.
After submitting the request, I’ll return to the post where I left the comment and refresh the page.
Perfect! We received an error that confirms the template engine in use is Twig.
When attempting to inject any RCE payloads to delete the file, none of them seemed to work. However, we noticed something different this time — why does this lab include an avatar upload feature? Since Twig is often used with PHP, let’s try uploading a simple PHP reverse shell to see if we can leverage it.
After uploading the file, we encountered an error, but this time it’s different from the previous ones.
This error is incredibly helpful because it reveals that the user object has a function called setAvatar with two arguments: the path of the avatar to be set and its MIME type.
Given that we previously confirmed the SSTI vulnerability, let’s try leveraging the setAvatar function by using it on the file path "/etc/passwd".
After submitting the request, we encountered an error!
The error indicates that the MIME type needs to be an image format.
Let’s adjust the MIME type to "image/png" to match the requirement for an image.
After submitting the request, we navigated back to the post where we left our comment. Upon refreshing the page, no errors appeared.
However, upon inspecting the page, instead of seeing the /etc/passwd content as the avatar, we only see a default SVG image.
This is happening because we haven’t set a normal avatar for our account. To fix this, we can generate an empty image for testing by executing the following Linux command:
convert -size 1x1 xc:white test.png
Let’s upload the generated image
and submit the request to set /etc/passwd as the avatar.
Next, refresh the commented post, right-click on the avatar image, and copy the image link.
After that, use the curl command on the copied image URL to view its contents:
HOORAY! As you can see, we are now able to view the file’s content by setting it as an avatar and using the `curl` command to retrieve it.
Now, let’s leverage this attack to complete our objective by deleting the `.ssh/id_rsa` file from Carlos’s home directory.
First, let’s use this attack to view the source code of the `user` object. We can extract the file path information from the error we encountered earlier when trying to upload a PHP file. which is /home/carlos/User.php
submit the request and let’s do the attack again
important note: You’ll need to refresh the comment section for the SSTI payload to take effect.
After refreshing, we can see all the functions of the user object. One of these functions is gdprDelete, which deletes the avatar's path. This is exactly what we need to achieve our objective:
The final step is to set the path "/home/carlos/.ssh/id_rsa" using the setAvatar function, and then simply delete it with the gdprDelete function.
Let’s refresh the commented page and then invoke the gdprDelete function. And just like that, we’ve successfully solved the lab!
Conclusion
And that’s a wrap! We’ve successfully exploited the Server-Side Template Injection (SSTI) vulnerability to achieve Remote Code Execution and fulfill the lab objective of deleting Carlos’s SSH private key. This walkthrough demonstrated the power of SSTI and how a creative approach can lead to system compromise, even when traditional methods fail.
By exploring different avenues like the avatar upload feature and leveraging internal functions, we were able to transform a seemingly simple vulnerability into a full-fledged attack. This lab is a great reminder of why it’s crucial to think outside the box and fully understand the application’s behavior.
If you enjoyed this walkthrough, stay tuned for more write-ups on advanced vulnerabilities and techniques. As always, happy hacking, and keep pushing the boundaries of what’s possible!
Thank you for reading! 🚀