連載
» 2004年11月12日 00時00分 UPDATE

Webアプリケーションに潜むセキュリティホール(13):OSコマンドインジェクションを防ぐルールを作成する (1/3)

[中村隆之,三井物産セキュアディレクション]

※ご注意

他社および他組織のWebサイトなどへのポートスキャンおよびデータの取得などの行為で得た情報を侵入などに悪用するか、または同じ目的を持つ第三者に提供した時点で違法となります。ご注意ください。

本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。

また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。



 前回は、クロスサイトスクリプティングを防ぐルールを作成した。今回は、OSコマンドインジェクション用のルールを考えてみることにしよう。OSコマンドは使用OSによって異なるため、今回はUNIX系OS向けのルールを作成する。

 なお、前回のクロスサイトスクリプティングのルールを作成したときと同様に、本稿で作成するmod_securityのルールも、さまざまなWebアプリケーションで検証を行ったわけではない。そのため、ルールにマッチしたリクエストを始めから拒絶する設定は危険であるので、十分なテスト運用が必要である。

OSコマンドインジェクションとは

 防御方法を考えるには、攻撃者がどのように攻撃してくるかを知らなければならない。まずは、OSコマンドインジェクションについて簡単に説明しておこう。

この攻撃は、不正な入力によって、サーバ上でOSコマンドを実行させる。攻撃の種類を以下のように分類しておく。

  • OSコマンドのパラメータを操作して、別の動作を行わせる
  • 別のOSコマンドを実行させる

 実は、このあたりの分類方法は、きっちりと線引きできるように決まっているわけではない。SQLインジェクションの場合は、不正文字列の入力によって別の意味となるSQL文が実行できれば、それはSQLインジェクションと分類するのだが、OSコマンドインジェクションの場合は、そうとは限らない。ファイルを表示するOSコマンドに「../etc/passwd」という文字列を渡せば、それはディレクトリ・トラバーサル攻撃に分類されるだろう。

 そのため本稿では、別のOSコマンドを実行させる攻撃をOSコマンドインジェクションとし、これを検知するためのルールを考えていくことにする。ただし、パラメータの操作によって、別のOSコマンドを実行できることもあるので、それについては今回の説明に含めることにする。

検知を容易にするためにApacheの設定を変更する

 mod_securityのような、ネガティブモデルのWebアプリケーションファイアウォールでは、受け取った文字列が確実に危険であると判断できる場合以外はリクエストを拒絶できない。これは前回までに説明したとおりである。そのために、Apache自身の設定を少し変更しておくことにする。

 Apacheの設定変更と書いたが、正確には Apacheに渡すPATH 環境変数を変更する。PATHはApacheの起動時にシェルから受け取り、OSコマンド実行時にコマンドの検索パスとして利用されている。このPATHが設定されている場合、攻撃者はOSコマンドをコマンド名の入力だけで実行できることになるため、これを防ぐためのルール設定が難しくなってしまう。PATHが設定されていない場合、OSコマンドの実行には絶対パスによる指定が必要となるため、「/bin」や「/usr/bin」などの文字列が攻撃パターンに現れることになる。そのため、検知が容易になるのである。

 PATHを空にするには、Apacheの起動スクリプト「apachectl」の先頭に以下の1文を追加し、スクリプト中でOSコマンドを相対パスで呼び出している箇所を、絶対パスに直してやればよい。

PATH=; export PATH; 

 なお、このように設定すると、相対パスでOSコマンドを呼び出しているアプリケーションが正常に動かなくなる可能性があるので、注意してほしい。また、アプリケーション内部でPATHを再設定している場合は、攻撃者もそのPATHを利用できてしまうため、今回の設定はあまり意味がなくなってしまう。

 ただし、PerlのTaintモード(汚染検出モード)を使用している場合は、アプリケーション中で明示的に環境変数を設定しないとエラーになってしまう。Taintモード使用時の対策としては、以下のように空のPATHを指定しておけばよい。

$ENV{'PATH'} = ""; 

 次に、攻撃パターンに現れるOSコマンドの絶対パスについて調べておく。筆者がテストで使っているRed Hat Linux 9では、ルートディレクトリ以下に次のようなディレクトリが存在している。

/bin /dev /home /lib /misc /opt /root /tftpboot /usr /boot /etc /initrd /lost+found /mnt /proc /sbin /tmp /var

 このうち、コマンド類が含まれるディレクトリだけルールに入れておけばよい。今回はこれらの中で、以下のディレクトリを指定する。

/bin
/home
/opt
/usr
/etc
/sbin
/var

 ほかにもコマンド類が置かれるディレクトリがあれば、それらも含める必要がある。このディレクトリ選択はユーザーごとに異なるはずなので注意してほしい。

第12回」へ


       1|2|3 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。