7


6

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

ファイルが実際に拡張子が示すものと同じ種類かどうかを判断する必要があります。 つまり、_trojan.exe_が_harmless.pdf_に名前変更されてアップロードされた場合、アプリケーションはアップロードされたファイルが.PDFファイルではないことを認識できなければなりません。

あなたはこれらのアップロードされたファイルを分析するためにどんなテクニックを使うでしょうか? これらのファイルのフォーマットに関する最良の情報はどこにありますか?

7 Answer


4


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


4


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

それは本当に問題ではありません。 .exeが.pdfとしてアップロードされ、それをapplication / pdfとしてダウンローダに正しく戻した場合、すべてのダウンローダは壊れたPDFになります。 危害を加えるには、手動で.exeに再入力する必要があります。

本当の問題は:

  1. ブラウザの中には、ファイルの内容を盗み見て、ファイルの種類について自分よりもよく知っていると判断するものがあります。 IEは、この点で特にまずいです。ファイルの先頭近くにHTMLタグが隠れている場合は、ファイルをHTMLとしてレンダリングすることを好む傾向があります。 スクリプトがあなたのサイトに挿入される可能性があるため、これは特に役に立ちません。アプリケーションレベルのセキュリティを危険にさらす可能性があります(cookie stealing et al)。 回避策としては、常にContent-Dispositionを使用してファイルを添付ファイルとして提供したり、別のホスト名のファイルを提供したりするため、メインサイトにクロスサイトスクリプトを作成することはできません。

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


3


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


2


私はあなたがC#を言ったことを知っています、しかしこれは移植されるかもしれません。 また、XMLファイルには、一般的なファイルの種類の記述子がすでに多数含まれています。

それはJMimeMagicと呼ばれるJavaライブラリです。 それはここにあります:http://jmimemagic.sourceforge.net/


1


多分あなたは別の方向からこれにアプローチすることができます。 アップロードされるすべてのファイルの種類を識別するのではなく(Excelだけでも、最近ではいくつかの形式があるため、私にとっては面倒なようです)、すべてのアップロードをウイルススキャナで実行しないでください。 さまざまなファイルにウイルスやトロイの木馬が含まれている可能性があります。 それはあなたのサーバーにとってはより多くの仕事かもしれませんが、それは最も安全な解決策です。

それからそれは合理的に思える彼らのファイルタイプを正しく識別することはユーザー次第です。 ユーザーを二重にチェックするために多くのコードを追加すること(これもテストする必要があります)は大きなステップのようです。 私がそれが.pdf2ファイルであると言うならば、あなたはそれを.pdfに改名しますか? これが企業環境にある場合は、ユーザーが自分のファイルに正しい拡張子を付けることをお勧めします。 誰が何をアップロードしたかも追跡します。 もしそれが公にされているのであれば、ファイルタイプのスキャンは価値があるかもしれませんが、私はウイルススキャンも絶対にしたいと思います。


1


  • NIX *システムでは_file(1)_というユーティリティがあります。 Windowsに似たものを見つけようとしますが、selfが移植されていればファイルユーティリティです。


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}。 // Office 2007ドキュメントのオフセット0バイト可能MSOldOffice [8] = {0xD0、0xCF、0x11、0xE0、0xA1、0xB1、0x1A、0xE1}; // Office 2003の可能性のあるドキュメントの場合は0をオフセット

byte msgFormatChkXLSPPT [4] = {0xFD、0xFF、0xFF、0xFF}; // offset 512:xls、ppt:FD FF FF FFバイトmsgFormatChkOnlyPPT [4] = {0x00、0x6E、0x1E、0xF0}; // offset 512:別のPPTオフセットPPT byte msgFormatChkOnlyDOC [4] = {0xEC、0xA5、0xC1、0x00}; // offset 512:EC A5 C1 00バイトmsgFormatChkOnlyXLS [8] = {0x09、0x08、0x10、0x00、0x00、0x06、0x05、0x00}; //オフセット512:XLS

int iMsgChk = 0; HANDLE fileHandle = CreateFile(ファイル名、GENERIC_READ、FILE_SHARE_READ、NULL、OPEN_EXISTING、FILE_ATTRIBUTE_READONLY、NULL); if(INVALID_HANDLE_VALUE == fileHandle){return -1; }

バイトバフ[20]; DWORD bytesRead; iMsgChk = 1; if(0 == ReadFile(fileHandle、buff、8、

if(buff [0] == msgFormatChk2007 [0]){while(buff [iMsgChk] == msgFormatChk2007 [iMsgChk]

if(iMsgChk> = 8){iRet = 1;そうでなければ(buff [0] == possibleMSOldOffice [0]){while(buff [iMsgChk] == possibleMSOldOffice [iMsgChk]

if(iMsgChk> = 8){//古いオフィスファイル形式の場合、実際のオフィス形式を除外するためにさらに512オフセットをチェックしてくださいiMsgChk = 1; SetFilePointer(fileHandle、512、NULL、FILE_BEGIN); if(ReadFile(fileHandle、buff、8、

if(buff [0] == msgFormatChkXLSPPT [0]){while(buff [iMsgChk] == msgFormatChkXLSPPT [iMsgChk]

if(iMsgChk == 4)iRet = 2。そうでなければ(buff [iMsgChk] == msgFormatChkOnlyDOC [iMsgChk]){while(buff [iMsgChk] == msgFormatChkOnlyDOC [iMsgChk])

そうでなければ(buff [0] == msgFormatChkOnlyPPT [0]){while(buff [iMsgChk] == msgFormatChkOnlyPPT [iMsgChk]

(iMsgChk == 4)iRet = 3の場合。そうでなければ(buff [0] == msgFormatChkOnlyXLS [0]){

while(buff [iMsgChk] == msgFormatChkOnlyXLS [iMsgChk]

if(iMsgChk == 9)iRet = 4。 }

if(0 == iRet){iRet = 5; }}}

CloseHandle(fileHandle);

iRetを返します。 }