Ninja
Flask Server-Side Template Injection (SSTI)
Description
Hey guys come check out this website I made to test my ninja-coding skills.
http://web.chal.csaw.io:5000
Solution
The webpage is vulnerable to a Server-Side Template Injection (SSTI) vulnerability.
However, there are a few restrictions. Using any of the blacklisted words will yield the following error:
Sorry, the following keywords/characters are not allowed :- _ ,config ,os, RUNCMD, base
Filter Bypass
I found this excellent tutorial on how to bypass Jinja2 SSTI filters. Basically, we can pass in any of the blacklisted characters as GET request arguments, then access them through request.args.
This allows us to pass them into attr(), which is a Jinja2 built-in filter that gets an attribute of an object. foo|attr("bar") is equivalent to foo.bar.
The following payload:
/submit?value={{()|attr(request.args.c)}}&c=__class__
will result in ().__class__ being evaluated and shown to the user.
Finding subprocess.Popen
To get the subclasses, we do ().__class__.__base__.__subclasses__().
I copied the output and used the following script to find <class 'subprocess.Popen'> in the subclasses. The index was 258.
We are subsequently able to access this index to obtain RCE through subprocess.Popen.
RCE
With access to subprocess.Popen, we simply have to leverage it to achieve RCE.
Finally, cat flag.txt gives us the flag!

The flag is flag{m0mmy_s33_1m_4_r34l_n1nj4}.
Last updated
Was this helpful?