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