WAF(Web Application Firewall)でWebサイトを脆弱性から守る

web application firewall

ウェブアプリケーションの脆弱性を利用した攻撃からWebサイトを守るための方法の一つとしてWAF(Web Application Firewall)の利用があげられます。
ここではオープンソースのWAFである ModSecurity を利用した方法に関して説明します。

はじめに

現在多くのWebサイトで、多数のWebアプリケーションが利用されています。
Webアプリケーションを作成する上では脆弱性を持たないように、セキュア・プログラミングを行うのが原則ですが、脆弱性に対する攻撃方法は日々進化しており、これら攻撃全てに対応するのは困難な場合も多いです。

Webアプリケーションに脆弱性が発見された場合、Webアプリケーションを改修して問題を修正するのが根本的な解決策です。
しかし、この方法を採るのが困難である場合に、WAFを適切に導入・運用する事で、Webサイトを保護する事が可能になる場合があります。

特に利用しているWebアプリケーションが以下のような状態の場合、WAF導入を検討してみる価値はあると思います。

  • オーダーメイドにより開発したシステムだが、保守期間を過ぎており改修が困難。開発した会社が既に存在しない等。
  • オープンソースを利用しているが、古いバージョンを利用していて保守期間を過ぎている。
    新バージョンへの移行は諸事情により行えない。
  • 改修を行う方法はあるが、予算やリソースがない。

特にオーダーメイドのシステムの場合等には( オープンソースや商用製品等と比べて脆弱性に関する調査が行われず )、脆弱性が存在するかどうかすら不明な場合も多いと思われます ( 実は脆弱性を突いた攻撃がされているのに気付いていない状態 )。
WAFの導入によってこれら未知の脆弱性に対する防御が可能になる場合もあると思われます。

WAFの概念や提供形態等詳細に関しては IPA が公開している Web Appplication Firewall 読本 に詳しいので、興味がある方はこちらを参照して下さい。

※写真は IM FREE から ( Back to basics by kennymatic )

環境

以下では、上記 IPAの WAF読本にも記載がある ModSecurity を利用した WAF構築に関して説明します。

構築環境は以下のようになります。

  • CentOSの場合
    OS CentOS 6.5 (64bit)
    Web Server Apache ( httpd-2.2.15-30.el6 )
    WAF mod_security-2.7.3-2.el6
    mod_security_crs-2.2.6-3.el6
    mod_security_crs-extras-2.2.6-3.el6
  • Amazon Linux の場合
    OS Amazon Linux (64bit)
    Web Server Apache ( httpd-2.2.26-1.1.amzn1 )
    WAF mod_security-2.7.3-20.amzn1
    mod_security_crs-2.2.6-3.4.amzn1
    mod_security_crs-extras-2.2.6-3.4.amzn1

注意点

実運用環境に導入する前にはテストを行う

構築を行う場合、最初は必ずテスト環境で導入・試験を行うようにします。

WAFはリクエストの内容を検知し、そのリクエストが不正なものか否かを判定しますが、この判定はプログラムにより機械的に行われるため、

正しいリクエストであっても、不正なものと判定される (偽陽性)

事があり得ます ( 逆もある )。

必ずテスト環境で試験を行い、Webサイト運用に問題のない設定を行ってから運用環境に適用するようにすべきです。

※実際、弊社Webサイトの試験環境にmod_securityを導入し、デフォルト設定で動作させてみた際は、管理画面が動作しなくなりました。

また、WAF、及び、検知ルールのアップデートによって、それまでは問題がなかった設定でも問題が発生してしまう可能性もあります。WAFに関するアプリケーションに関しては

  • パッケージの自動アップデートを行っている場合でもWAFは対象外にする
    テスト環境で試験してから手動アップデートを行う
  • アップデートをきちんと監視して、問題が発生した場合でも直ぐに対応できるようにする

といった対応をとる必要がでてきます。

WAFが知られるようになって大分立ちますが実際に運用しているサイトはまだまだ少ないように思いますし、ModSecurityに関しては特に日本語の文献は少ないようです。

WAFの導入にあたっては、運用面も踏まえて導入するかどうかを決める必要があります。

パフォーマンスに影響が出る可能性も考慮する

WAFを導入する際、検知を行うパターンが増えれば、その分パフォーマンスにも影響します。
セキュリティの点からすると全ての検知を行いたくなりますが、こういった点も踏まえて、適用するルールは必要十分なものに絞るべきかと思います。
( 「何をもって必要十分か?」は、環境によるので、これが適切と言い切れないのが難しいですが )

ModSecurity のインストール

ModSecurity のインストール手順を以下に示します。
ModSecurityは yum を利用してインストールする事にします。
Apache は既にインストール/動作済みとします。

epel リポジトリのインストール

CentOS の場合、mod_security は標準の yum リポジトリには含まれていないので、epel リポジトリをインストールします。
  1. epel リポジトリがインストールされていない場合、rpm を取得しインストールします。 http://download.fedoraproject.org/pub/epel/ から環境に併せた rpm を取得します。
    $ wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    
  2. 取得した rpm ファイルを利用して epel リポジトリをインストールします。
    $ sudo rpm -ivh epel-release-6-8.noarch.rpm
    

ModSecurity のインストール

yum でインストールします。
mod_security (ModSecurity本体)、mod_security_crs(Core Rule Set)、及び、mod_security_crs-extras(追加のCore Rule Set) の三つをインストールします。
※Core Rule Set は一般的なWebサイトに対する攻撃を検知するためのルールを定義したものになります。

$ sudo yum install mod_security mod_security_crs mod_security_crs-extras

ModSecurity の設定

  1. 上記をインストールすると設定ファイルが作成されるのでこれを編集します。
    $ sudo vi /etc/httpd/conf.d/mod_secuirty.conf
    
    以下部分を編集します (抜粋)。
        # ModSecurity Core Rules Set configuration
            Include modsecurity.d/*.conf
            Include modsecurity.d/activated_rules/*.conf
        # 以下は mod_security_crs-extras 設定 (必要に応じて追記)
        Include /usr/lib/modsecurity.d/experimental_rules/*.conf
        Include /usr/lib/modsecurity.d/optional_rules/*.conf
        Include /usr/lib/modsecurity.d/slr_rules/*.conf
    
        # Default recommended configuration
    #    SecRuleEngine On
        SecRuleEngine DetectionOnly
    
    SecRuleEngine 設定を "DetectionOnly" に設定する事で、攻撃を検知した場合に、リクエストをブロックせずに、検知内容をログ出力するようになります。

    ※上記設定では、mod_security_crs-extras の設定については、インストール先の設定ファイルを直接インクルードしていますが、mod_security_crs で設定されているのと同じように、/etc/httpd/modsecurity.d/activated_rules ディレクトリからシンボリックリンクを張った方がいいかもしれません。
    この辺りの設定はお好みでどうぞ。

    全てのCore Rules Set に関して検知するのではなく、SQLインジェクション や クロスサイトスクリプティング に関するチェックのみ行うといった場合は、以下のようにします。

    #    Include modsecurity.d/activated_rules/*.conf
        Include modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf
        Include modsecurity.d/activated_rules/modsecurity_crs_41_xss_attacks.conf
    
  2. Mod Security の設定を行ったら apache を (再)起動します。
    $ sudo /etc/rc.d/init.d/httpd restart
    

Mod Security ログの確認

Mod Security のログファイルは 上記 mod_security.conf 中で出力先が定義されています (SecAuditLog)。
デフォルトでは、/var/log/httpd/modsec_audit.log に設定されているので、このログファイルをチェックする事で、どのようなアクセスがチェックに引っかかったかを確認する事ができます。

以下に出力ログの一例を示しますが、はっきり言って判りにくいと思います。
Mod Security に相当慣れている方でもないと、このログを見てどのような問題が発生しているのか判定するのは難しいのではないか?と思います。

--d3ae0f4f-A--
[20/Apr/2014:22:44:16 +0900] U1PPMKwfEiEAAC59@iUAAAAH 122.18.213.123 48448 172.31.18.33 80
--d3ae0f4f-B--
GET / HTTP/1.0
User-Agent: check_http/v1.4.16 (nagios-plugins 1.4.16)
Connection: close

--d3ae0f4f-F--
HTTP/1.1 302 Found
Pragma: no-cache
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://www.agilegroup.co.jp/index.html
Content-Type: text/html;charset=UTF-8
Content-Length: 0
Connection: close

--d3ae0f4f-E--

--d3ae0f4f-H--
Message: Warning. Operator EQ matched 0 at REQUEST_HEADERS. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "29"] [id "960008"] [rev "2"] [msg "Request Missing a Host Header"] [severity "WARNING"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"]
Message: Warning. Operator EQ matched 0 at REQUEST_HEADERS. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "47"] [id "960015"] [rev "1"] [msg "Request Missing an Accept Header"] [severity "NOTICE"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/MISSING_HEADER_ACCEPT"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"]
Message: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_60_correlation.conf"] [line "37"] [id "981204"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5, SQLi=, XSS=): Request Missing an Accept Header"]
Apache-Handler: proxy-server
Stopwatch: 1398001456285107 2997 (- - -)
Stopwatch2: 1398001456285107 2997; combined=1031, p1=272, p2=595, p3=3, p4=62, p5=97, sr=99, sw=2, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/); OWASP_CRS/2.2.6.
Server: Apache
Engine-Mode: "DETECTION_ONLY"

--d3ae0f4f-Z--

偽陽性判定があった場合

問題ないリクエストが偽陽性判定された場合には、auditログを確認しid ( [id "XXXXXX"] ) をチェックします。
例外として mod_security.conf に除外設定を行います。

$ sudo vi /etc/httpd/conf.d/mod_secuirty.conf
以下を追記
    # id= 960008 は偽陽性
    SecRuleRemoveById 960008
※管理画面等の特定パスのみ除外したい場合、以下のように設定する事で対応可能
( 特定のディレクトリに対し、SecRuleEngine Off を指定して mod_security 自体を無効にするといった指定も可能 )
 <LocationMatch /path/to/application>
     SecRuleRemoveById 960008
 </LocationMatch>
設定変更後はapacheを再起動します。
$ sudo /etc/rc.d/init.d/httpd restart

管理ツール ( AuditConsole ) の導入

上述の通り、Mod Security のログを解析するにはそれなりのスキル、及び、慣れが必要と思われます。
幸い、これらログをGUIから閲覧可能にするためのツールがあるので、これを利用して解析・管理にかかる労力を軽減する事にします。

AuditConsole は Mod Security が出力する audit イベントを管理する事ができるアプリケーションです。
J2EEアプリケーション(JavaのWebアプリケーション) として実装されており、Webブラウザからアクセスする事で、以下のような事が行えます。

  • audit イベントの収集、保存
    mlogc ( ModSecurity log collector ) を利用するか、直接 audit.log をインポートしてイベントを収集する事ができます。
    収集されたイベントはDBに保存されます。
  • GUIによるイベント情報の閲覧
    ログファイルを直接見るのに比べると情報のチェックはかなりやり易くなるはずです。
    保存されたイベントのフィルタリング等も随時行えます。
  • ビューの定義
    ユーザー毎にビュー定義が行えます。チェック・管理したいイベントを抽出するビューを定義する事で、特に定期的なチェックがやり易くなります。
  • イベントへのタグ付け
    イベントへのタグ付けが行えます。ブックマーク的に利用したり、偽陽性と思われるイベントに自分で定義したタグをつけておいて、後でタグでフィルタリングを行うといった使い方ができます。
  • ルールの定義
    ルール定義のための簡単な機能があります。
    これに関しては、まだ使っていないため大した事が言えませんが、フィルタリングルール(=チェックしたい情報を抽出するためのルール)に適合したイベントに対してアクションを行うためのルールを生成できるようです。

AuditConsole のインストール

以下 AuditConsole のインストール手順に関して示します。

環境

インストール先の環境は以下になります。
今回のインストールでは既に稼働中の Tomcat 上に war ファイルを配備する方法で行うものとします。      
Javajava 1.7
Web Application Server Apache Tomcat 7
Windows上のxampp環境でも動作する事を確認しています。

パッケージの取得

AuditConsole のダウンロードページ からパッケージをダウンロードします。
このページを見ると 0.4.2-5 が最新と書いてありますが、ページに記載の latest release のリンク http://download.jwall.org/AuditConsole/current/ にアクセスしてみると、0.4.6 が最新だったりします(2014/4/23時点)。

以下では AuditConsole-0.4.6-13.war を取得したものとして話をすすめます。

war ファイルのデプロイ

取得した war ファイルを Apache Tomcat にデプロイします。
Tomcat の webapps ディレクトリにコピーします。
※Windows の xampp 環境であれば、C:\xampp\tomcat\webapps 等がコピー先になります。

Apache Tomcat が起動中であれば、war ファイルは自動的に展開されます。起動していない場合は、コピー後に起動してください。

AuditConsoleのセットアップ

  1. war ファイルが展開されたら AuditConsole のURLにWebブラウザでアクセスします。warファイル名を変更していない場合、URLは以下のようになります。

    http://Tomcatサーバ名:ポート番号/AuditConsole-0.4.6-13
  2. AuditConsole にアクセスするとログイン画面が表示されるのでログインします。
    初期状態では admin / admin でログイン可能になっています。
    AuditConsole Login
  3. 初回アクセス時にはセットアップ処理が実行されます。
    先ず、Term of use & Copyright Notece ( 利用規約 & 著作権表示 ) 画面が表示されます。
    AuditConsole Term of use & Copyright Notice
    規約内容に問題なければ、画面下部の [ I accept these terms. ] にチェックし、[Ok]ボタンをクリックします。
  4. 規約に同意し次に進むと Basic Settings 画面になります。
    AuditConsole Basic Settings
    プロパティ設定内容
    Base Directoryログや設定ファイルが保存されるベースディレクトリを指定します。デフォルトではTomcatのベースディレクトリとなっているようです。
    別ディレクトにする場合適宜変更して下さい (ディレクトリは作成しておく事)。
    Base URLAuditConsoleのベースURL。
    メール通知の際に記載されるURLになるので受信者がアクセス可能なURLを記載する。
    REST APIREST APIを利用する場合チェックする
    SOAP APISOAP APIを利用する場合チェックする
    Allow OpenID+Google AccountsOpenID、及び、Google アカウントでのアクセスを許可する場合チェックする
    この画面では基本的にそのまま[Save]ボタンをクリックしても大丈夫です。
    API アクセスや OpenIDでの認証を行う場合には、必要に応じて該当する項目をチェックして下さい。
  5. Basic Settings を保存すると Storage Engine 設定ページに遷移します。
    AuditConsole Storage Engine ここではイベントデータを保存するデータベースの設定を行います。
    プロパティ設定内容
    JDBC URLデータを保存するDBのJDBC URLを指定します。
    デフォルトでは組み込みのDerbyデータベースを利用する設定になっています。
    UserJDBC接続で利用するユーザIDを指定します。
    PasswordJDBC接続で利用するパスワードを指定します。
    Storage Typeストレージタイプを選択します。
    Data directoryデータ保存先ディレクトリを指定します。
    Database limitデータベースサイズの上限を指定します。
    デフォルトではAuditConsoleに組み込まれているJavaDB(Derby)を利用する設定になっています。MySQL等の外部DBをストレージエンジンとして利用する場合、AuditConsole用のデータベースを生成しこのデータペースを利用するようにJDBC設定を行う必要があります。
    ここではDerby を利用するものとして、値は変更せずに先に進めます。
    [Save]ボタンをクリックします。
  6. データベース設定が問題なく行われれば、AuditConsole が利用可能になります。
    AuditConsole Storage Engine

ユーザ設定の変更

セットアップが完了したら、必要に応じてユーザー設定を変更しておきましょう。

  1. 画面右上の [User Settings] をクリックします。
  2. User Details 画面が表示されるので、User Name を必要に応じて変更し、[Save]ボタンをクリックします。
  3. 左メニューにある [Change Password] をクリックします。
  4. "Old Password:" 欄に現在のパスワード(admin) を入力し、"New Password:"、及び、"Confirm new Password:" に新しいパスワードを入力して [Save] ボタンをクリックします。
    パスワードが変更されれば、The password has sucessfully been changed! メッセージが表示されます。

AuditConsole の利用

AuditConsole で ModSecurity の Audit ログをチェックしてみます。

実運用環境等では mlogc ( ModSecurity log collector ) を利用してログを収集するべきでしょうが、環境によっては設定が難しいといった問題もあるため、今回は audit ログを AuditConsole にインポートする方法に関して説明します。

audit ログのインポート

  1. AuditConsole のメニューから [Events]>[Upload] をクリックします。
    AuditConsole Events Upload
  2. Log-File Upload 画面に遷移するので、[参照...] ボタンをクリックして ModSecurity の audit ログファイルを選択し、[Upload] ボタンをクリックします ( audit ログファイルはSCP等で事前に取得して下さい )。
    AuditConsole Events Upload

    ファイルがアップロードされると、以下メッセージが表示されます。
    Successfully uploaded the file. It is a ModSecurity 2.x Serial Audit-Log log-file.
    Processing of the file has been scheduled.

イベントを見る

ログファイルインポート後に Dashboard 画面に遷移すると、アラートが表示されているのが確認できるはずです。
Dashboard画面の右側にはグラフが表示されており、mlogc を利用してリアルタイムにイベントを取得している場合にはアラートの発生状況がグラフ表示されます。
AuditConsole Dashboard

Events メニューをクリックする事で、保存されている全イベントの表示、及び、フィルタリングが行えます。
下図では、社内からのアクセスを除外するフィルタをかけています。
AuditConsole Events

ログを確認すると判りますが、WARNING 以上のアラートイベントについては、確かに怪しげなアクセスが多いのが判ります。

ModSecurityの実運用

検知されているイベントに問題がなさそうだったら、問題があるリクエストをブロックする設定に変更します。

  1. mod_security.conf を編集 ( DetectionOnly → On )
    SecRuleEngine On
    # SecRuleEngine DetectionOnly
    
  2. apache 再起動
    $ sudo /etc/rc.d/init.d/httpd restart
    
  3. 実際に動作確認し、問題ないかチェック
  4. 実運用環境へのModSecurity導入

運用開始後も定期的にイベントを確認し、問題がないかどうかチェックするべきです。

まとめ

WAFを利用する事で、Webサイトの脆弱性を狙ったアクセスをある程度防御する事が可能になります。

ModSecurity はソフトウェア自体は無料で利用する事ができるため、DetectionOnly 設定で運用し、Webサイトに対してどのような脆弱性を狙った攻撃がなされているか把握する 目的で利用する方法もありでしょう。

この場合も、全てのルールを一度に適用せずに、Web Appplication Firewall 読本 での実例のように SQLインジェクション だけに絞って検知する等、影響の大きな脆弱性に絞って適用を行うなど、運用負荷を急激に増やさない形で適用していくのがよいと思います。

実際に攻撃がなされていて、セキュリティ面での不安がある場合、以下のような選択肢が考えられますが、これに関しては、運用負荷やコスト等を考慮して決定すればよいのではないでしょうか。

  • アプリケーションの改修を行う
  • ModSecurityを利用したWebサイトの防御を行う
  • 商用のWAF製品やサービスを利用してサイトを防御する