Exploiting File Upload Vulnerabilities with DVWA
This exercise explores vulnerabilities associated with file uploads. The target machine was the Damn Vulnerable Web Application (DVWA) found at http://www.dvwa.co.uk/ however, this web application came preinstalled with Metasploitable 2 found at https://information.rapid7.com/metasploitable-download.html.
DVWA, according to its website, “is a PHP/MySQL web application that is damn vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, help web developers better understand the processes of securing web applications and aid teachers/students to teach/learn web application security in a classroom environment” (http://www.dvwa.co.uk/).
Metasploitable “is virtual machine based on Linux that contains several intentional vulnerabilities for you to exploit. Metasploitable is essentially a penetration testing lab in a box, available as a VMware virtual machine (VMX),” (https://information.rapid7.com/metasploitable-download.html).
The attacker machine used, as always, was Kali Linux, found at https://www.kali.org. For this exploit, I opted to use VirtualBox from Oracle instead of the Microsoft Hyper-V platform. VirtualBox can be downloaded from https://www.virtualbox.org/wiki/Downloads.
For this test, it was paramount to ensure that both Kali and Metasploitable were running on the same NAT network. To check, I simply ran the ifconfig command, as both machines run on Linux. However, in order to authenticate to Metasploitable, I had to login using the default username and password msfadmin.
Next, I navigated to 10.0.2.4 in the web browser to access Metasploitable.
Once open, I navigated to the DVWA page. I was directed to the login page. The default username is admin and the default password is password.
Next, I navigated to the upload page to see if I was able to successfully upload an image to the server.
Using Weevely (a tool that comes preinstalled in the Kali Linux distribution, I created a backdoor shell command. According to the Kali Linux documentation, “Weevely is a stealth PHP web shell that simulate telnet-like connection. It is an essential tool for web application post exploitation, and can be used as stealth backdoor or as a web shell to manage legit web accounts, even free hosted ones” (https://tools.kali.org/maintaining-access/weevely). The command syntax is as follows: weevely generate <password> <location to save file to>. Once this command was executed, a success message below the command appeared.
The first test for this exploit was done with the DVWA security settings set to low.
I then went back to the Upload page and uploaded the created PHP file generated by weevely.
Once this file was successfully upload, I opened a terminal back in the attacker system (Kali) and ran the following command: weevely <Target URL to Uploaded File> <password>. The results showed that the connection was made and I was able to successfully run commands on the target server.
I decided to see if I could have the same success with increased security settings on DVWA. I set the security settings to medium and tried to repeat the process.
I tried to upload the PHP file in the same manner and it failed.
I decided to use Burp Suite to see if I could manipulate the file type and successfully upload the PHP file. First, I changed the shell.php file to shell.jpg.
I followed by uploading the file to the server with the intercept feature on. Below is the results before the filename was changed in the header using Burp Suite. The following image shows where the filename was modified back to shell.php before forwarding to the server.
Once manipulated, I forwarded the request and it was successfully uploaded to the server.
Following the same methods before to test for connectivity, I was able to successfully send commands to the target server.
Lastly, I set the security settings to high to test and see if I would be able to follow the same steps to successfully upload the PHP file as I did with medium settings.
My first attempt was not successful. Looking at the source code showed that the settings were checking to ensure that the filename had an image file extension. I decided to manipulate the filename by adding a .jpg to the end. Instead of just changing the filename to shell.php like I did with the medium security settings, I renamed the file shell.php.jpg.
Once forwarded, the file was successfully uploaded.
Going back to weevely, I was able to successfully execute commands on the target machine.
To mitigate against these types of exploitations, first, ensure a user is never permitted to upload executable files (i.e. PHP, EXE, etc.). Additionally, ensure that both the file types AND the file extensions are thoroughly inspected and sanitized for any undesirable types and/or extensions. Lastly, close analysis of the uploaded file itself could prove extremely beneficial. Recreate the file and rename it for closer inspection.
The source code below, called impossible.php, implements these recommendations. It checks to ensure that the file extension is limited to image file file extensions as well as ensures that the image type itself is an image. Also, it uses a PHP library to strip any metadata associated with the user uploaded image, creates a new file with a new file name, ensures that the file extension is of an image file type, and lastly, deletes the user uploaded file from the server. The source code can be seen below and can also be found at https://github.com/ethicalhack3r/DVWA/blob/master/vulnerabilities/upload/source/impossible.php.
<?php
| |
if( isset( $_POST[ 'Upload' ] ) ) {
| |
// Check Anti-CSRF token
| |
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
| |
$uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
| |
$uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
| |
// Where are we going to be writing to?
| |
$target_path = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
| |
//$target_file = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
| |
$target_file = md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
| |
$temp_file = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
| |
$temp_file .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
| |
// Is it an image?
| |
if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&
| |
( $uploaded_size < 100000 ) &&
| |
( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
| |
getimagesize( $uploaded_tmp ) ) {
| |
// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
| |
if( $uploaded_type == 'image/jpeg' ) {
| |
$img = imagecreatefromjpeg( $uploaded_tmp );
| |
imagejpeg( $img, $temp_file, 100);
| |
}
| |
else {
| |
$img = imagecreatefrompng( $uploaded_tmp );
| |
imagepng( $img, $temp_file, 9);
| |
}
| |
imagedestroy( $img );
| |
// Can we move the file to the web root from the temp folder?
| |
if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
| |
// Yes!
| |
$html .= "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";
| |
}
| |
else {
| |
// No
| |
$html .= '<pre>Your image was not uploaded.</pre>';
| |
}
| |
// Delete any temp files
| |
if( file_exists( $temp_file ) )
| |
unlink( $temp_file );
| |
}
| |
else {
| |
// Invalid file
| |
$html .= '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
| |
}
| |
}
| |
// Generate Anti-CSRF token
| |
generateSessionToken();
| |
?>
|
Comments
Post a Comment