Ответ 1
Существует не один шаг или полный прямой способ использовать ваш код, но вот некоторые мысли.
Вы передаете его в copy()
в этом примере, но вы упомянули, что используете этот метод для проверки файла ext awhile now, поэтому я предполагаю, что у вас были другие случаи, которые могли использовать эту процедуру для других функций тоже для разных PHP-версии.
Рассмотрим это как тестовую процедуру (Exploiting include, require):
$name = "test.php#.txt";
if (preg_match('/\.(xml|csv|txt)$/i', $name) && preg_match('/\.(asp|jsp|php)$/i', $name) == false) {
echo "in!!!!";
include $name;
} else {
echo "Invalid data file";
}
Это закончится печатью "in!!!!" и выполнение "test.php", даже если оно будет загружено, оно будет включать его из папки tmp - конечно, что в этом случае вы уже являетесь владельцем злоумышленника, но также рассмотрите эти варианты. Это не общий сценарий для процедуры загрузки, но это концепция, которая может быть использована путем объединения нескольких методов:
Перемещение вперед - если вы выполните:
//$_FILES['image']['name'] === "test.php#.jpg";
$name = $_FILES['image']['name'];
if (preg_match('/\.(jpeg|jpg|gif|png|bmp|jpe)$/i', $name) && preg_match('/\.(asp|jsp|php)$/i', $name) == false) {
echo "in!!!!";
copy($_FILES['image']['tmp_name'], "../uploads/".$name);
} else {
echo "Invalid image file";
}
Снова отлично. Файл скопирован в папку "uploads" - вы не можете получить к нему доступ напрямую (поскольку веб-сервер будет вырезать правую сторону #), но вы ввели файл, и злоумышленник может найти способ или другую слабую точку для вызова это позже.
Пример такого сценария выполнения распространен среди сайтов совместного доступа и хостинга, где файлы обслуживаются PHP script, который (в некоторых небезопасных случаях) может загрузить файл, включив его с неправильным типом функций, таких как require
, include
, file_get_contents
, которые все уязвимы и могут выполнять файл.
NULL-байт Атаки с нулевым байтом были большой слабостью в php < 5.3, но был повторно введен регрессией в версиях 5.4+ в некоторых функциях, включая все связанные с файлом функции и многое другое в расширениях. Он был исправлен несколько раз, но он все еще там, и многие старые версии все еще используются. Если вы работаете со старой версией php, вы определенно Exposed:
//$_FILES['image']['name'] === "test.php\0.jpg";
$name = $_FILES['image']['name'];
if (preg_match('/\.(jpeg|jpg|gif|png|bmp|jpe)$/i', $name) && preg_match('/\.(asp|jsp|php)$/i', $name) == false) {
echo "in!!!!";
copy($_FILES['image']['tmp_name'], "../uploads/".$name);
} else {
echo "Invalid image file";
}
Будет напечатан "in!!!!" и скопируйте файл с именем "test.php".
Как исправлено php, проверяя длину строки до и после передачи ее более глубокой процедуре C, которая создает фактический массив char, и тем самым, если строка усечена нулевым байтом (что указывает на конец строки в C) длина не будет соответствовать. читать больше
Как ни странно, даже в исправленных и современных версиях PHP он все еще там:
$input = "foo.php\0.gif";
include ($input); // Will load foo.php :)
Мой вывод:
Ваш метод проверки расширений файлов может быть значительно улучшен - ваш код позволяет пропустить PHP файл с именем test.php#.jpg
, пока он не должен. Успешные атаки в основном выполняются путем объединения нескольких уязвимостей даже младших - вы должны рассматривать любые неожиданные результаты и поведение как один.
Примечание: есть еще много проблем с именами файлов и картинками, потому что они много раз включены в страницы позже, и если они не фильтруются правильно и включены безопасно, вы подвергаете себя еще многим материалам XSS но это не по теме.