Asp classic 找出真正的文件类型

Asp classic 找出真正的文件类型,asp-classic,analysis,file-type,Asp Classic,Analysis,File Type,我正在一个ASP网页上处理文件上传。只允许上载某些类型的文件,如.XLS、.XML、.CSV、.TXT、.PDF、.PPT等 我必须决定一个文件是否真的与扩展名显示的类型相同。换句话说,如果特洛伊木马.exe重命名为无害.pdf并上载,应用程序必须能够发现上载的文件不是.pdf文件 您将使用什么技术来分析这些上传的文件?在哪里可以获得有关这些文件格式的最佳信息?获取“安全”文件类型的文件头-可执行文件总是有自己的头类型,您可能可以检测到这些头类型。但是,您必须熟悉您想要接受的每种格式。一种方法是

我正在一个ASP网页上处理文件上传。只允许上载某些类型的文件,如.XLS、.XML、.CSV、.TXT、.PDF、.PPT等

我必须决定一个文件是否真的与扩展名显示的类型相同。换句话说,如果特洛伊木马.exe重命名为无害.pdf并上载,应用程序必须能够发现上载的文件不是.pdf文件


您将使用什么技术来分析这些上传的文件?在哪里可以获得有关这些文件格式的最佳信息?

获取“安全”文件类型的文件头-可执行文件总是有自己的头类型,您可能可以检测到这些头类型。但是,您必须熟悉您想要接受的每种格式。

一种方法是检查文件中的某些签名或幻数。此页面有一个方便的已知文件签名列表,似乎是最新的:

我知道你说的是C#,但这可能是移植的。此外,它还有一个XML文件,其中已经包含许多常见文件类型的描述符


这是一个名为JMimeMagic的Java库。它在这里:

也许你可以从另一个方向来处理这个问题。与其识别上传的所有文件类型(仅Excel一项对我来说似乎是一团糟,因为它现在有多种格式),为什么不通过病毒扫描程序运行所有上传的文件呢?各种各样的文件可能包含病毒和特洛伊木马。对于您的服务器来说,这可能需要更多的工作,但这是最安全的解决方案

然后由用户来正确识别他们的文件类型,这似乎是合理的。添加大量代码(也需要进行测试)只是为了再次检查您的用户,这似乎是一大步。如果我说它是一个.pdf2文件,你会把它重命名为.pdf吗?如果这是在公司环境中,那么期望用户的文件具有正确的扩展名是合理的。我也会追踪谁上传了什么。如果它是公共的,那么扫描文件类型可能是值得的,但我绝对也会做病毒扫描

换句话说,如果特洛伊木马.exe重命名为无害.pdf并上载,应用程序必须能够发现上载的文件不是.pdf文件

那真的不是问题。如果一个.exe以.pdf格式上传,并且您正确地以application/pdf格式将其备份到下载程序,那么下载程序将得到一个损坏的pdf。他们必须手动将其重新键入.exe才能受到伤害

真正的问题是:

  • 一些浏览器可能会嗅探文件的内容,并确定他们比您更了解文件的类型。IE在这方面尤其糟糕,如果它看到任何HTML标记潜伏在文件开头附近,倾向于将文件呈现为HTML。这尤其没有帮助,因为这意味着脚本可以被注入到您的站点中,可能会损害任何应用程序级别的安全性(cookie窃取等)。解决方法包括始终使用内容处置将文件作为附件提供,和/或从不同的主机名提供文件,这样它就不能跨站点脚本返回到主站点

  • PDF文件无论如何都不安全!它们可能充满了脚本,并且存在严重的安全漏洞。利用PDF阅读器浏览器插件中的漏洞是当前在web上安装特洛伊木马的最常见方法之一。通常,您几乎无法尝试检测这些漏洞,因为它们可能非常模糊


  • 在**NIX*系统上,我们有一个名为file(1)的实用程序。尝试找到类似的Windows,但文件实用工具如果已被移植。

    < P>下面的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;
    }
    
    /-1:文件不存在或没有访问权限
    //0:不是office文档
    //1:(一般)微软office 2007
    //2:(一般)MS office早于2007年
    //3:MS office 2003 PowerPoint演示文稿
    //4:MS office 2003 Excel电子表格
    //5:MS office应用程序或其他
    int ISOFICE2007OROLDER(文件名)
    {
    int-iRet=0;
    字节msgFormatChk2007[8]={0x50,0x4B,0x03,0x04,0x14,0x00,0x06,0x00};//office 2007文档的偏移量0
    字节possibleMSOldOffice[8]={0xD0,0xCF,0x11,0xE0,0xA1,0xB1,0x1A,0xE1};//可能的office 2003文档的偏移量为0
    字节msgFormatChkXLSPPT[4]={0xFD,0xFF,0xFF};//偏移量512:xls,ppt:FD-FF
    字节msgFormatChkOnlyPPT[4]={0x00,0x6E,0x1E,0xF0};//偏移量512:另一个ppt偏移量ppt
    字节msgFormatChkOnlyDOC[4]={0xEC,0xA5,0xC1,0x00};//偏移量512:EC A5 C1 00
    字节msgFormatChkOnlyXLS[8]={0x09、0x08、0x10、0x00、0x00、0x06、0x05、0x00};//偏移量512:XLS
    int iMsgChk=0;
    HANDLE fileHandle=CreateFile(文件名,一般读取,
    文件\共享\读取,空,打开\存在,文件\属性\只读,空);
    if(无效的\u句柄\u值==文件句柄)
    { 
    返回-1;
    }
    字节buff[20];
    德沃德·拜特斯雷德;
    iMsgChk=1;
    if(0==ReadFile(fileHandle,buff,8,&bytesRead,NULL))
    { 
    返回-1;
    }
    如果(buff[0]==msgFormatChk2007[0])
    {
    而(buff[iMsgChk]==msgFormatChk2007[iMsgChk]&&iMsgChk<9)
    iMsgChk++;
    如果(iMsgChk>=8){
    iRet=1;//office 2007文件格式
    }
    } 
    else if(buff[0]==possibleMSOldOffice[0])
    {
    while(buff[iMsgChk]==possibleMSOldOffice[iMsgChk]&&iMsgChk<9)
    iMsgChk++;
    如果(iMsgChk>=8)
    {   
    //旧的office文件格式,请进一步检查512偏移量,以筛选出真实的office格式
    iMsgChk=1;
    SetFilePointer(文件句柄,512,NULL,文件开始);
    if(ReadFile(fileHandle,buff,8,&bytesRead,NULL)==0){return 0;}
    if(buff[0]==msgFormatChkXLSPPT[0])
    {
    而(buff[iMsgChk]==msgFormatChkXLSPPT[iMsgChk]&&iMsgChk<5)