Contents

[picoCTF 2025] SSTI1

SSTI1 is a beginner-friendly web challenge where you learn how to trick a website into running hidden code by taking advantage of how it builds its pages.

Announcement Homepage
Announcement Homepage

I tested the vulnerability by inputting {{7 * 7}}, which is a typical template expression in Flask using Jinja2.

7 times 7 using template expression using Jinja2
7 times 7 using template expression of Jinja2

The application returned 49, the result of 7 * 7, confirming that it is using Jinja2 and is vulnerable to Server-Side Template Injection (SSTI).

Product of 7 times 7
Product of 7 times 7

The website is vulnerable to Server Side Template Injection

Note

As per OWASP, Server Side Template Injection vulnerabilities (SSTI) occur when user input is embedded in a template in an unsafe manner and results in remote code execution on the server.

I used a payload to identify the location of the flag. I discovered that the flag is located at /challenge/flag.

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('find / -name flag 2>/dev/null').read() }}

  • self.init.globals — enables access to the self object’s global variables through the init method. This is a method for accessing Python’s internal workings.
  • .builtins — python’s built-in functions and modules, such as open(), eval(), import(), and others, are accessed from the globals.
  • .import(‘os’) — accesses operating system capabilities by importing the OS module using the built-in import() function.
  • .popen(‘find / -name flag 2>/dev/null’) — carries out a shell command using os.popen(). This command searches the file system for any files with the name flag.
    • find / -name flag — Looks for a file with the name flag beginning at the root /
    • 2>/dev/null — suppresses error notifications (such as permission denied)

Location of the Flag
Location of the Flag

Now that I knew where the flag was, I modified the payload to read the contents of the flag directly.

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('cat /challenge/flag').read() }}

picoCTF{s4rv3r_s1d3_t3mp14t3_1nj3ct10n5_4r3_c001_99fe4411}