I am learning file upload bypass mechanisms in PHP, which include multiple techniques, such as bypassing extensions, mime types, and adding magic bytes.
I have a simple script (copied from chatGPT) that validates the extension.
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["file"]["name"]);
$imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
$check = getimagesize($_FILES["file"]["tmp_name"]);
$allowedTypes = ['jpg', 'jpeg', 'gif', 'png'];
print_r($imageFileType);
echo "Response: ". in_array($imageFileType, $allowedTypes);
if (in_array($imageFileType, $allowedTypes)) {
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
echo "file=" . urlencode($target_file);
} else {
http_response_code(500);
echo "Sorry, there was an error uploading your file.";
}
} else {
http_response_code(400);
echo "File is not an image or not allowed.";
}
}
hello.php
to hello.php.png
, it uploads fine.But when I try to access the file using localhost/hello.php.png, it is still rendered as a png instead of a PHP.
What is missing here? I see online tutorials where if we upload the file by changing hello.php.png it will be treated as a PHP as the magic bytes are PNG but the file is actually PHP. Am I missing something?
To have hello.php.png
executed as PHP script you need that your web server is configured to do so. One possible way is to use Apache HTTP Server and use the AddHandler
directive to identify scripts:
AddHandler application/x-httpd-php .php
or:
AddType application/x-httpd-php php
As documentation warns:
The extension argument is case-insensitive and can be specified with or without a leading dot. Filenames may have multiple extensions and the extension argument will be compared against each of them.
For that reason, the PHP manual recommends this other mechanism:
Tell Apache to parse certain extensions as PHP. For example, let's have Apache parse .php files as PHP. Instead of only using the Apache AddType directive, we want to avoid potentially dangerous uploads and created files such as exploit.php.jpg from being executed as PHP. Using this example, you could have any extension(s) parse as PHP by simply adding them. We'll add .php to demonstrate.
<FilesMatch \.php$> SetHandler application/x-httpd-php </FilesMatch>
So this is basically a specific exploit on a specific vulnerable setup.