shin-ch13のエンジニア日記

知らぬは恥、やらぬは逃げ

WebGoat+OWASP ZAP/Burp Suiteで脆弱性診断テスト環境を作る

セキュリティに関する仕事を約3年間行っているがこれといったテクニカルなセキュリティスキルが身についていないと思い、 Webアプリケーション診断について基礎的な勉強をしたのでその記録になります。

学習に際しては下記書籍を活用した。

脆弱性診断とは

脆弱性はコンピュータシステムを構成するネットワーク、OS、ソフトウェア等による 仕様上の問題やバグ、設計不備、プログラムおよび設定上のミスであり、 これにより発生する情報セキュリティ上の欠陥と言える。

脆弱性を放置すると悪意のある第三者が、許容していないアクションを実施できたり、 最悪の場合、システムに存在する機密情報を搾取することができてしまう。

脆弱性診断はこうした脆弱性を発見するためのテスト手法である。

脆弱性診断は大きく2種類に分類することができる。

本記事ではWebアプリケーション脆弱性診断について取り扱う

学習環境

Webアプリケーション脆弱性診断について学習するにあたっては 下記構成の環境を自身のローカルPC上に構築した。

f:id:shin-ch13:20210106205534p:plain

OS:macOS Catalina 10.15.6

擬似サイト:WebGoat 8.0 (Docker desktop 2.1.0.5)

診断ツール:OWASP ZAP 2.10.0

診断ツール:Burp Suite Community Edition 2020.12.1

ブラウザ:Firefox 84.0.1

ブラウザ:Google Chrome 87.0.4280.88

WebGoat

github.com

hub.docker.com

WebGoatは、OWASPによって提供されている意図的に安全でない状態で用意された Webアプリケーションサイトであり、Webアプリケーションのセキュリティ学習を行えるように設計されています。

イメージはDockerでも提供されているため簡単に構築を行うことができる。

OWASP ZAP

www.zaproxy.org

OWASP ZAPはOWASPがOSSで開発したWebアプリケーション用の自動脆弱性スキャンツールである。 OWASP ZAPをローカルのプロキシとして使用し、ブラウザ(今回の場合Firefox)の通信を OWASP ZAP経由で行うことで経由された通信内容の確認、診断のためのリクエストの改竄を実現している。

OWASP ZAPのスキャンは大きく3つ存在する。

  • 簡易スキャン:
    WebアプリケーションのルートURLを入力すると、OWASP ZAPがその配下をクロールして脆弱性診断を行う。

  • 静的スキャン:
    Webアプリケーションの基本的な機能をブラウザを通じて動かすと、 OWASP ZAPがリクエストおよびレスポンスのHTTPメッセージを記録し、その内容から脆弱性診断を行う。 安全に負荷なく診断できるが、インジェクション系の脆弱性は診断できない欠点がある。

  • 動的スキャン:
    静的スキャンで行った操作を、OWASP ZAPがパラメータやヘッダーを変えて再実行し 脆弱性診断を行う。

Burp Suite

portswigger.net

Burp SuiteはPortSwigger社が開発したWebアプリケーション用の手動脆弱性スキャンツールである。 無料版(Free Edition)と有料版(Professional Edition)の二種類が存在し、 有料版は自動診断ができたり、無料版では診断プロジェクトを一時的なものとして扱えないが、 保存できるような機能も備わっている。

なおOWASP ZAPと同様でローカルのプロキシとして使用し、ブラウザ(今回の場合Firefox)の通信をBurp Suite経由で行うことで 経由された通信内容の確認、診断のためのリクエストの改竄を実現している。

またOWASP ZAPよりも手動性に特化しており自由度が高いため、やや操作の習熟が必要となるが Webサイトのデバッグにも利用することができる。 その点で言えば、HTTPプロトコルに特化したWireSharkとも言えるかもしれない。

インストール

OWASP ZAPとBurp Suiteは下記URL先よりダウンロードできる。

OWASP ZAP

Download Burp Suite Community Edition - PortSwigger

WebGoatはDockerをインストールした上で下記コマンドを実行することで Webgoatサイトを立ち上げることができる。 今回は「localhost:8000」をdockerコンテナの8080/tcpにフォーワードディングするよう設定している。

docker pull webgoat/webgoat-8.0
docker run -p 8000:8080 -t webgoat/webgoat-8.0

http://localhost:8000/WebGoat/loginにアクセスすることでサイトが表示される。 「Register new user」にてアカウントを作成するとログインできる。

f:id:shin-ch13:20210105235755p:plain
WebGhoatログイン画面

f:id:shin-ch13:20210106000219p:plain
WebGhoatトップ画面

ローカルプロキシ設定

OWASP ZAPのローカルプロキシ設定

OWASP ZAPのローカルプロキシ設定は[ツール]->[オプション]より設定できる。
デフォルトで「localhost:8080」がローカルプロキシ起動先となっているが、 別プロセスで利用している場合には変更する。

Explore 項目にて[Forefox]を選択の上[Launch Browser]をクリックすると、 プロキシ設定済みの状態でFirefoxブラウザを起動することができる。

f:id:shin-ch13:20210223152953p:plain
OWASP ZAPローカルプロキシ設定

Burp Suiteのローカルプロキシ設定

Burp Suiteのローカルプロキシ設定は[Proxy]->[Options]より設定できる。
OWASP ZAPと同様にデフォルトで「localhost:8080」がローカルプロキシ起動先となっているが、 別プロセスで利用している場合には変更する。 ※OWASP ZAPとBurp Suiteは動作の整合性上、同時に起動しない方がいい。

[Proxy]->[Intercept]にて[Open Browser]をクリックすると、 プロキシ設定済みの状態でGoogle Chromeブラウザを起動することができる。

f:id:shin-ch13:20210106205908p:plain
BurpSuiteローカルプロキシ設定

OWASP ZAPを使った脆弱性診断

プロテクトモードの設定

スキャンする上での注意事項

OWASP ZAPを勉強で使う場合、関係しないサイトに検査通信を行わないよう「プロテクトモード」で行う。  

  • セーフモード:
    コンテキストに登録しても、クローリングや動的スキャンはできない。
  • プロテクトモード:
    コンテキストに登録したサイトのみ診断対象。
  • 標準モード:
    見つけたサイトは外部でも診断対象。
  • 攻撃モード:
    コンテキスト登録したサイトのみ診断対象(自動的にリアルタイム診断開始)

f:id:shin-ch13:20210223155827p:plain
BurpSuiteプロテクトモードの設定

診断サイトをコンテキストに登録するには、[Launch Browser]をクリックして診断サイトにアクセス後、 サイドバーに表示された診断サイトURLを右クリックし、
[コンテキストに含める] -> [New Contents]に設定ができる。
コンテキストに登録が完了するとサイドバーに表示された診断サイトのフォルダアイコンに赤い丸印がつく。

f:id:shin-ch13:20210224191441p:plain
コンテキストに登録するURLの選択

f:id:shin-ch13:20210224191505p:plain
コンテキストの登録確認

静的スキャン

Manuual Explore(静的スキャン) にて[Launch Browser]をクリックして診断サイトにアクセスする。 静的スキャンでは、ブラウザで画面操作を行うことで、 同時にローカルプロキシであるOWASP ZAPがリクエスト/レスポンスを検査し脆弱性を発見する。

脆弱性を発見するとブラウザの右下に内容がポップアップされる。
また、ブラウザの左サイドバーに現在表示しているページ内の脆弱性が記録され、 ブラウザの右サイドバーに現在診断しているサイト内の脆弱性が記録される。

脆弱性はリスクに応じてHigh/Medium/Low/Infoの4つに分類される。

f:id:shin-ch13:20210223162910p:plain
静的スキャン実行画面

発見した脆弱性の詳細情報はOWASP ZAP上の画面から確認できる。
下画面の[アラート]タブより対象の脆弱性と該当するURLをダブルクリックすると脆弱性の詳細情報が表示される。 上画面には脆弱性を判断した該当のHTTPリクエスト/レスポンスが表示され、 上段にヘッダー情報、下段にボディ情報が表示される。

下記はWebGhoatの静的スキャンで発見されたjQuery脆弱性である。
Webサイトにてjquery-ui-1.10.4.jsを利用しており、ページ読み込みによるhttp://localhost:8000/WebGoat/js/libs/jquery-ui-1.10.4.jsへのアクセスに対して、
正常応答が返された頃から、脆弱性として認識している。

Tips

リクエスト/レスポンスのエリアで右クリック[再送信]を実行することで

脆弱性を確認したHTTP通信を再度実行することができる。

f:id:shin-ch13:20210223165146p:plain
静的スキャンにより発見されたjQuery脆弱性

発見された脆弱性の詳細を確認するには画面でも確認できるが、 OWASP ZAPで概要のみしか掲載されないケースもあるため詳細情報を調べる場合には、 [その他の情報]に記載のあるCVE番号(下の例だとCVE-2016-7103)よりネットで検索を行い確認すると良い。

Tips

CVE番号はソフトウェアの脆弱性に対して与えられる脆弱性を一意に識別する番号である。

ただし、SQLインジェクションクロスサイトスクリプティングのようなプログラムミスによる脆弱性にはこの番号はふられない。

CVE-2016-7103はjQuery UI が保持するクロスサイトスクリプティング脆弱性であり、 jQuery UI 1.12.0 未満にて発生する。脆弱性を保持しているとリモートの攻撃者により、 dialog 関数の closeText パラメータを介して、任意の Web スクリプトまたは HTML を挿入される可能性があります。
ベンダより正式な対策が公開されています。ベンダ情報を参照して適切な対策を実施してください。
https://jvndb.jvn.jp/ja/contents/2016/JVNDB-2016-007993.html

スパイダー検索

静的スキャンにおいてWebサイト上の1通りの巡回が終わったら、スパイダー検索を行う。 スパイダー検索は、手動では見付からなかったページを自動で探すいわゆる自動クロール機能であり、同時に静的スキャンも行われます。

またスパイダー検索およびこの後行う動的スキャンでは、診断サイトがWebGhoatのような認証を必要とする場合、 自動的にログインができるようにコンテキストに認証の設定が必要になります。 設定しておくことで、もしログアウトを自動クロール中に実行してしまっても、 ログインしていない事を検知して自動ログインを実行することができる。

上記を設定するには、下画面の[履歴]タブよりログインが成功した際のリクエスト通信 (今回の場合、http://localhost:8000/WebGoat/loginへのPOSTリクエスト)を検索し、 右クリックで[【コンテキスト名】:Form-based Auth Login Request]を選択する。

f:id:shin-ch13:20210223182407p:plain
自動ログイン用のコンテキスト設定(1/2)

Form-based Auth Login Requestのコンテキストは下記のように設定します。

Tips

Regex pattern identified in Logged Out response Message欄に「\Q/WebGoat/login\E」と記載します。

 

これはログアウト状態を判定するため、ログアウト時のレスポンス内容を登録する必要があるためです。

(「\Q」と「\E」で囲んで記述します。)

f:id:shin-ch13:20210223182411p:plain
自動ログイン用のコンテキスト設定(2/2)

自動ログインの設定が完了したら、スパイダー検索を実行します。
サイドバーに表示されている診断サイトURLから開始位置のURLで
右クリック[攻撃]->[スパイダー]を選択します。 表示されたポップアップ画面において、[ユーザー]欄に先ほど作成した自動ログインのコンテキストを選択し、 スパイダー検索を実行します。

f:id:shin-ch13:20210223182416p:plain
スパイダー検索の実行

f:id:shin-ch13:20210223183825p:plain
スパイダー検索の実行結果

スパイダー検索で596件のURIを検知しました。実行後、下画面の[アラート]タブを再度表示すると、 発見したURIへの静的スキャン結果として脆弱性の詳細情報が表示されます。

f:id:shin-ch13:20210223184206p:plain
スパイダー検索で発見された脆弱性

動的スキャン

次にOWASP ZAPの動的スキャンを実行します。
自動的にログインができるようにスパイダー検索と同様に[ユーザー]欄にコンテキストを設定して実行します。

動的スキャンでは事前に検知したURIに対してスキャンを実行します。

実行する前に静的スキャンによるブラウジング/スパイダー検索を行い、

OWASP ZAPにスキャンするURIを認識させておきましょう。

注意

動的スキャンはリクエストパラメータを付与/変更して攻撃コードをWebサイトに送り込みます。

実際のサイトにスキャンを行う際には、サイトの管理者に必ず確認をとりましょう。

またプロテクトモードを再度確認して、意図せず他のサイトをスキャンしないようにしましょう。

f:id:shin-ch13:20210224205103p:plain
動的スキャンの実行

f:id:shin-ch13:20210224190519p:plain
動的スキャンの実行結果

f:id:shin-ch13:20210224190524p:plain
動的スキャンで発見された脆弱性

約2時間、約3万件の検査リクエストを行い動的スキャンが完了しました。
[アラート]タブを再度表示すると、 発見したURIへの動的スキャン結果が追加され脆弱性の詳細情報が表示されます。

リスクHighの脆弱性として下記が検出されました。

OWASP ZAPのような自動診断ツールは誤検知や見逃しが生じている可能性があります。

脆弱性の再現は後述するBurp Suiteやブラウザを利用して、検査スキャンと同じリクエストを送ることで確認する必要があります。

レポートの作成

OWASP ZAPの便利な機能の1つとしてレポート出力機能があります。
OSのOWASP ZAPメニュータブ[レポート] -> [(出力形式) レポート生成]で出力することができます。

f:id:shin-ch13:20210223231105p:plain
HTMLレポートの出力

f:id:shin-ch13:20210223231428p:plain
HTMLレポートの出力結果

BurpSuiteを使った脆弱性診断

前述した通り、自動診断ツールでは誤検知の可能性があります。
そのため、診断ツールで脆弱性を発見した検査スキャンと同じリクエストを送ることで再現性を確認します。

BurpSuiteはHTTPの通信をローカルプロキシとしてキャプチャすることにより、
リクエストとレスポンスのHTTPメッセージを記録することができます。記録したHTTPメッセージは、 後で確認したり、再利用してHTTPメッセージを一部編集して再送信することができます。

今回はOWASP ZAPで発見した下記クロスサイトスクリプティング(反射型)とSQLインジェクション脆弱性の再現をBurpSuiteを用いて確認します。

f:id:shin-ch13:20210224190222p:plain
OWASP ZAPで発見したクロスサイトスクリプティング(反射型)の脆弱性

f:id:shin-ch13:20210224190217p:plain
OWASP ZAPで発見したSQLインジェクション脆弱性

BurpSuiteの基本操作について

検査スキャンを再現するには、まず脆弱性が見つかったURLへ BurpSuiteローカルプロキシを介してアクセスします。

その後、[Proxy]タブの[HTTP history]から対象の通信を選択し、 右クリック[Send to Repeater]を実行します。

Tips

[Send to Repeater]は履歴に記録したリクエストを再度BurpSuiteから送信する機能です。

送信する際にはHTTPリクエストメッセージを編集することもできます。

クロスサイトスクリプティング(反射型)診断

クロスサイトスクリプティング(反射型)は攻撃者が指定したコードを反射的にユーザーのブラウザ インスタンスに紛れ込ませる攻撃手法です。 自分が書いたスクリプトを実行しただけでは、特に悪影響が生じるわけではないが、 他人をこのURLにアクセスさせることで、アクセスした人のブラウザ上で任意のスクリプトを実行させることが可能となります。 その結果、ページをリダイレクトさせたり、任意のコードを実行させることも可能となります。 入力値やリクエストをコードとして認識しないよう無害化することが対処方法の1つとなります。 https://www.ipa.go.jp/files/000024726.pdf

脆弱性の解説

下記サイトは「Enter your credit card number:」に入力されたパラメータfield1をそのまま結果出力している。

そのためHTMLタグで囲ったソースを記載することでクロスサイトスクリプティングが成立する。

OWASP ZAPの検査パラメータでは「 <img src=x onerror=alert(1);>」を入力し、画像読み込み失敗のerrorイベントを発生させることで

javascriptコードの「alert(1)」を実行させている。

f:id:shin-ch13:20210224191548p:plain
対象診断ページの応答確認

f:id:shin-ch13:20210224001921p:plain
パラメータfield1へクロスサイトクリプティングの実行

SQLインジェクション診断

SQLインジェクションは、Webアプリケーションの脆弱性により本来の意図ではない不当なSQL文が作成されてしまい、 インジェクションされることによって、データベースのデータを不正に操作される攻撃手法です。 SQLインジェクションの攻撃を受けると、データが読み取られたり、データが改ざんまたは削除されたりすることがあります。 入力値やリクエストをSQLインジェクションが発生しないよう無害化することが対処方法の1つとなります。 https://www.ipa.go.jp/security/vuln/websecurity-HTML-1_1.html

脆弱性の解説

下記サイトは「Employee Name:」に入力されたパラメータnameおよび

「Authentication TAN:」に入力されたパラメータauth_tanをバックエンドで実行しているSQL

「"SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "';」

に格納して、その結果を出力している。

シングルクオーテーションで括られており一見無害化されている様にも見えるが値をそのまま格納していることから、

「 ZAP' OR '1'='1' --」を入力値として与えることでシングルクオーテーションを閉じ、かつ全てにマッチする条件「OR '1'='1'」を付加し、

さらに「--」で残りのSQLをコメント文にすることができる。

SQLインジェクションの成立により、テーブルの全ての情報を表示してしまっている。

f:id:shin-ch13:20210224191529p:plain
対象診断ページの応答確認

f:id:shin-ch13:20210224013659p:plain
パラメータauth_tanへSQLインジェクションの実行

以上より、OWASP ZAPで発見したクロスサイトスクリプティング(反射型)とSQLインジェクション脆弱性は、 誤検知ではなく、脆弱性が存在し攻撃が成立することが確認できた。

最後に

今回はWebアプリケーション脆弱性診断について疑似診断環境を作って学びました。 脆弱性が実際に発見/再現した際には面白みがありましたが、実際にこれをお客様環境に行う際には、 サイト構造の把握からきちんと行う必要があり、また自動診断の誤検知やその振り分けはかなり大変だと思いました。

また自動診断を行っていてWebGhoat内の脆弱性が一部検知されていないことに気づきました。 こうした脆弱性を見つけるには、BurpSuiteなどで検査通信を送り、その応答から発見するスキルが必要になり、 脆弱性に対する理解と攻撃方法(検査方法)の幅広い知識が必要になると思いました。

今回取り上げた、SQLインジェクションクロスサイトスクリプティングを含め検査方法/脆弱性埋め込み方は、 Webサイトによって異なるため、この点も必要になってきます。

WebGhoatの他にEasyBuggyなど世の中には、Webアプリケーション脆弱性診断を勉強するための 疑似診断サイトを安易に構築できるソフトウェアがあるので、これらを活用してさらにスキルを高めたいと思います。