ディレクトリ内のすべてのファイルが画像ファイルであることを確認するシェルスクリプトを作成したいと思います。
最近、ハッカーがディレクトリにファイルを生成し、それを.jpgファイルとしてマスクできるという問題がありました。シェルスクリプトを作成して、ディレクトリ内のすべてのファイルをチェックして、それらが実際のjpg、gif、またはpngファイルであることを確認します。
完全に信頼できない入力を与える状況でfile
を使用する場合は、細心の注意が必要だと思います。たとえば、RHEL 5 file
はこれを識別します。
GIF87a
<?php
echo "Hello from PHP!\n";
?>
「GIF画像データ、バージョン87a、15370 x 28735」として。 PHPインタプリタはその入力を実行するのに問題はありません。この問題の欠如が " ローカルファイルのインクルード "(LFI)の問題の根拠です。
次に、file
(さらにはstrings
)が実際に入力ファイルを解析して、知りたいことを伝えます。これらの パーサーは複雑です および 問題があります 。
ImageMagick スイートからidentify
コマンドを提案します。上記の簡単な例ではだまされず、画像ファイルを正しく解析するだけなので、file
よりもセキュリティ上の欠陥が発生しにくいはずです。
簡単な最初のパスとして、 file
コマンドは画像ヘッダーをすばやく検出できます。
if file "$FILE" |grep -qE 'image|bitmap'; then
echo "File '$FILE' has the headers of an image"
fi
(bitmap
の2番目の代替は、認識したい場合に必要です Windows BMP files libmagicはWordの「イメージ」を使用してビットマップイメージを記述しないため。)
ただし、PHPをベースにした偽のイメージでfile
をだますことができます Bruce Edigerの回答 :
$ echo 'GIF87a<?php echo "Hello from PHP!"; ?>' > fake.gif
$ file fake.gif && echo image detected || echo no image detected
fake.gif: GIF image data, version 87a, 16188 x 26736
image detected
ImageMagick スイートには、特定の画像のメタデータを返すCLIフロントエンドを備えた identify スクリプトがあります。予想されるメタデータが存在しない場合は失敗するため、この目的に最適です。
$ identify fake.gif && echo image detected || echo no image detected
identify-im6.q16: negative or zero image size `fake.gif' @ error/gif.c/ReadGIFImage/1402.
no image detected
大量のファイルのスキャンを高速化するには、両方をまとめることをお勧めします。
if file "$FILE" |grep -qE 'image|bitmap' \
&& ! identify "$FILE" >/dev/null 2>&1; then
echo "File '$FILE' is a fake image!"
fi
(これは、identify
の出力を忘却にリダイレクトします。これは、正常に完了できたかどうかのみが対象であるため、終了コードによってキャプチャされます。)
次の例では、同じPHPコードが最後に追加されたシンプルな1x1の白いGIFを使用しています。わからないPHP実際には実行されますが、PHPは<?php … ?>
タグの外側にリテラル「テキスト」を出力するテンプレート言語であるため、指定されたコードをそのまま実行すると想定しています、ペイロードの前にゴミがいくらかあるだけです。
$ { echo 'R0lGODdhAQABAIAAAP///////ywAAAAAAQABAAACAkQBAD'
echo 's8P3BocCBlY2hvICJIZWxsbyBmcm9tIFBIUCEiOyA/Pgo='
} | base64 -d > fake2.gif
$ strings fake2.gif
GIF87a
;<?php echo "Hello from PHP!"; ?>
$ file fake2.gif
fake2.gif: GIF image data, version 87a, 1 x 1
$ identify fake2.gif
fake2.gif GIF 1x1 1x1+0+0 8-bit sRGB 2c 68B 0.000u 0:00.000
これは、GIFコメントを使用して画像として完全に有効にすることもできます。
$ hd fake3.gif
00000000 47 49 46 38 39 61 01 00 01 00 80 00 00 ff ff ff |GIF89a..........|
00000010 ff ff ff 21 fe 20 3c 3f 70 68 70 20 65 63 68 6f |...!. <?php echo|
00000020 20 22 48 65 6c 6c 6f 20 66 72 6f 6d 20 50 48 50 | "Hello from PHP|
00000030 21 22 3b 20 3f 3e 00 2c 00 00 00 00 01 00 01 00 |!"; ?>.,........|
00000040 00 02 02 44 01 00 3b |...D..;|
00000047
私はGIFを選び、そのコメントシステムを利用しましたが、画像の後にペイロードを連結するだけでも、この検出手法をバイパスすることができます。これは、file
をだますことよりも難しく、(実装によっては)might証拠を残す(画像のゴミ)ことがあります。