TryHackMe — Upload Vulnerabilities Room — Complete Beginner Pathway
Tutorial room exploring some basic file-upload vulnerabilities in websites
Room Link: https://tryhackme.com/room/uploadvulns
Note: This room is for Premium Members Only. who purchased THM premium membership.
Pre-Requisites: If you are new to Penetration Testing / Ethical Hacking, and have not followed along this path thus far, I recommend starting with the “Pre-Security” pathway located here: https://tryhackme.com/paths.
Task 1: Getting Started
To start the challenge, we will deploy our VM using the “start machine” button in the top right of Task 1. This next step is imperative: Once you’ve clicked deploy, you’ll need to configure your own computer to be able to connect.
(Note: This is an abnormal step for a TryHackMe machine, but must be completed in order to access the practical content of this room)
If you’ve successfully deployed the machine then the following commands will already have the IP address filled in. If any of them have “MACHINE_IP” in them, then you still need to deploy the machine, and the following instructions will not work.
Linux or MacOS: open a terminal, copy and paste the following command (with your machine IP substituted for “Machine IP”):
echo “MACHINE IP overwrite.uploadvulns.thm shell.uploadvulns.thm java.uploadvulns.thm annex.uploadvulns.thm magic.uploadvulns.thm jewel.uploadvulns.thm demo.uploadvulns.thm” | sudo tee -a /etc/hosts
When you finish the room, run this command to revert the hosts file back to normal:
sudo sed -i '$d' /etc/hosts
Windows: run Powershell as an Admin & enter the following command:
AC C:\Windows\System32\drivers\etc\hosts “10.10.185.200 overwrite.uploadvulns.thm shell.uploadvulns.thm java.uploadvulns.thm annex.uploadvulns.thm magic.uploadvulns.thm jewel.uploadvulns.thm demo.uploadvulns.thm"
When finished, use this command to revert back to normal:
(GC C:\Windows\System32\drivers\etc\hosts | select -Skiplast 1) | SC C:\Windows\System32\drivers\etc\hosts
It is important to use the remove command every time you restart your machine & never use the add common a second time if you haven’t already used the remove command.
Once you have done this, the machine should be set up and ready for you to use! Let’s get into it…
Task 2: Introduction
This task is simple, just read the content in the task and truly understand it. Once understood, click complete and move on!
Task 3: General Methodology
This task is also simple, just read the content and understand it. Once understood, click complete and move on!
Task 4: Overwriting Existing Files
In this task, we learn how to use the page source to determine if client-side filtering is on & where images are being loaded from. Once we determine that, we grab an image from the internet, name it the same as the image on the page, and upload it. If successful, we should now see our image loaded. Done! When it is your time to perform this, navigate to
overwrite.uploadvulns.thm NOT the IP address of your VM.
Read the content of the task and follow along with the walkthrough.
Answer the questions below
What is the name of the image file which can be overwritten?
Overwrite the image. What is the flag you receive?
Task 5: Remote Code Execution
In this task we will attempt to upload a file to create either a web-shell or reverse-shell to capture the flag on the machine.
For the go-buster scan, I recommend using the wordlist located on default kali installs at the following path: /usr/share/wordlists/dirb/common.txt. So the command would be:
gobuster dir -u http://overwrite.uploadvulns.thm -w /usr/share/wordlists/dirb/common.txt
See the instructions and demo below!
It’s all well and good overwriting files that exist on the server. That’s a nuisance to the person maintaining the site, and may lead to some vulnerabilities, but let’s go further; let’s go for RCE!
Remote Code Execution (as the name suggests) would allow us to execute code arbitrarily on the web server. Whilst this is likely to be as a low-privileged web user account (such as
There are two basic ways to achieve RCE on a webserver: webshells, and reverse shells. Realistically a fully featured reverse shell is the ideal goal for an attacker; however, a webshell may be the only option available (for example, if a file length limit has been imposed on uploads). We’ll take a look at each of these in turn. As a general methodology, we would be looking to upload a shell of one kind or another, then activating it, either by navigating directly to the file if the server allows it, or by otherwise forcing the webapp to run the script for us.
Let’s assume that we’ve found a webpage with an upload form:
Where do we go from here? Well, let’s start with a gobuster scan:
Looks like we’ve got two directories here —
assets. Of these, it seems likely that any files we upload will be placed in the "uploads" directory. We'll try uploading a legitimate image file first. Here I am choosing our cute dog photo from the previous task:
Now, if we go to
http://demo.uploadvulns.thm/uploadswe should see that the spaniel picture has been uploaded!
Ok, we can upload images. Let’s try a webshell now.
As it is, we know that this webserver is running with a PHP back-end, so we’ll skip straight to creating and uploading the shell. In real life, we may need to do a little more enumeration; however, PHP is a good place to start regardless.
A simple webshell works by taking a parameter and executing it as a system command. In PHP, the syntax for this would be:
This code takes a GET parameter and executes it as a system command. It then echoes the output out to the screen.
Let’s try uploading it to the site, then using it to show our current user and the contents of the current directory:
We could now use this shell to read files from the system, or upgrade from here to a reverse shell. Now that we have RCE, the options are limitless. Note that when using webshells, it’s usually easier to view the output by looking at the source code of the page. This drastically improves the formatting of the output.
The process for uploading a reverse shell is almost identical to that of uploading a webshell, so this section will be shorter. We’ll be using the ubiquitous Pentest Monkey reverse shell, which comes by default on Kali Linux, but can also be downloaded here. You will need to edit line 49 of the shell. It will currently say
$ip = '127.0.0.1'; // CHANGE THIS-- as it instructs, change
127.0.0.1to your TryHackMe tun0 IP address, which can be found on the access page. You can ignore the following line, which also asks to be changed. With the shell edited, the next thing we need to do is start a Netcat listener to receive the connection.
nc -lvnp 1234:
Now, let’s upload the shell, then activate it by navigating to
http://demo.uploadvulns.thm/uploads/shell.php. The name of the shell will obviously be whatever you called it (
The website should hang and not load properly — however, if we switch back to our terminal, we have a hit!
Once again, we have obtained RCE on this webserver. From here we would want to stabilise our shell and escalate our privileges, but those are tasks for another time. For now, it’s time you tried this for yourself!
shell.uploadvulns.thmand complete the questions for this task.
Task 5 Answers
Answer the questions below
Run a Gobuster scan on the website using the syntax from the screenshot above. What directory looks like it might be used for uploads? (remember the gobuster scan I put above!)
(N.B. This is a good habit to get into, and will serve you well in the upcoming tasks…)
Get either a web shell or a reverse shell on the machine. What’s the flag in the /var/www/ directory of the server?
For this one, I had some issues. Whenever I uploaded my script, it wouldn’t appear in the /resources directory. I tried terminating my VM and restarting it multiple times. Eventually, it worked after one time I used the remove command:
sudo sed -i '$d' /etc/hosts & then re-did the original command to create the virtual hosts.
Eventually, I got it to upload, and then all you do is set up your netcat listener using
nc -lvnp 1234 & then click on the file in the /resources directory. Flag acquired!
Task 6: Filtering
This task is again a rather easy one, as it just asks you to read & understand the content, with 3 questions to quiz your understanding.
Answer the questions below
What is the traditionally predominant server-side scripting language?
When validating by file extension, what would you call a list of accepted extensions (whereby the server rejects any extension not in the list)?
[Research] What MIME type would you expect to see when uploading a CSV file?
Task 7: Bypassing Client-Side Filtering
Read & understand the content in the task.
Important things to note for this task: these virtual hosts work better in the In-Browser “AttackBox” than they do with a local machine. I have found myself and others have struggled to connect to the virtual hosts when running purp as a proxy.
Connect to the site (important you specify “http://”):
Start with a gobuster scan:
gobuster dir -u http://java.uploadvulns.thm -w /usr/share/wordlists/dirb/common.txt
Boom! We found the /assets folder & the /images folder. What can we do with these? Well we can perform client-side filter bypass OR MIME/File Extension bypass. I will go through both:
Connect to the site with Burp Intercept On, and make sure you have edited the burp settings to intercept .js files.
Once done, load the site and in the request in Burp, select “Do Intercept Response”
Once completed, you can intercept the response and remove the client-side script.
Once the script is removed, just upload the shell.php file and then go to the /images folder to select it. Don’t forget to set up your NetCat listener on the same port!
Alternatively, you can change the file extension to .jpg for the shell file & intercept the upload request to the site using Burp. Once intercepted, change the MIME back to “text/x-php” and the extension back to .php. Then forward that request to the site & the file should be in the /images directory!
Answer the questions below
What is the flag in /var/www/?