

From the briefing, I assumed it would be a SSTI.
Opened the challenge URL. Here we can design our own certificate and the parameters are rendered by the template engine.

Tried {{7*7}} to confirm whether it is evaluated by the template engine or not.

I already played some CTFs previously, so I referred a writeup to get a working payload to get RCE on the server with SSTI.
{{ cycler.__init__.__globals__.os.popen('ls').read() }}
cycleris a Jinja global/object available in the template context.cycler.__init__gives access to its initialization function.__globals__exposes the globals of that Python function.osgives access toos.popen().popen(...).read()executes the command and returns its output.

__ is blocked by the naive safety filter. Need to bypass it to get RCE.
We can build the underscore character using its ASCII code (95) like this.
The payload will look something like this.
1 | {%set u='%c'|format(95)%} |

We successfully bypassed the filter. You can see the files on the server.
Let’s read app.py to know where the flag is located on the server.


Now we know the flag is located at /flag.txt. Let’s get it with this below payload :)
1 | {%set u='%c'|format(95)%} |
