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.";
}
}
- Now, If I try to upload a PNG, it works fine. However, if I create a simple PHP file and try to upload it, it won’t upload as expected.
- Now, if you change the magic bytes of the PHP file and try to upload it,it is still not uploaded as we are not checking on magic bytes but on the extension.
- If I try to change the magic bytes and change the PHP file from
hello.php
tohello.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?