У меня есть сайт PHP, где люди могут заполнять справочные билеты. Это позволяет им загружать скриншоты для своего билета. Я разрешаю загружать gif, psd, bmp, jpg, png, tif. После получения загрузки PHP script игнорирует расширение файла. Он идентифицирует тип файла, используя только информацию MIME, которая для этих типов файлов всегда хранится в первых 12 байтах файла.
Кто-то загрузил несколько GIF файлов, которые при просмотре в браузере в браузере сказали, что он недействителен, и мой антивирусный сканер предупредил меня, что это была инъекция (или что-то в этом роде). См. Ниже для zip файла, содержащего эти GIF файлы.
Я не думаю, что проверка информации заголовка достаточно. Я слышал, что изображение может быть полностью допустимым, но также содержать код эксплойта.
Итак, у меня есть два основных вопроса:
- Кто-нибудь знает, как они ввели плохие вещи в GIF (сохраняя при этом действительный тип MIFE GIF)? Если я это знаю, возможно, я смогу проверить его во время загрузки.
- Как я могу запретить кому-то загружать такие файлы?
- Я нахожусь на общем хостинге, поэтому я не могу установить серверный вирус сканер.
- Отправка информации на веб-сайт сканирования вирусов онлайн может быть слишком медленным.
- Есть ли способ проверить себя с помощью класса PHP, который проверяет эти вещи?
- Изменяет размер изображения с помощью GD, если он недействителен? Или эксплойт все же проскользнет и окажется в измененном изображении? Если это не удастся, это было бы идеально, потому что тогда я мог бы использовать изменение размера как метод, чтобы убедиться, что они действительны.
Обновление:. Все, спасибо за ответ. Я пытаюсь посмотреть на сервере для загруженных GIF файлов. Я буду обновлять этот пост, если найду их.
Обновление 2: Я нашел GIF для всех, кого это интересует. Я поместил их в zip файл, зашифрованный паролем "123". Он расположен здесь (будьте осторожны, есть несколько кнопок "Загрузить" на этом хостинговом сайте - некоторые из них предназначены для рекламы) http://www.filedropper.com/badgifs. Мой защищенный вирус 5060.gif отмечен как троянец (TR/Graftor.Q.2). Я должен отметить, что эти файлы были загружены до того, как я осуществил проверку MIME первых 12 байтов. Итак, теперь я в безопасности для этих конкретных. Но я все равно хотел бы знать, как обнаружить эксплойт, скрывающийся за правильным типом MIME.
Важное пояснение: Меня беспокоит только риск для ПК, который загружает эти файлы, чтобы посмотреть на них. Файлы не являются риском для моего сервера. Они не будут выполнены. Они сохраняются с использованием чистого имени (шестнадцатеричный хэш-вывод) с расширением ".enc", и я сохраняю их на диск в зашифрованном состоянии с помощью фильтра fwrite:
// Generate random key to encrypt this file.
$AsciiKey = '';
for($i = 0; $i < 20; $i++)
$AsciiKey .= chr(mt_rand(1, 255));
// The proper key size for the encryption mode we're using is 256-bits (32-bytes).
// That what "mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)" says.
// So we'll hash our key using SHA-256 and pass TRUE to the 2nd parameter, so we
// get raw binary output. That will be the perfect length for the key.
$BinKey = hash('SHA256', '~~'.TIME_NOW.'~~'.$AsciiKey.'~~', true);
// Create Initialization Vector with block size of 128 bits (AES compliant) and CBC mode
$InitVec = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$Args = array('iv' => $InitVec, 'key' => $BinKey, 'mode' => 'cbc');
// Save encoded file in uploads_tmp directory.
$hDest = fopen(UPLOADS_DIR_TMP.'/'.$Hash.'.enc', 'w');
stream_filter_append($hDest, 'mcrypt.rijndael-128', STREAM_FILTER_WRITE, $Args);
fwrite($hDest, $Data);
fclose($hDest);