7

ファイルのアップロードを処理する ASP Web ページに取り組んでいます。.XLS、.XML、.CSV、.TXT、.PDF、.PPT など、特定の種類のファイルのみをアップロードできます。

拡張子が示すのと同じタイプのファイルが本当にあるかどうかを判断する必要があります。つまり、trojan.exeの名前がharmless.pdfに変更されてアップロードされた場合、アプリケーションは、アップロードされたファイルが .PDF ファイルではないことを検出できなければなりません。

これらのアップロードされたファイルを分析するには、どのような手法を使用しますか? これらのファイルの形式に関する最良の情報はどこで入手できますか?

4

7 に答える 7

4

1 つの方法は、ファイル内の特定の署名またはマジック ナンバーを確認することです。このページには、既知のファイル署名の便利なリストがあり、かなり最新のようです。

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

于 2009-01-16T16:17:11.590 に答える
4

つまり、trojan.exe の名前がharmless.pdf に変更されてアップロードされた場合、アプリケーションは、アップロードされたファイルが .PDF ファイルではないことを検出できなければなりません。

それは本当に問題ではありません。.exe が .pdf としてアップロードされ、ダウンローダに application/pdf として正しく提供された場合、ダウンローダは壊れた PDF だけを取得します。被害を受けるには、手動で .exe に再入力する必要があります。

実際の問題は次のとおりです。

  1. 一部のブラウザは、ファイルの内容をスニッフィングし、ファイルの種類についてユーザーよりもよく知っていると判断する場合があります。IE はこれが特に苦手で、ファイルの先頭付近に HTML タグが潜んでいるのを見つけた場合、ファイルを HTML としてレンダリングすることを好む傾向があります。これは、スクリプトがサイトに挿入される可能性があり、アプリケーション レベルのセキュリティ (Cookie 盗用など) が危険にさらされる可能性があることを意味するため、特に役に立ちません。回避策には、Content-Disposition を使用して常にファイルを添付ファイルとして提供すること、および/または別のホスト名からファイルを提供することが含まれます。これにより、クロスサイト スクリプトでメイン サイトに戻ることができなくなります。

  2. とにかくPDFファイルは安全ではありません!それらはスクリプトでいっぱいになる可能性があり、重大なセキュリティ ホールが存在します。現在、Web にトロイの木馬をインストールする最も一般的な手段の 1 つは、PDF リーダー ブラウザ プラグインのホールの悪用です。また、エクスプロイトは高度に難読化されている可能性があるため、エクスプロイトを検出するために通常できることはほとんどありません。

于 2009-01-16T17:06:27.497 に答える
3

「安全な」ファイル タイプのファイル ヘッダーを取得します。実行可能ファイルには常に独自のタイプのヘッダーがあり、おそらくそれらを検出できます。ただし、受け入れる予定のすべての形式に精通している必要があります。

于 2009-01-16T16:15:39.580 に答える
2

あなたがC#と言ったのは知っていますが、これはおそらく移植される可能性があります。また、一般的なファイル タイプの多くの記述子が既に含まれている XML ファイルもあります。

JMimeMagic という Java ライブラリです。ここにあります: http://jmimemagic.sourceforge.net/

于 2009-01-16T16:23:31.107 に答える
1

たぶん、あなたは別の方向からこれに近づくことができます。アップロードされたすべてのファイルタイプを識別する代わりに(Excelだけでは、最近いくつかの形式があるため、私には混乱しているように見えます)、ウイルススキャナーを介してすべてのアップロードを実行してみませんか?多種多様なファイルにウイルスやトロイの木馬が含まれている可能性があります。サーバーにとってはより手間がかかるかもしれませんが、最も安全なソリューションです。

次に、ファイルタイプを正しく識別するのはユーザーの責任であり、これは合理的と思われます。ユーザーを再確認するためだけに多くのコードを追加する(これもテストする必要があります)のは大きな一歩のようです。.pdf2ファイルだと言ったら、名前を.pdfに変更しますか?これが企業環境にある場合は、ユーザーがファイルに正しい拡張子を持っていることを期待するのが妥当です。誰が何をアップロードしたかも追跡します。公開されている場合は、ファイルタイプをスキャンする価値があるかもしれませんが、ウイルススキャンも絶対に行います。

于 2009-01-16T16:42:25.453 に答える
1

**NIX* システムには、file(1)というユーティリティがあります。Windows 用に似たものを探してみてください。

于 2009-01-16T17:08:14.263 に答える
0

次の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;
}
于 2011-03-15T07:29:06.237 に答える