Write up SHX 3 (PHP Security) - Hello Photo
This is the last Write Up about SHX 3 from Shellter Labs.
Problem description:
Your friend asked you to verify that the new website that he is developing is secure. Can you help him?
It is also provided the link to the site to be explored, that has this appearance:
Soon after opening the site, you can see that it is an image upload site, so let’s understand how the upload process is being done, uploading any image:
After uploading the image the following page is displayed:
As shown in Fig3, the images are saved in the uploads directory, and having this information, we can try uploading a PHP file to get a shell.
When trying to upload a file in PHP with a simple “Hello World”, the application returns an error:
My first attempt to bypass this validation was to use the Burp Suite to change the Mime Type of the file at the request, but did not work, error persisted, and I realized that validation checked part of the file contents to see if it was an image, the solution was to inject a PHP code into the image content. I used GIMP to do this, but you can do this with Photoshop or even editing the file with VIM.
It was done as follows:
After that, just save and modify the extension of the image to .php and upload it back into the system. And this time it works:
After that, we have a shell ready to use, now just look for the flag by the server’s file system.
For those who are curious, I downloaded the file uploader.php and this is the unsafe code:
<?php
$imageinfo = getimagesize($_FILES['uploadedfile']['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') {
echo "Error: Please provide a valid image (GIF or JPEG).<br><br>Click <a href=\"./\">here</a> to go back.";
exit;
}
$uploaddir = 'uploads/';
$temp = explode(".", basename($_FILES['uploadedfile']['name']));
$newfilename = round(microtime(true)) . '.' . end($temp);
$uploadfile = $uploaddir . basename($_FILES['uploadedfile']['name']);
//if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploaddir . $newfilename)) {
echo "File <b>" . $newfilename . "</b> is valid, and was successfully uploaded to the uploads directory.<br><br>Click <a href=\"./\">here</a> to go back.";
} else {
echo "Oops! Something went wrong.";
}
?>
In this specific case, a possible solution to prevent PHP files from being run in the uploads folder would be to create an .htaccess and add the code:
php_flag engine off
Of course this does not guarantee 100%, but it would solve this case.
If you have found an error, have something to add or a question, comment below!