Вопрос

Я работаю над веб-страницей ASP, которая обрабатывает загрузку файлов. Допускается загрузка только определенных типов файлов, таких как .XLS, .XML, .CSV, .TXT, .PDF, .PPT и т. Д.

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

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

Это было полезно?

Решение

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

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

Другие советы

  

Другими словами, если файл 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;
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top