Domanda

Sto lavorando su una pagina Web ASP che gestisce i caricamenti di file. È consentito caricare solo determinati tipi di file, come .XLS, .XML, .CSV, .TXT, .PDF, .PPT, ecc.

Devo decidere se un file ha davvero lo stesso tipo mostrato dall'estensione. In altre parole se un trojan.exe è stato rinominato in harmless.pdf e caricato, l'applicazione deve essere in grado di scoprire che il file caricato NON è un file .PDF.

Quali tecniche useresti per analizzare questi file caricati? Dove posso ottenere le migliori informazioni sul formato di questi file?

È stato utile?

Soluzione

Un modo sarebbe quello di verificare alcune firme o numeri magici nei file. Questa pagina ha un pratico elenco di firme di file conosciute e sembra abbastanza aggiornata:

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

Altri suggerimenti

  

In altre parole, se un trojan.exe è stato rinominato in harmless.pdf e caricato, l'applicazione deve essere in grado di scoprire che il file caricato NON è un file .PDF.

Questo non è davvero un problema. Se un .exe è stato caricato come .pdf e lo hai correttamente inviato al downloader come application / pdf, tutto il downloader sarebbe un PDF rotto. Dovrebbero riscriverlo manualmente in .exe per essere danneggiato.

I veri problemi sono:

  1. Alcuni browser potrebbero annusare il contenuto del file e decidere di conoscere meglio di te il tipo di file. IE è particolarmente dannoso in questo, tendendo a preferire il rendering del file come HTML se vede qualche tag HTML in agguato vicino all'inizio del file. Ciò è particolarmente inutile in quanto significa che gli script possono essere iniettati sul tuo sito, compromettendo potenzialmente qualsiasi sicurezza a livello di applicazione (cookie stealing et al). Le soluzioni alternative includono sempre la pubblicazione del file come allegato utilizzando Content-Disposition e / o la pubblicazione di file con un nome host diverso, in modo che non possa tornare indietro nel tuo sito principale.

  2. I file PDF non sono comunque sicuri! Possono essere pieni di script e hanno avuto falle di sicurezza significative. Lo sfruttamento di un buco nel plug-in del browser del lettore PDF è attualmente uno dei mezzi più comuni per l'installazione di trojan sul web. E di solito non puoi fare nulla per cercare di rilevare gli exploit in quanto possono essere altamente offuscati.

Ottieni le intestazioni dei file di " safe " tipi di file: gli eseguibili hanno sempre i propri tipi di intestazioni e probabilmente li puoi rilevare. Dovresti conoscere ogni formato che intendi accettare, tuttavia.

So che hai detto C #, ma questo potrebbe forse essere portato. Inoltre, ha già un file XML che contiene molti descrittori per tipi di file comuni.

È una libreria Java chiamata JMimeMagic. È qui: http://jmimemagic.sourceforge.net/

Sui sistemi ** NIX * abbiamo un'utilità chiamata file (1) . Prova a trovare qualcosa di simile per Windows, ma l'utilità del file se self è stato portato.

Forse potresti avvicinarti da un'altra direzione. Invece di identificare tutti i tipi di file che vengono caricati (Excel da solo mi sembra un disastro, perché al giorno d'oggi ha diversi formati), perché non eseguire tutti i caricamenti tramite uno scanner antivirus ? Un'ampia varietà di file può contenere virus e trojan. Potrebbe essere più lavoro per il tuo server, ma è la soluzione più sicura.

Quindi spetta agli utenti identificare correttamente i loro tipi di file, il che sembra ragionevole. Aggiungere un sacco di codice (che dovrà essere testato anche solo) solo per ricontrollare i tuoi utenti sembra un grande passo. Se dico che è un file .pdf2, lo rinominerai in .pdf? Se questo è in un ambiente aziendale, è ragionevole aspettarsi che gli utenti abbiano le estensioni corrette sui loro file. Tracciai anche chi ha caricato cosa. Se è pubblico, la scansione per i tipi di file potrebbe essere utile, ma farei anche la scansione dei virus.

Il seguente codice C ++ potrebbe aiutarti:

//-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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top