ファイルが勝手にスクリプトとして実行される

Security 12月 6, 2005
(Last Updated On: 2005年12月6日)

また困った問題が見つかりました…(問題と言うより仕様に気が付きました)

full-disclosureで「これおかしくない?」と報告されています。Wikiがフィッシング(Phishing)に利用される問題などがあったので影響を受けるシステムは少なくなっている、とは思いますが直ぐに攻撃のまだまだ影響を受けるシステムも多いと思います。

個人的にはLinux上のApache 2.0.54上のPHP 5.0.5/PHP 5.1.1が影響を受ける事を確認しました。
(Mac OSXでも同様の動作である、と聞きました)

http://137.113.100.11/manual/ja/mod/mod_mime.html

によると

ファイルは複数の拡張子を持つことができ、拡張子の順番は通常は関係ありません。例えば、ファイル welcome.html.fr がコンテントタイプは text/html に、言語はフランス語にマップされる場合、welcome.fr.html もまったく同じ情報にマップされます。 同じメタ情報にマップされる拡張子が複数あるときには、右側にあるものが使用されます。たとえば、”.gif” が MIME タイプ image/gif にマップされ、”.html” が MIMEタイプ text/html にマップされる場合は、ファイル welcome.gif.html は MIME タイプ “text/html”に関連付けられます。

複数の拡張子のあるファイルが MIME タイプとハンドラの両方に関連付けられているときは注意する必要があります。その場合、普通はリクエストがハンドラに関連付けられた モジュールによって扱われることになります。たとえば、拡張子 .imap が(mod_imap の) “imap-file” にマップされていて、 .html が MIME タイプ “text/html”にマップされているときは、ファイル world.imap.html は “imap-file” ハンドラと “text/html” MIMEタイプに関連付けられます。ファイルが処理されるときは “imap-file” ハンドラが使用されますので、そのファイルは mod_imapのイメージマップファイルとして扱われることになります。

つまり、test.php.bakがPHPスクリプトとして実行されるのは仕様のようです。

記憶が曖昧ですが古いApacheはこんな動作ではなかったと思ったのですが、調べてみると1.3からはずっと同じのようです。

拡張子による適用されるハンドラのチェックは普通に行われているので、この仕様には十分注意が必要ですね。

■概要

アップロードされたファイルなどがスクリプトとして実行できる。

■問題

Aapche 1.3系、2.0系のSAPIとして動作(Apacheモジュールとして動作)させている場合、httpd.confのAddTypeディレクティブで登録された拡張子のファイルのみPHPスクリプトとして実行されるべきです。最近(?)のPHPのApache SAPIは登録された拡張子以外のファイルをPHPスクリプトとして実行してしまう仕様のようです。

例えば、test.php.bak, test.php.rar などhttpd.confにAddTypeでPHPスクリプトとして登録されていないファイルの場合でも勝手にPHPスクリプトして実行されます。PHP以外の言語ハンドラでも同様です。

サンプルスクリプト

<?php echo “This file is executed as PHP script” ?>

このスクリプトをtest.php.bakとしてドキュメントルート以下のディレクトリに保存し、PHPがインストールされている場合、PHPスクリプトとして実行する事が可能です。

Apacheに登録されていない特殊な画像ファイル(psd等)、圧縮ファイル(rar等)、マイナーな文書形式(.jwt等)、etcを取り扱っているサイトは注意が必要です。

私の環境では.html, .txt, .gif, .png等Apacheに登録済みの拡張子はスクリプトとして実行されませんでした。

未検証ですがPHPのみでは無くCGIでもAddHandlerで登録されたハンドラでも同じだそうです。

/cgi-bin/test.cgi.bak

でも同じ様にスクリプトが実行されるそうです。

■影響

主にこの問題の影響を受けるアプリケーションはファイルをアップロード可能なシステムです。アップロードされたファイルがドキュメントルートに配置されている場合、簡単に任意スクリプトをローカルホスト上で実行される可能性があります。

例えば、PHPの

bad.php.bak

等のファイルアップロードされ、ブラウザから参照できるディレクトリに置いてあるとリモートから任意のスクリプトを実行される場合があります。

■対処策

対処策にはいくつかの方法があります。

1.ユーザからアップロードされたファイル等、信頼できないファイルをドキュメントルート以下に配置しない。(そもそも、アップロードされたデータ全てはドキュメントルート以下に配置するべきではありません)
2. Apacheで明示的にTypeが指定されていないファイルはアップロードさせない。(1の対処をするべきです。直ぐには不可能な場合のみ。非推奨)
3.アップロードされる可能性のある拡張子はhttp.confで別のTypeとして登録する(1の対処をするべきです。直ぐには不可能な場合のみ。非推奨)

備考:PHPに限らずイメージ識別関数はファイルのヘッダ部分のみチェックしています。PHPの場合、スクリプトタグ以外の部分単純にecho出力されるためイメージ形式識別関数で形式をチェックしていても普通にエラーの無いPHPスクリプトとして実行可能です。イメージ形式を識別しているからと言って安心することは出来ません。

■まとめ

ファイルアップロードをサポートしている場合、ファイルはドキュメントルート以下に配置しない(基本)を守らないと色々ありますね…

投稿者: yohgaki