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

自分の勉強用まとめです。解釈に間違いがあるかもしれないのでその時はご指摘していただけると助かります><

今回は、ファイルアップロード攻撃についてです。

ファイルアップロード攻撃とは

ファイルアップロード攻撃とは、ファイルをアップロードするサービスにおいて、悪意のあるスクリプトをアップロードし、そのファイルにアクセスすることによって情報を抜き出したりする攻撃です。

以下に、例を示します。

<?php
$tmpfile = $_FILES["upfile"]["tmp_name"];
$dirfile = $_FILES["upfile"]["name"];

/*ファイルが適切にアップロードされているかどうかを調べる。*/
if (! is_uploaded_file($tmpfile)) {
    die('ファイルがアップロードされていません');
/*指定したディレクトリに移動する。できない場合はエラーを吐く。*/
} else  if (! move_uploaded_file($tmpfile, 'img/' . $dirfile)) {
    die('ファイルをアップロードできません');
}
?>

上記のコードを考えます。

ユーザからファイルがアップロードされたら、tmpfileを作成し、is_uploaded_file関数でファイルが適切にアップロードされているかを確認します。関数の説明はこちら

そして、move_uploaded_file関数で送られてきたファイルを指定したディレクトリに置きます。関数の説明はこちら

ここで、imgディレクトリが公開フォルダだとします。

この時、このソースにはファイルアップロード攻撃の脆弱性が存在します。

攻撃者が悪意のあるスクリプトをアップロードした場合、そのスクリプトは公開フォルダに設置されることになります。

たとえば、 <?php passthru($_GET["cmd"]); と書かれたphpファイル(ファイル名をhack.phpとします)をアップロードされた場合を考えます。

このとき、/img/hack.php?cmd=lsなどでgetリクエストを飛ばすと、phpの方でpassthru関数でcmdを呼び出してしまい、lsコマンドを実行されてしまいます。

このような攻撃がファイルアップロード攻撃です。

また、$_FILES[]['name']には、PHP5.3.6以前のバージョンでCVEが発行されています。 入力されたファイル名はディレクトリ部分は消されるのですが、/tino.pngなどルート直下のディレクトリを指定した場合、そのままフルパスとして処理してしまう脆弱性です。

詳しくはCVE-2011-2202脆弱性をごらんください。

対策

ファイルアップロード攻撃の対策としては、以下のような方法が挙げられます。

1.アップロードされたファイルを非公開ディレクトリに移す(悪意あるスクリプトを実行できなくする)

2.アップロードされたファイル名をrenameする(拡張子などを変えることによって悪意あるスクリプトを実行できなくする)

3.動かしているサーバー側の権限を最小限にする(万が一shellを取られても何もできないようにする)

などが考えられます。

参考文献:体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践 / 徳丸 浩 著