DVWA - File upload
A very useful aspect of PHP is the ability to manage file uploads. Allowing users to send a file opens a whole can of worms, so be careful when allowing this fonctionnality. If wrong protected it could result of a full control of the server. With DVWA you can learn effective defense.
Low
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
$html .= '<pre>';
$html .= 'Your image was not uploaded.';
$html .= '</pre>';
} else {
$html .= '<pre>';
$html .= $target_path . ' succesfully uploaded!';
$html .= '</pre>';
}
The first level is the easiest because it has absolutly no protection against malicious file upload. Choose a file - in my case a PHP shell - and submit the form:
The script has been successfully uploaded and the path displayed, now you can easily call it:
Medium
if (($uploaded_type == "image/jpeg") && ($uploaded_size < 100000)){
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
$html .= '<pre>';
$html .= 'Your image was not uploaded.';
$html .= '</pre>';
} else {
$html .= '<pre>';
$html .= $target_path . ' succesfully uploaded!';
$html .= '</pre>';
}
}
else {
echo '<pre>Your image was not uploaded.</pre>';
}
In the next level, the script checks the size of the uploaded file, which is useless because a PHP backdoor can be under 1ko, and the mime type by allowing only jpeg image, which is a good idea. If you try to upload anything else you will be faced to the following error:
To bypass this test, you need to change the mime type of the file you choosed.
There is plenty of browser extensions available to perform that kind of tricks, I personally like LiveHTTPHeaders for Firefox which is very easy to use.
After submitting your file, you can view, modify and replay the request.
Locate the Content-type
header and replace it by: image/jpeg
Submit the new request, et voilà! It works like a fucking charm!
High
if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){
if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
$html .= '<pre>';
$html .= 'Your image was not uploaded 1.';
$html .= '</pre>';
} else {
$html .= '<pre>';
$html .= $target_path . ' succesfully uploaded!';
$html .= '</pre>';
}
}
Here the check of the mime type has been replaced by an extension check. That does not mean you can only upload jpeg image but only a file with an allowed jpeg extension. Of course if you upload a PHP script renamed with a jpeg extension your browser will throw an error when trying to display the image:
It would be also possible to bypass this if you could upload an .htaccess
but there is no way in this level, it’s well secured.