Узнайте реальный тип файла
-
19-08-2019 - |
Вопрос
Я работаю над веб-страницей ASP, которая обрабатывает загрузку файлов. Допускается загрузка только определенных типов файлов, таких как .XLS, .XML, .CSV, .TXT, .PDF, .PPT и т. Д.
Я должен решить, действительно ли файл имеет такой же тип, как показано в расширении. Другими словами, если trojan.exe был переименован в mageless.pdf и загружен, приложение должно быть в состоянии определить, что загруженный файл НЕ является файлом .PDF. р>
Какие методы вы бы использовали для анализа этих загруженных файлов? Где я могу получить лучшую информацию о формате этих файлов?
Решение
Один из способов - проверить наличие определенных подписей или магических номеров в файлах. На этой странице есть удобный список известных сигнатур файлов, и он выглядит довольно актуально:
Другие советы
Другими словами, если файл trojan.exe был переименован в файлlessless.pdf и загружен, приложение должно выяснить, что загруженный файл НЕ является файлом .PDF.
Это на самом деле не проблема. Если файл .exe был загружен в формате .pdf, и вы правильно подали его обратно в загрузчик как application / pdf, загрузчик получит только поврежденный PDF. Им придется вручную набрать его в .exe, чтобы получить вред.
Реальные проблемы:
<Ол>Некоторые браузеры могут прослушивать содержимое файла и решать, что они знают лучше, чем вы, о типе файла. В IE это особенно плохо, он предпочитает отображать файл как HTML, если он видит какие-либо HTML-теги, скрывающиеся в начале файла. Это особенно бесполезно, так как это означает, что скрипт может быть внедрен на ваш сайт, потенциально ставя под угрозу любую безопасность на уровне приложения (cookie-кража и др.). Обходные пути включают в себя всегда обработку файла в качестве вложения с использованием Content-Disposition и / или обслуживание файлов с другого имени хоста, чтобы он не мог выполнять межсайтовый скрипт обратно на ваш основной сайт.
PDF-файлы в любом случае не безопасны! Они могут быть полны сценариев и имеют значительные дыры в безопасности. Использование дыры в плагине браузера для чтения PDF-файлов в настоящее время является одним из наиболее распространенных способов установки троянов в Интернете. И вы почти ничего не можете сделать, чтобы попытаться обнаружить эксплойты, поскольку они могут быть сильно запутаны.
Получить заголовки файлов " safe " типы файлов - исполняемые файлы всегда имеют свои собственные типы заголовков, и вы, вероятно, можете их обнаружить. Однако вы должны быть знакомы с каждым форматом, который вы намереваетесь принять.
Я знаю, что вы сказали C #, но это может быть перенесено. Кроме того, в нем есть файл XML, уже содержащий множество дескрипторов для общих типов файлов.
Это библиотека Java, которая называется JMimeMagic. Это здесь: http://jmimemagic.sourceforge.net/
В системах ** NIX * у нас есть утилита file (1) . Попробуйте найти что-то похожее для Windows, но файловую утилиту, если self был портирован.
Может быть, вы могли бы подойти к этому с другой стороны. Вместо того, чтобы идентифицировать все типы файлов, которые загружаются (один Excel для меня кажется беспорядком, потому что он имеет несколько форматов в наши дни), почему бы не запустить все загрузки через антивирусный сканер ? Большое разнообразие файлов может содержать вирусы и трояны. Это может быть больше работы для вашего сервера, но это самое безопасное решение. Р>
Тогда пользователи должны правильно определить типы файлов, что кажется разумным. Добавление большого количества кода (который также должен быть протестирован) просто для двойной проверки ваших пользователей кажется большим шагом. Если я скажу, что это файл .pdf2, вы переименуете его в .pdf? Если это в корпоративной среде, то разумно ожидать, что пользователи будут иметь правильные расширения в своих файлах. Я бы отследил, кто что загрузил. Если это общедоступно, тогда может быть целесообразно выполнить сканирование на наличие типов файлов, но я бы также сделал проверку на вирусы. Р>
Вам может помочь следующий код C ++:
//-1 : File Does not Exist or no access
//0 : not an office document
//1 : (General) MS office 2007
//2 : (General) MS office older than 2007
//3 : MS office 2003 PowerPoint presentation
//4 : MS office 2003 Excel spreadsheet
//5 : MS office applications or others
int IsOffice2007OrOlder(wchar_t * fileName)
{
int iRet = 0;
byte msgFormatChk2007[8] = {0x50, 0x4B, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00}; //offset 0 for office 2007 documents
byte possibleMSOldOffice[8] = {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}; //offset 0 for possible office 2003 documents
byte msgFormatChkXLSPPT[4] = {0xFD, 0xFF, 0xFF, 0xFF}; // offset 512: xls, ppt: FD FF FF FF
byte msgFormatChkOnlyPPT[4] = {0x00, 0x6E, 0x1E, 0xF0}; // offset 512: another ppt offset PPT
byte msgFormatChkOnlyDOC[4] = {0xEC, 0xA5, 0xC1, 0x00}; //offset 512: EC A5 C1 00
byte msgFormatChkOnlyXLS[8] = {0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00}; //offset 512: XLS
int iMsgChk = 0;
HANDLE fileHandle = CreateFile(fileName, GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL );
if(INVALID_HANDLE_VALUE == fileHandle)
{
return -1;
}
byte buff[20];
DWORD bytesRead;
iMsgChk = 1;
if(0 == ReadFile(fileHandle, buff, 8, &bytesRead, NULL ))
{
return -1;
}
if(buff[0] == msgFormatChk2007[0])
{
while(buff[iMsgChk] == msgFormatChk2007[iMsgChk] && iMsgChk < 9)
iMsgChk++;
if(iMsgChk >= 8) {
iRet = 1; //office 2007 file format
}
}
else if(buff[0] == possibleMSOldOffice[0])
{
while(buff[iMsgChk] == possibleMSOldOffice[iMsgChk] && iMsgChk < 9)
iMsgChk++;
if(iMsgChk >= 8)
{
//old office file format, check 512 offset further in order to filter out real office format
iMsgChk = 1;
SetFilePointer(fileHandle, 512, NULL, FILE_BEGIN);
if(ReadFile(fileHandle, buff, 8, &bytesRead, NULL ) == 0) { return 0; }
if(buff[0] == msgFormatChkXLSPPT[0])
{
while(buff[iMsgChk] == msgFormatChkXLSPPT[iMsgChk] && iMsgChk < 5)
iMsgChk++;
if(iMsgChk == 4)
iRet = 2;
}
else if(buff[iMsgChk] == msgFormatChkOnlyDOC[iMsgChk])
{
while(buff[iMsgChk] == msgFormatChkOnlyDOC[iMsgChk] && iMsgChk < 5)
iMsgChk++;
if(iMsgChk == 4)
iRet = 2;
}
else if(buff[0] == msgFormatChkOnlyPPT[0])
{
while(buff[iMsgChk] == msgFormatChkOnlyPPT[iMsgChk] && iMsgChk < 5)
iMsgChk++;
if(iMsgChk == 4)
iRet = 3;
}
else if(buff[0] == msgFormatChkOnlyXLS[0])
{
while(buff[iMsgChk] == msgFormatChkOnlyXLS[iMsgChk] && iMsgChk < 9)
iMsgChk++;
if(iMsgChk == 9)
iRet = 4;
}
if(0 == iRet){
iRet = 5;
}
}
}
CloseHandle(fileHandle);
return iRet;
}