Rating: 5.0

We try /foo and sure enough we see "foo" on the page. Perhaps we can include php on the page?

/ reminds us that the question mark is for get parameters. Better urlencode it.
/%3C%3Fphp%20echo%201%3B%20%3F%3E gives us nothing, but the source shows the attempt was escaped.
We got something like  back. So they are trying to blacklist commands. Blacklisting has a bad smell about it.

After a while of trying to get php to be included, we tried to switch gears and look for other server side includes.
/{{session}} worked, we get an object back. After some more fiddling, /{{session.__dict__}} proves this is python and we figure out that this looks like jinja2 templates from flask.

We try /{{url_for.__globals__}} which gives us access to some python functionality, the os module (exposed as url_for.__globals__.os) is particularly interesting to us as it allows us to explore the operating system with os.listdir. It should be noted that many things were tried, but os.open and os.popen were blocked to us and things like os.system('scp file location') would error out. Eventually we figure out that we can use flasks send_file which returns a request object, which itself can be displayed through the template with the .text attribute.

The final url ended up being: /{{url_for.__globals__.send_file('/opt/app/flag_secret_file_910230912900891283').response.text}} which yields the flag.

Original writeup (http://185.168.131.123/).