Подтвердить что ты не робот

Способы остановить людей от загрузки GIF с инъекциями в них?

У меня есть сайт 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);
4b9b3361

Ответ 1

Что касается первого вопроса, вы никогда не узнаете, не сможете ли вы получить какие-либо журналы или изображения, о которых идет речь, потому что есть много вещей, которые эти эксплойты могут иметь целенаправленные и зависящие о том, какой целью способ был использован эксплойт в файл, может быть совершенно другим.

Изменить: W32/Graftor - это общее имя для программ, которые, как представляется, имеют трояноподобные характеристики.

После открытия файла 5060.gif в шестнадцатеричном редакторе я заметил, что программа фактически является переименованной программой Windows. Несмотря на то, что он не используется браузером и, таким образом, безвреден, если он фактически не был открыт и не выполнен, вам нужно убедиться, что он не поддерживается с типом MIME, определенным загрузчиком, потому что пользователь может все еще быть обманом в открытии программы; см. ответ на второй вопрос.

Что касается второго вопроса: чтобы предотвратить запуск какого-либо кода эксплойта или пользователя, вам необходимо убедиться, что все файлы хранятся с безопасным расширением в имени файла, чтобы они были с правильным типом MIME. Например, вы можете использовать это регулярное выражение для проверки имени файла:

if(!preg_match ( '/\\.(gif|p(sd|ng)|tiff?|jpg)$/' , $fileName)){
    header("415 Unsupported Media Type");
    die("File type not allowed.");
}

Также убедитесь, что вы обслуживаете файлы с правильным типом содержимого; убедитесь, что вы не используете тип содержимого, указанный с загруженным файлом, при обслуживании файла для пользователя. Если вы полагаетесь на Content-Type, заданный загрузчиком, файл может быть представлен как text/html или что-то подобное и будет проанализирован браузером пользователей как таковой.

Обратите внимание, что это защищает только от вредоносных файлов, использующих уязвимости в браузере пользователей, исключая анализатор изображений.

Если вы пытаетесь предотвратить эксплойты против сервера, вам нужно убедиться, что вы не позволяете парсеру PHP выполнять содержимое изображения и что библиотека изображений, которую вы используете для обработки изображения, не имеют известные уязвимости.

Также обратите внимание, что этот код не защищает вас от изображений, содержащих эксплойт для парсера изображений, используемого браузером пользователей; для защиты от этого, вы можете проверить, соответствует ли значение getimagesize() true, как предложено Jeroen.

Обратите внимание, что использование только getimagesize() недостаточно, если вы не проверяете имена файлов и убедитесь, что файлы обслуживаются с правильным заголовком Content-Type, поскольку полностью допустимые изображения могут содержать HTML/PHP-код, встроенный в комментарии.

Ответ 2

Для этого вы можете использовать функцию getimagesize(). Если изображение недействительно, оно просто вернет false.

if (getimagesize($filename)) {
    // valid image
} else {
    // not a valid image
}

Стоит отметить, что это тоже не 100% безопасно, но это лучшее, что вы можете сделать, насколько мне известно.

Подробнее об этом здесь.

Ответ 3

Вы можете попробовать phpMussel на любом php script, который принимает закачки. Файл будет сканироваться с использованием подписей ClamAV, а также некоторые внутренние эвристические подписи, которые специально предназначены для такого типа вторжений.

Ответ 4

Я не знаю много о форматах изображений, но воссоздавая изображения, а затем сохраняя результат, я чувствую, что у меня есть хороший шанс устранить ненужные хитроумные вещи. Особенно, если вы разделите все метаданные, такие как комментарии и все другие типы дополнительных встроенных полей, которые поддерживают некоторые форматы изображений.

Ответ 5

1) Вы никогда не узнаете, в чем проблема, если вы удалили .gif, и ваш A/V не записывал журнал.

Q: Вопрос .gif все еще находится на сервере?

Q: Вы проверили свои журналы A/V?

2) Существует множество различных возможных эксплойтов, которые могут иметь или не иметь ничего общего с форматом файла .gif. Вот один пример:

3) Чтобы уменьшить риск в этом примере, вы должны:

a) Загрузка файлов (любых файлов) в безопасный каталог на сервере

b) Используйте только файлы с определенными суффиксами (.gif,.png и т.д.)

c) Будьте предельно параноидальными в отношении всего, что загружено на ваш сайт (особенно если вы разрешите другим пользователям загружать его с вашего сайта!)

Ответ 6

В очень полезном совете, чтобы предотвратить проблемы с внедренным PHP, я пришел из моей администратор главной системы: у меня есть сайт, на котором люди могут загружать свой собственный контент. Я хотел убедиться, что каталог, в котором загружены загруженные изображения, не запускает никакого PHP. Таким образом, кто-то может даже опубликовать изображение под названием "test.php", и он все равно НИКОГДА не будет разбираться с PHP, если он был в каталоге загрузки. Решение было простым: в папке загруженный контент подан из следующего .htacess:

RewriteEngine On
RewriteRule \.$ - [NC]
php_flag engine off

Это отключит механизм PHP для этой папки, тем самым прекратив любую попытку запуска любого PHP для использования уязвимостей на стороне сервера.

Ответ 7

Поздний ответ, но может быть полезен для кого-то. Вы можете попробовать такой подход:

//saves filtered $image to specified $path
function save($image,$path,$mime) {
    switch($mime) {
        case "image/jpeg"   : return imagejpeg(imagecreatefromjpeg($image),$path);
        case "image/gif"    : return imagegif(imagecreatefromgif($image),$path);
        case "image/png"    : return imagepng(imagecreatefrompng($image),$path);
    }
    return false;
};