このエントリーは、GMOアドマーケティング Advent Calendar 2018の 【12/12】 の記事です。
GMOアドマーケティングとしては初のAdvent Calendar参戦です。
こんにちは。GMOアドマーケティングのN.Sです。
この度Webアプリケーションの脆弱性診断について研修を受けたので、内容について共有します。
OWASP ZAPという自動診断ツールを使って、診断から対策までの流れをざっと説明します。
環境
Mac:10.12.6(Sierra)
OWASP ZAP:2.7.0
Burp Suite:1.7.36
インストール
OWASP ZAP:https://github.com/zaproxy/zaproxy/wiki/Downloads
Burp Suite:https://portswigger.net/burp/communitydownload
対象サイト
今回は脆弱性診断レッスン用のサイト「WebGoat」をローカル環境に構築して利用します。
環境構築
WebGoatはDockerでイメージ化されているので、誰でもdocker pullすることができます。
$ docker pull webgoat/webgoat-8.0
$ docker run -itd -p 127.0.0.1:10080:8080 webgoat/webgoat-8.0
これで「http://localhost:10080/WebGoat」にアクセスし、ログイン画面に入れればOKです。
(入れない場合は、ポートフォワーディングが8080に向いてないか、アドレスに「/WebGoat」を付けてないことが多いです。)
診断
環境ができたら、早速診断していきましょう。
診断にはOWASP ZAPというWebアプリケーション自動診断用のツールを使います。(Mac/Windows共に対応)
引用元:https://github.com/zaproxy
開くと以下のような画面が開きます。
▼診断の流れです
1.静的スキャン
・対象Webサイトのクロール
・静的スキャン
2.動的スキャン
・診断用にパラメータを付加してレスポンスを自動診断
3.スキャン結果の精査
・1,2の結果が正しいのか手動で確認
4.脆弱性対応
1.静的スキャン
対象Webサイトをクロールし、いくつURIがあるのかなど確認できます。
この静的スキャンだけでも少し脆弱性は分析してくれるのですが、どちらかというと後ほど行う動的スキャンの事前準備の意味合いが強いです。
まずOWASP ZAPで「クイックスタート」→「Launch Browser」押下でOWASP ZAPをプロキシとして設定されたブラウザを立ち上げます。
これによって、CookieをOWASP ZAPで保持してくれるため、ブラウザと自動診断の状態を連携させることができます。
サインアップしてサイト内を巡回してみます。
サイドバーとコンテンツエリアの画面構成になってます。
※ここでサイドバーのボタンを全てクリックしておいてください。
OWASP ZAPのサイト一覧がどんどん増えてくのが分かると思います。
これを「手動クロール」といいます。
OWASP ZAPのクロール機能である程度ページは網羅してくれるのですが、#(ハッシュタグ)や?(クエリパラメータ)で指定するページは自動クロールしてくれません。
そのため、手動でポチポチOWASP ZAPに認識させていく必要があるのです。。
手動クロールできたら、次は「スパイダー機能」で自動クロールさせましょう。
下側のタブで「スパイダー」タブを選択→「新規スパイダー」押下
開始位置に「http://localhost:10080/WebGoat」を指定し、「スキャン開始」します。
自動クロール後、画面がログアウトされていますね。。汗
どうやらログアウトボタンを踏んでそれっきりになっているようです。
これではクロールもままなりません。
認証を突破する方法はいくつか存在するのですが、ここではForm-based認証を紹介します。
「既定のコンテキスト」→「認証」にてログイン時の認証方法を設定しておきます。
一番下の欄に「\Q/WebGoat/login\E」とありますが、これはログアウト状態を判定するため、ログアウト時のレスポンス内容を一部で良いので登録しています。(「\Q」と「\E」で囲む必要があります。)
続いて突破用のユーザを作ります。
「既定のコンテキスト」→「ユーザ」でログインできるユーザを登録します。
再度スパイダーで自動クロールします。
今度は「ユーザー」に今ほど登録したユーザを設定します。
これでログアウトされずに自動クロールできました。
検出URI数も結構増え、私の環境だと475件となりました。
ほぼ全てのURIを検出できたと思うので、次は動的スキャンを行います。
2.動的スキャン
動的スキャンでは、先程と同じコンテキストを使い、実際に攻撃コードを仕掛けていきます。
その前に、動的スキャンは静的スキャンと何が違うのか簡単に説明します。
静的スキャンは各ページを単にクロールしており、攻撃コードは送っていませんでした。
動的スキャンはパラメータを付与・変更し、あらゆるパターンの攻撃コードをシステムに送り込みます。
例えばログイン画面で以下のようなパラメータがあったとします。
Username=user01
Password=ZAP ←間違っている
上記内容では本来ログインできませんが、以下のようなパラメータに変更してログインできるか検査しています。
Password=ZAP OR 1=1 —
また、動的スキャンを行う前に以下のことをお願いします。
・プロテクトモードに設定
コンテキストで指定したURL内にのみ攻撃するモードです。
「コンテキスト」→「コンテキストに含める」にて「http://localhost:10080/WebGoat.*」と登録してください。
・実際に攻撃するため、データのバックアップを取るなど、万が一に備えておきましょう。
・何万件というリクエストを投げるので、インフラ担当や場合によってはクラウド事業者に一言伝えておきましょう。(BANされる恐れがあります。)
・IPS(侵入防止システム)をオフにしておきましょう。
IPSでリクエストが遮断され、アプリケーションの診断ができなくなるのを防ぐため。
それでは自動スキャンをかけます。
下タブの「自動スキャン」→「新規スキャン」押下。
(コンテキストやユーザはスパイダーと同じ設定にします。)
自動スキャンを開始しますが、結構時間がかかります。
WebGoatだと2〜3時間ほどかかりました。
(ちなみにスキャン結果はセッションファイル化できるので、講習などではセッションファイルを渡しちゃうことも多いです。)
2時間後・・・
71171件のリクエストを投げてくれ、スキャン結果がずらずらと出ています。
3.スキャン結果の精査
下のアラートタブを見ると、SQLインジェクションなどクリティカルな脆弱性が検知されています。
とはいえ、OWASP ZAPは結構誤検知も多いため、本当に脆弱性が存在するのか手動で精査する必要があります。
今回はXSSを精査してみます。
(IPアドレスが先程までと変わっているのは気にしないでください(^_^;))
対象のページはこんな感じのユーザIDを入力して、関連情報を出力するページのようです。
さて、このページで脆弱性を検知した際の攻撃コードを送ってみるのですが、その際にBurp Suiteというプロキシツールを使います。
▼Burp Suiteインストールサイト
https://portswigger.net/burp/communitydownload
まずはプロキシの設定です。
「Proxy」→「Options」でProxyListenerを設定します。
新規ブラウザを立ち上げ、上記で設定したプロキシを通るよう設定します。
「設定」→「接続設定」で手動プロキシを設定します。
▼FireFoxの例
プロキシを設定したブラウザで攻撃時のリクエストを投げます。
するとBurp Suiteがリクエストをインターセプトしてくれるので、パラメータを攻撃コードに変えてみます。
WebGoat画面で攻撃コードが実行されたことが確認できました。
この流れで各アラートに対して精査を行っていきます。
(これがかなり時間がかかります。)
4.脆弱性対応
見つかったXSSに対して対応しましょう。
▼XSSの場合だと、以下のような対応策を施すべきです。
・ウェブページに出力する全ての要素に対して、エスケープ処理を施す。
記号文字(「」、「&」等を、HTML エンティティ(「<」、「>」、「&」等)に置換
・URL を出力するときは、「http://」や 「https://」で始まる URL のみを許可する。
javascript:から始まるものは除外する
・要素の内容を動的に生成しない。
・スタイルシートを任意のサイトから取り込めるようにしない。
・Cookie 情報の漏えい対策として、発行する Cookie に HttpOnly 属性を加え、 TRACE メソッドを無効化する。
などなど
対応策を考えるにあたり、よく参考にされるのは、以下の資料です。
OWASPの公式サイト
https://www.owasp.org/index.php/Main_Page
IPAが発行している「安全なウェブサイトの作り方」
https://www.ipa.go.jp/files/000017316.pdf
まとめ
標準的なWebアプリケーションのスキャン実施〜対策までをざっくりご説明しました。
はじめてOWASP ZAPを使う際、適当にURLを入れてスキャンするだけでもある程度結果が出るので満足しがちなのですが、実はあまりページをカバーできてないというケースが多いようです。
そのため、最初のクローリングでしっかりページを網羅させておくことが診断漏れを防ぐためのミソです。
また、脆弱性診断は継続することが重要なのでCIに組み込んでおくと良いのですが、その辺の話もいずれブログにしたいところです。
ここまで読んで頂き、ありがとうございました!
明日は、【PHPとGo言語のURLパーサについて】についてのお話です。
お楽しみに。
クリスマスまで続くGMOアドマーケティング Advent Calendar 2018
ぜひ今後も投稿をウォッチしてください!
■エンジニアによるTechblog公開中!
https://techblog.gmo-ap.jp/
■Wantedlyページ ~ブログや求人を公開中!~
https://www.wantedly.com/projects/199431
■エンジニア採用ページ ~福利厚生や各種制度のご案内はこちら~
https://www.gmo-ap.jp/engineer/
■エンジニア学生インターン募集中! ~有償型インターンで開発現場を体験しよう~
https://hrmos.co/pages/gmo-ap/jobs/0000027