Узнать реальный тип файла

Я работаю над веб-страницей ASP, которая обрабатывает загрузку файлов. Только определенные типы файлов могут быть загружены, например .XLS, а также .XML. ,CSV,.ФОРМАТ TXT. ,документ PDF. ,PPT, etc.

Я должен решить, действительно ли файл имеет тот же тип, что и расширение. Другими словами, если троян.exe была переименована в безобидна.формат PDF и загружено, приложение должно иметь возможность узнать ,что загруженный файл не является.файл PDF.

какие методы вы используете для анализа эти загруженные файлы? Где я могу получить лучшую информацию о формате этих файлов?

7 ответов


один из способов-проверить наличие определенных подписей или магических чисел в файлах. Эта страница имеет удобный список известных подписей файлов и кажется вполне актуальной:

http://www.garykessler.net/library/file_sigs.html


другими словами, если Трояна.exe был переименован в безвредные.pdf и загружено, приложение должно иметь возможность узнать ,что загруженный файл не является.файл PDF.

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

реальные проблемы являются:

  1. некоторые браузеры могут понюхать содержимое файла и решить, что они знают лучше, чем вы, о том, какой тип файла это. IE особенно плох в этом, предпочитая отображать файл как HTML, если он видит какие-либо теги HTML, скрывающиеся около начала файла. Это особенно бесполезно, так как это означает, что скрипт может быть введен на ваш сайт, потенциально угрожая безопасности любого уровня приложения (cookie stealing et al). Обходные пути включают всегда обслуживание файла как вложение с использованием Content-Disposition и / или обслуживания файлов из другого имени хоста, поэтому он не может вернуться на ваш основной сайт.

  2. PDF-файлы в любом случае не безопасно! Они могут быть полны сценариев и иметь значительные дыры в безопасности. Использование дыры в плагине браузера PDF reader в настоящее время является одним из наиболее распространенных средств установки троянов в интернете. И вы почти ничего не можете сделать, чтобы попытаться обнаружить подвиги, как их можно сильно запутать.


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


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

это библиотека Java под названием JMimeMagic. Это здесь: http://jmimemagic.sourceforge.net/


на* * NIX * системах у нас есть утилита под названием (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;
}