asp classic - programacion - Descubre el tipo de archivo real
historia de asp (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.
Debo decidir si un archivo realmente tiene el mismo tipo que muestra la extensión. En otras palabras, si se cambió el nombre de un trojan.exe a inofensivo.pdf y se lo 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?
En otras palabras, si se cambió el nombre de un trojan.exe a inofensivo.pdf y se lo 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 verdaderos problemas son:
Algunos navegadores pueden olfatear el contenido del archivo y decidir que saben mejor que usted sobre qué tipo de archivo es. 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.
¡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.
El siguiente código de C ++ podría ayudarlo 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;
}
En los sistemas ** NIX * tenemos una utilidad llamada archivo (1) . Intente encontrar algo similar para Windows, pero la utilidad de archivo si se ha portado.
Obtenga los encabezados de archivo de los tipos de archivos "seguros": los ejecutables siempre tienen sus propios tipos de encabezados y probablemente pueda detectarlos. Sin embargo, debería estar familiarizado con cada formato que pretenda aceptar.
Sé que dijiste C #, pero esto 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/
Tal vez podrías acercarte a esto desde una dirección diferente. En lugar de identificar todos los tipos de archivos que se cargan (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, depende de 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.
Una forma sería verificar si hay ciertas firmas o números mágicos en los archivos. Esta página tiene una lista práctica de firmas de archivos conocidas y parece bastante actualizada: