Windows版PHPのOSコマンドインジェクション脆弱性について

投稿者: | 2015年7月21日

先週IPAからWindows版PHPにOSコマンドインジェクションが
存在すると注意喚起されました。
今回はOSコマンドインジェクションについて簡単に説明したいと思います。

OSコマンドインジェクションとは、OSコマンドを実行するプログラムに細工したパラメータを読み込ませ意図しない動作をさせる攻撃の事を指します。
例えば、下記のようなフォルダ名を受け取りファイル一覧を取得するプログラムがあるとします。
フォルダ名に下記のようなパラメータを渡す事により、OSをシャットダウンする事ができます。

system('dir '.$folder);

$folder = 'C:\\ & shutdown -s';

↓実際に実行されるコマンド

dir C:\ & shutdown -s

OSコマンドインジェクションを避ける為にはパラメータをエスケープするのが一般的です。

system('dir '.escapeshellarg($folder));

↓実際に実行されるコマンド

dir "C:\ & shutdown -s"

パラメータをエスケープする事により、1つの文字列としてOSコマンドに渡す事ができます。
escapeshellarg関数はシェルコマンド用パラメータをエスケープする為にPHPで用意された関数です。
今回の脆弱性はこの関数にありました。
パラメータに細工を施してescapeshellargを実行すると、一部分がエスケープされないようです。
既にパッチは配布されているのでsystemなどのOSコマンド実行するプログラムを動作させている場合は早急に適用をお勧めします。

OSコマンドは実行されてしまうと非常に危険な為、出来ればプログラムではOSコマンドを実行しないのが好ましいと思います。
どうしても実行しなければならない場合は入力値をそのままパラメータにする事は避け、チェックを十分に行った上で利用するべきでしょう。

■参考サイト
Windows 版「PHP」におけるOSコマンド・インジェクションの脆弱性対策について(JVN#73568461)