2009-01-16 19 views
7

Estoy trabajando en una página web ASP que maneja cargas de archivos. Solo se permiten subir ciertos tipos de archivos, como .XLS, .XML, .CSV, .TXT, .PDF, .PPT, etc.Averigüe el tipo de archivo real

Tengo que decidir si un archivo tiene realmente el mismo tipo que el archivo extensión muestra. En otras palabras, si un trojan.exe se renombró a inofensivo.pdf y se cargó, la aplicación debe ser capaz de descubrir que el archivo cargado NO es un archivo .PDF.

¿Qué técnicas usarías para analizar estos archivos cargados? ¿Dónde puedo obtener la mejor información sobre el formato de estos archivos?

Respuesta

3

Obtenga los encabezados de los archivos "seguros" - los ejecutables siempre tienen sus propios tipos de encabezados, y probablemente los pueda detectar. Sin embargo, debería estar familiarizado con cada formato que pretenda aceptar.

2

Sé que dijiste C#, pero esto tal vez podría ser portado. Además, tiene un archivo XML que ya contiene muchos descriptores para tipos de archivos comunes.

Es una biblioteca de Java llamada JMimeMagic. Está aquí: http://jmimemagic.sourceforge.net/

1

Tal vez podría abordar esto desde una dirección diferente. En lugar de identificar todos los tipos de archivos cargados (Excel solo me parece un desastre, porque tiene varios formatos en la actualidad), ¿por qué no ejecutar todas las cargas a través de un escáner de virus? Una gran variedad de archivos puede contener virus y troyanos. Puede ser más trabajo para su servidor, pero es la solución más segura.

Luego, corresponde a los usuarios identificar correctamente sus tipos de archivos, lo que parece razonable. Agregar un montón de código (que deberá probarse también) solo para verificar a los usuarios parece un gran paso. Si digo que es un archivo .pdf2 ¿lo cambiarás a .pdf? Si se trata de un entorno corporativo, es razonable esperar que los usuarios tengan las extensiones correctas en sus archivos. Yo rastrearía quién cargó también. Si es público, puede que valga la pena buscar los tipos de archivos, pero también debo hacer el escaneo de virus.

4

En otras palabras, si un trojan.exe se renombró a harmless.pdf y se cargó, la aplicación debe ser capaz de descubrir que el archivo cargado NO es un archivo .PDF.

Eso no es realmente un problema. Si un .exe se cargó como .pdf y lo devolvió correctamente al descargador como application/pdf, todo lo que descargue sería un PDF dañado. Tendrían que volver a escribirlo manualmente en .exe para que se dañen.

Los problemas reales son:

  1. Algunos navegadores pueden olfatear el contenido del archivo y decidir que saben más que usted acerca de qué tipo de archivo se trata. IE es particularmente malo en esto, tiende a preferir renderizar el archivo como HTML si ve alguna etiqueta HTML al acecho cerca del inicio del archivo. Esto es particularmente inútil ya que significa que el script puede ser inyectado en su sitio, potencialmente comprometiendo cualquier seguridad a nivel de la aplicación (cookie stealing et al).Las soluciones incluyen siempre servir el archivo como un archivo adjunto utilizando Content-Disposition y/o servir archivos de un nombre de host diferente, por lo que no puede cruzar el script del sitio en su sitio principal.

  2. ¡Los archivos PDF no son seguros de todos modos! Pueden estar llenos de secuencias de comandos y han tenido importantes problemas de seguridad. La explotación de un agujero en el plugin del navegador PDF es actualmente uno de los medios más comunes para instalar troyanos en la web. Y casi no se puede hacer nada para tratar de detectar los exploits, ya que pueden ser muy ofuscados.

1

En ** * NIX sistemas que tienen una utilidad llamada archivo (1). Intente encontrar algo similar para Windows, pero la utilidad de archivo si se ha portado.

0

El siguiente código C++ podría ayudarle a:

//-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; 
} 
Cuestiones relacionadas