ファイルアップロード攻撃@PHP技術

ファイルアップロード攻撃です。
ファイルをアップロードさせた後、アップロードしたファイルを踏んでのPHPコードやJavascriptを実行させる攻撃です。
この攻撃の脅威は、

  1. アップロードしたいファイルにスクリプトを仕込んで置く
  2. 転送したファイルを”システムにとって適切なファイルである”と偽装することで、ファイルを保存させる
  3. 保存したファイルにアクセスしてコードを実行させる(内部情報を抜き出すなど)

ができることです。

サイト内(DocumentRoot下)へアップロードファイルを管理している時に起こる可能性があります。

  1. ファイルアップロード攻撃 攻撃側

攻撃を行って見ます。ここではアップロードされたファイルを/image配下に設置しています。ここはURL指定できる場所になっています。

if(!empty($_FILES['userfile']['tmp_name'])){
    move_uploaded_file($_FILES['userfile']['tmp_name'],dirname(__FILE__).'/images/'.$_FILES['userfile']['name']);
    header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']);
    exit;
}

header('Content-Type: text/html; charset=utf-8');

echo "
<html>
<body>
<form action='/PHPS/2-4.php' method='post' enctype='multipart/form-data'>
    <input type='file' name='userfile' />
    <input type='submit' value='upload' />
</form>
</body>
</html>

実際にアップロードしてみます。
ここでは、Javascriptとphpinfo()関数を仕込んだattack.phpファイルをアップロードしました。

すると、/image配下にアップロードファイルが保存されました。
その後、以下のURLを叩きます。

http://〜〜/PHPS/images/attack.php

結果、Javascriptとphpinfo()関数が実行されました。

ちなみに、

if(preg_match('/[a-z]*.html$/',$_FILES['userfile']['name']) === 0){
        echo "アップロードできません";
        exit;
    }

などとしてアップロードできる拡張子をhtmlだけにしてもJavascriptを仕込めるし、html自体にphpコードが潜んでいれば実行されるので意味がないです。


  • ファイルアップロード攻撃 防御側

注意!以下の解決策は解決になっているか微妙な方法です



ファイルアップロード攻撃に対しての防御策は、アップロードされた後にアクセスできることがまずいので、ファイル保存場所を非公開化します。
具体的には

  • 公開フォルダの外に出す
  • ランダムなファイル名で保存する
  • 転送スクリプトを書く

などがあるそうです。
この中でランダムなファイル名版を作ってみました。
保存ロジックにランダムファイル生成(+ハッシュ化)ロジックを組み込みました

$fileName = hash("md5", $_FILES['userfile']['name'].mt_rand(0, 10000));
    move_uploaded_file($_FILES['userfile']['tmp_name'], dirname(__FILE__).'/images/'.$fileName);

これで簡単にはファイルにアクセスできないはず!


ここで学んだことは、

  1. ファイルの付加情報を偽装される事を知った。
  2. ユーザーから投げられる情報(ファイルなど)は全て疑うべきということを再認識した

以上です