18

私は人々がヘルプチケットを記入できるPHPのウェブサイトを持っています。チケットのスクリーンショットをアップロードできます。gif、psd、bmp、jpg、png、tifのアップロードを許可します。アップロードを受信すると、PHPスクリプトはファイル拡張子を無視します。MIME情報のみを使用してファイルタイプを識別します。これらのファイルタイプの場合、ファイルの最初の12バイト内に常に格納されます。

誰かがいくつかのGIFをアップロードしましたが、ブラウザで表示すると、ブラウザはそれが無効であると言って、私のウイルススキャナーはそれが注射(またはそのようなもの)であると私に警告しました。これらのGIFを含むzipファイルについては、以下を参照してください。

ヘッダー情報をチェックするだけでは十分ではないと思います。画像は完全に有効である可能性があると聞きましたが、エクスプロイトコードも含まれています。

だから私は2つの基本的な質問があります:

  1. 誰かが(有効なGIF MIMEタイプを維持しながら)GIFに悪いものを注入した方法を知っていますか?これを知っていれば、アップロード時に確認できるかもしれません。
  2. 誰かがこのようなファイルをアップロードするのを防ぐにはどうすればよいですか?
    • 共有ホスティングを使用しているため、サーバー側のウイルススキャナーをインストールできません。
    • オンラインのウイルススキャンWebサイトに情報を送信するのは遅すぎる可能性があります。
    • これらをチェックするPHPクラスを使用して自分自身をチェックする方法はありますか?
    • GDを使用した画像のサイズ変更は、有効でない場合は失敗しますか?それとも、エクスプロイトはすり抜けてサイズ変更された画像に含まれるのでしょうか?それが失敗した場合、それが理想的です。なぜなら、サイズ変更をテクニックとして使用して、それらが有効かどうかを確認できるからです。

更新:皆さん、これまでのところ返信していただきありがとうございます。アップロードされたGIFをサーバーで検索しようとしています。見つけたらこの投稿を更新します。

更新2:興味のある人のためにGIFを見つけました。パスワード「123」で暗号化したzipファイルに入れました。ここにあります(このホスティングサイトには複数の[ダウンロード]ボタンがあることに注意してください。そのうちのいくつかは広告用です)http://www.filedropper.com/badgifs。5060.gifと呼ばれるものは、私のアンチウイルスによってトロイの木馬(TR / Graftor.Q.2)としてフラグが立てられています。これらのファイルは、最初の12バイトのMIMEチェックを実装する前にアップロードされたことに注意してください。だから今、私はこれらの特定のもののために安全です。しかし、正しいMIMEタイプの背後に隠れているエクスプロイトを検出する方法を知りたいのです。


重要な説明: 私は、これらのファイルをダウンロードしてそれらを見るPCへのリスクについてのみ懸念しています。 ファイルは私のサーバーにとってリスクではありません。それらは実行されません。それらは、拡張子が「.enc」のクリーンな名前(16進ハッシュ出力)を使用して保存され、fwriteフィルターを使用して暗号化された状態でディスクに保存します。

// Generate random key to encrypt this file.
$AsciiKey = '';
for($i = 0; $i < 20; $i++)
    $AsciiKey .= chr(mt_rand(1, 255));

// The proper key size for the encryption mode we're using is 256-bits (32-bytes).
// That's what "mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)" says.
// So we'll hash our key using SHA-256 and pass TRUE to the 2nd parameter, so we
// get raw binary output.  That will be the perfect length for the key.
$BinKey = hash('SHA256', '~~'.TIME_NOW.'~~'.$AsciiKey.'~~', true);

// Create Initialization Vector with block size of 128 bits (AES compliant) and CBC mode
$InitVec = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$Args = array('iv' => $InitVec, 'key' => $BinKey, 'mode' => 'cbc');

// Save encoded file in uploads_tmp directory.
$hDest = fopen(UPLOADS_DIR_TMP.'/'.$Hash.'.enc', 'w');
stream_filter_append($hDest, 'mcrypt.rijndael-128', STREAM_FILTER_WRITE, $Args);
fwrite($hDest, $Data);
fclose($hDest);
4

7 に答える 7

6

最初の質問については、ログや問題の画像を取得できないかどうかはわかりません。これらのエクスプロイトがターゲットにしている可能性のあるものはたくさんあり、エクスプロイトの配置方法によっては、ターゲットが何であるかによって異なります。ファイルへの入力は完全に異なる場合があります。

編集: W32 / Graftorは、トロイの木馬のような特性を持っているように見えるプログラムの総称です。

5060.gif16進エディタでファイルを開いた後、プログラムが実際には名前が変更されたWindowsプログラムであることに気付きました。これはブラウザのエクスプロイトではないため、実際に開いて実行しない限り無害ですが、ユーザーがだまされてプログラムを開く可能性があるため、アップローダーによって定義されたMIMEタイプで提供されないようにする必要があります。2番目の質問の答えを参照してください。

2番目の質問については、エクスプロイトコードやユーザーが実行されないようにするには、すべてのファイルがファイル名に安全な拡張子で保存され、正しいMIMEタイプで提供されるようにする必要があります。たとえば、次の正規表現を使用してファイル名を確認できます。

if(!preg_match ( '/\\.(gif|p(sd|ng)|tiff?|jpg)$/' , $fileName)){
    header("415 Unsupported Media Type");
    die("File type not allowed.");
}

また、正しいコンテンツタイプでファイルを提供していることを確認してください。ユーザーにファイルを提供するときは、アップロードされたファイルで指定されたコンテンツタイプを使用しないようにしてください。アップローダーによって指定されたContent-Typeに依存している場合、ファイルは、text/htmlまたは同様のものとして提供される可能性があり、ユーザーのブラウザーによってそのように解析されます。

これは、画像パーサーを除いて、ユーザーのブラウザの脆弱性を悪用する悪意のあるファイルからのみ保護することに注意してください。

サーバーに対するエクスプロイトを防止しようとしている場合は、PHPパーサーに画像のコンテンツを実行させないようにし、画像の処理に使用している画像ライブラリに既知のものがないことを確認する必要があります。脆弱性。

また、このコードは、ユーザーのブラウザで使用される画像パーサーのエクスプロイトを含む画像からユーザーを保護するものではないことに注意してください。getimagesize()これを防ぐために、Jeroenが提案したように評価がtrueであるかどうかを確認できます。

完全に有効な画像にはコメント内にHTML/PHPコードが埋め込まれている可能性があるためgetimagesize()、ファイル名をチェックせず、ファイルが正しいヘッダーで提供されていることを確認しない場合は、単独で使用するだけでは不十分であることに注意してください。Content-Type

于 2012-06-02T19:27:49.807 に答える
2

これにはgetimagesize()関数を使用できます。画像が無効な場合は、単に。を返しfalseます。

if (getimagesize($filename)) {
    // valid image
} else {
    // not a valid image
}

これも100%安全ではないことは注目に値しますが、私が知る限り、これが最善の方法です。

これについて詳しくは、こちらをご覧ください。

于 2012-06-02T19:33:13.680 に答える
2

アップロードを受け入れる任意のphpスクリプトでphpMusselを試すことができます。ファイルは、ClamAVシグニチャに加えて、このタイプの侵入を具体的に探すいくつかの内部ヒューリスティックシグニチャを使用してスキャンされます。

于 2014-09-23T09:25:35.627 に答える
1

画像のフォーマットについてはよくわかりませんが、画像を作り直して保存することで、不要なトリッキーなものを排除できる可能性が高いと感じています。特に、コメントなどのすべてのメタデータと、一部の画像形式でサポートされている他のすべてのタイプのオプションの埋め込みフィールドを削除する場合。

于 2012-06-02T19:36:22.013 に答える
0

1).gifを削除し、A / Vがログを書き込まなかった場合、問題が何であったかを正確に知ることはできません。

Q:問題の.gifはまだサーバー上にありますか?

Q:A / Vログを確認しましたか?

2)さまざまなエクスプロイトが考えられますが、.gifファイル形式と直接関係がある場合とない場合があります。これが1つの例です:

3)この例のリスクを軽減するには、次のことを行う必要があります。

a)サーバー上の安全なディレクトリにのみファイル(任意のファイル)をアップロードする

b)特定のサフィックス(.gif、.pngなど)が付いたファイルのみを提供します

c)サイトにアップロードされたものについては、非常に偏執的になります(特に、他の人にサイトからのダウンロードを許可する場合)。

于 2012-06-02T19:35:05.440 に答える
0

注入されたPHPの問題を防ぐための非常に役立つヒントは、私のホストのシステム管理者からのものです。私は、人々が自分のコンテンツをアップロードできるサイトを持っています。アップロードされた画像が提供されるディレクトリでPHPが実行されていないことを確認したかったのです。そうすれば、誰かが「test.php」という名前の画像を投稿することさえでき、それがアップロードディレクトリにある場合でもPHPによって解析されることはありません。解決策は簡単でした。アップロードされたコンテンツが提供されるフォルダーに、次の.htacessを配置します。

RewriteEngine On
RewriteRule \.$ - [NC]
php_flag engine off

これにより、フォルダーのPHPエンジンがオフになり、サーバー側の脆弱性を悪用するためにPHPを起動する試みが停止します。

于 2015-06-24T10:48:01.683 に答える
0

応答が遅いが、誰かに役立つかもしれない。あなたはそのようなアプローチを試みるかもしれません:

//saves filtered $image to specified $path
function save($image,$path,$mime) {
    switch($mime) {
        case "image/jpeg"   : return imagejpeg(imagecreatefromjpeg($image),$path);
        case "image/gif"    : return imagegif(imagecreatefromgif($image),$path);
        case "image/png"    : return imagepng(imagecreatefrompng($image),$path);
    }
    return false;
};
于 2016-05-10T09:36:25.440 に答える