「ハッキング・ラボのつくりかた 完全版 仮想環境におけるハッカー体験学習」と「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践」(通称:徳丸本)を参考に、セキュリティの勉強を進めています。
今回は、徳丸本の 7章の「脆弱性診断入門」の OWASP ZAP の自動脆弱性スキャンについて、実際にやっていきたいと思います。
それでは、やっていきます。
参考文献
はじめに
「セキュリティ」の記事一覧です。良かったら参考にしてください。
セキュリティの記事一覧
徳丸本の環境構築については、以下の第9回でやりました。
daisuke20240310.hatenablog.com
この環境を使ってやっていきます。
日本語化や、Firefox でセキュリティ警告が出る対策などを追記しました。
あと、徳丸本のサポートML は以下です。困ったときは、ここを見ると、解決できるかもです。
https://groups.google.com/g/wasbook-readers
脆弱なサンプルアプリケーション(Bad Todo)の準備
徳丸本では、脆弱性を診断する対象として、Bad Todo という Webアプリケーションを用意してくれています。
これは、脆弱性仮想マシン(wasbook)の中に含まれていて、目次(https://example.jp/
)の「7 Bad Todo(脆弱性診断サンプルアプリケーション)」をクリックすることで、Bad Todo にアクセスすることが出来ます(https://example.jp/todo/
)。
では、早速アクセスしてみます。以下のようにトップページが表示されます。ログインをクリックします。
最初は、ユーザが登録されていないので、以下のように「こちら」をクリックします。会員登録とありますが、あくまでローカルの環境なので、どこかに登録した内容が通知されることはありません。
会員登録の画面になるので、なんでもいいので、適当に、ユーザID(daisuke)、パスワード(useruser)、メールアドレス(daisuke@gmail.com)と、適当な画像をアイコン画像として登録します。アイコン画像を登録せずに進んだら、「アイコン画像を登録してください」と出て、先に進めなかったので、登録が必要です。入力できたら「確認」をクリックします。
「入力を確認してください」と出るので、「登録」をクリックします。
「登録しました。」「続いて ログイン してください。」と出るので、「ログイン」をクリックします。
今決めた ユーザID とパスワードを入力して、「ログイン」をクリックします。
2件の Todo が登録されていますが、追加で1件登録します。
名前やその他を適当に入力し、添付ファイルも適当に用意したものを指定して、「登録」をクリックします。
これで準備は完了です。
いったんは、「公開」で登録しましたが、思い直して、非公開に変更しました。
「一覧」から、todo の「pentest」をクリックします。「編集」ボタンをクリックすると編集画面に遷移します。公開のところのチェックを外して、「更新」ボタンをクリックします。
※2024/8/18:追記
この時点で、データベースを保存しておきます。そうすると、データベースが壊れたときに、この状態に戻すことが出来ます。保存方法と復旧方法は後述します。
OWASP ZAPによる自動脆弱性スキャン
OWASP ZAP で、脆弱性診断を行うには、設定が必要なようです。
自動脆弱性スキャンの設定
これから自動脆弱性スキャンの設定を行っていきますが、設定の中には、一度設定すれば、OWASP ZAP を終了しても維持されるものと、毎回設定しなければならない設定が存在します。(自分用ですが)毎回しなければならない設定には黄色い下線を付けています。
OWASP ZAP に、たくさんのアクセスログがたまってる場合は、見にくいので、クリアしておくと見やすくなります。クリアする方法は、下図のアイコンをクリックするだけです。
では、Bad Todo にアクセスします。以降の図では(間違えて)ログインした状態になっていますが、ログインしていない状態で設定していきます。左側のペイン(子ウィンドウ)に todo というフォルダが出来ていると思います。この todo を右クリックして、コンテキストに含める→新規コンテキストをクリックします。
Regex のところに、https://example.jp/todo.*
となっていることを確認して、OK をクリックします。左のペインのコンテキストに、「todo」が追加されたと思います。何か操作を間違えた場合は、この todo のコンテキストを右クリック、削除してから、最初から設定しなおすことが出来ます。
次に、OWASP ZAP のウィンドウの左上の「標準モード」を「プロテクトモード」に変更します。この設定は OWASP ZAP を終了させても維持されています。
プロテクトモードに変更することにより、脆弱性診断を設定したコンテキストにのみ対象とすることが出来るようです。
続いて、セッションID名を設定します。ツール→オプション... で、Httpセッションをクリックし、追加をクリックします。トークン名に、「TODOSESSID」を入力して追加をクリックします。この設定も OWASP ZAP を終了させても維持されています。
さらに、アンチ CSRF トークンを設定します。同じく、ツール→オプション... で、アンチCSRF トークンをクリックし、追加をクリックします。トークン名に、「todotoken」を入力して追加をクリックします。この設定も OWASP ZAP を終了させても維持されています。
まだまだ設定が続きます。次は、自動ログインの設定です。Bad Todo にログインします。ログインすると、OWASP ZAP の左側のペインの todo フォルダに、POST:logindo.php
というのが見つかると思います。この POST:logindo.php
を右クリック→Flag as Context→todo : Form-based Auth Login Request をクリックします。
この設定は、OWASP ZAP の自動脆弱性スキャンが、ログインする POSTリクエストを特定するために設定するのだと思います。
すると、たくさんの項目があるダイアログが開くので、Username Parameter * のところを、「userid」を選択し、Password Parameter * のところを、「pwd」を選択し、OK をクリックします。
次に、左側のペインの todo フォルダの、先ほどの POST より下に、GET:todolist.php
が見つかると思います。この GET:todolist.php
を選択して、右側のレスポンスのペインから、<a href="logout.php" class="">
を探して、ドラッグして選択します。選択できたら、それを右クリックして、Flag as Context→todo : 認証ログイン表示をクリックします。
この設定は、OWASP ZAP の自動脆弱性スキャンが、ログインが成功したかどうかを判定できるようにするために設定するのだと思います。
すると、以下のように、上で設定したダイアログに、追加で、Regex pattern used to identify Logged in messages に、\Q<a href="logout.php" class="">\E
が設定されます。まだ OK は押さずに、続いて設定します。
左側のペインの、今設定していた 2: 認証
のすぐ下の 2: ユーザ
を選択します。
書籍では、自動的にログインしたユーザが登録されているような記述になっているのですが、実際にやってみると、ユーザは登録されていませんでした。なので、自分で登録します。
右上の追加をクリックし、ユーザ名を入力(たぶん任意だが、念のためログインするユーザID と同じにしておく)し、Username にログインするユーザID、パスワードにログインパスワードを入力して、追加をクリックします。
左側のペインの、2: ユーザ
のすぐ下の 2: 強制ログインユーザ
を選択します。すると、上で追加したユーザが表示されていることを確認して、OK をクリックして設定を閉じます。
これで設定は終わりました。
自動脆弱性スキャンのクローニング
自動スキャンを行うにあたり、対象サイトを自分で巡回する必要があるようです。そうすることにより、OWASP ZAP が、対象サイトのページに遷移するの URL と、パラメータを記憶するようです。
あまり分かってませんが、とにかく、ポチポチとリンクをクリックして巡回してみます。最初なので、Todo の登録や、マイページのプロフィールの変更などはせずに、あくまでリンクを辿るだけにしてみます。
一通り巡回が終わったら、OWASP ZAP の左上のコンテキストの「todo」を右クリックして、Export URLs for Context(s) をクリックして、任意の場所にクローニング結果を保存しておきます。
私の結果を貼っておきます。
https://example.jp/todo
https://example.jp/todo/export.php
https://example.jp/todo/icons
https://example.jp/todo/icons/_64_66ba0e1aac3d2-2024-08-03_15h28_57.png
https://example.jp/todo/import.php
https://example.jp/todo/index.html
https://example.jp/todo/inquery.php
https://example.jp/todo/login.php?url=todolist.php
https://example.jp/todo/logindo.php
https://example.jp/todo/mypage.php?rnd=66bb61e9e988a&id=3
https://example.jp/todo/newtodo.php?rnd=66bb61e042f60
https://example.jp/todo/todolist.php
https://example.jp/todo/todolist.php?key=pen
https://example.jp/todo/todolist.php?rnd=66bb61ef5761c
このファイルはインポートすることが出来ます。再診断するときに、また巡回するのは大変なので、このファイルをインポートします。インポート→Import a File Containing URLs で、ファイルを選択すればインポートできます。
これで、ようやく自動診断が出来るようになりました。
後ろの方で述べてますが、この時点で、セッションを保存するといいかもしれません。うまくいけば、再診断するときに、保存したセッションを使えば、同じ状態の診断が出来るかもしれません。
自動脆弱性スキャンの自動クローニング(スパイダー)
徳丸本でも言及がありますが、クローニングについては、OWASP ZAP のスパイダーという機能を使って、自動で巡回させることが出来ます。ただし、スパイダーは万能というわけではないので、漏れがないようにするには、自分で巡回するのが確実とされています。
では、スパイダーを使ってみます。スパイダーを実行するタイミングは、手動で巡回するタイミングと同じです。
todo フォルダを右クリックして、攻撃→スパイダー... をクリックします。
確認画面が出るので、ユーザを選択して、スキャン開始をクリックします。
結構時間がかかります。スパイダーの実行が完了したら、手動で巡回した場合と同様に、OWASP ZAP の左上のコンテキストの「todo」を右クリックして、Export URLs for Context(s) をクリックして、クローニングの結果を保存しておきます。
スパイダーで巡回した結果です。手動より、多くの URL が検出できています。比較してみたところ、手動で巡回した URL は全て含まれていました。
https://example.jp/todo
https://example.jp/todo/
https://example.jp/todo/addtodo.php
https://example.jp/todo/attachment
https://example.jp/todo/attachment/66bdf1b17f4a1-shindan.txt
https://example.jp/todo/attachment/memo.txt
https://example.jp/todo/changeicon.php?id=3
https://example.jp/todo/changeicondo.php
https://example.jp/todo/changemail.php?id=3
https://example.jp/todo/changemaildo.php
https://example.jp/todo/changepwd.php?id=3
https://example.jp/todo/changepwddo.php
https://example.jp/todo/confirmuser.php
https://example.jp/todo/css
https://example.jp/todo/css/common.css
https://example.jp/todo/delfile.php
https://example.jp/todo/editdone.php
https://example.jp/todo/editlist.php
https://example.jp/todo/edittodo.php?item=3&rnd=66c198e796e0c
https://example.jp/todo/export.php
https://example.jp/todo/exportdo.php
https://example.jp/todo/icons
https://example.jp/todo/icons/_64_66bdf1306124b-2024-08-03_15h28_57.png
https://example.jp/todo/icons/_64_elephant.png
https://example.jp/todo/icons/_64_ockeghem.png
https://example.jp/todo/import.php
https://example.jp/todo/importdo.php
https://example.jp/todo/index.html
https://example.jp/todo/inquery.php
https://example.jp/todo/inquerydo.php
https://example.jp/todo/login.php?url=todolist.php
https://example.jp/todo/logindo.php
https://example.jp/todo/logout.php
https://example.jp/todo/mypage.php?id=3&rnd=66c198e883080
https://example.jp/todo/newtodo.php?rnd=66c198e883080
https://example.jp/todo/newuser.php
https://example.jp/todo/quit.php?id=3
https://example.jp/todo/quitdo.php
https://example.jp/todo/resetpwd.php
https://example.jp/todo/resetpwddo.php
https://example.jp/todo/todo.php?item=3&rnd=66c198e807b94
https://example.jp/todo/todolist.php
https://example.jp/todo/todolist.php?key=ZAP
https://example.jp/todo/todolist.php?rnd=66c198e883080
自動脆弱性スキャンの実行
自動診断を実行する前に、強制ログインモードを選択しておきます。下図のように、ツールバーのカギのアイコンをクリックして、カギがかかった状態にします。
カギがかかった状態にしたままだと、OWASP ZAP を普通に使うときに、挙動がおかしくなるので、自動診断が終わったらカギのかかってない状態に戻します。
では、自動診断を実行します。
左側のペインの todo フォルダを右クリックして、攻撃→動的スキャン... をクリックします。
スキャン内容の確認の画面になります。ユーザーが空欄になっているので、先ほど設定したユーザを選択して、スキャンを開始をクリックします。これで、自動脆弱性スキャンの実行が開始されます。
画面の下の方に、現在の進捗状況が表示されます。
進捗が 100% になると、スキャンが完了しています。アラートをクリックして、一番左にある的(マト)のようなアイコンをクリックして、赤くします。これにより、今回のコンテキストのアラートだけが表示されるようになります。25件が検出されたようです。
自動脆弱性スキャンの結果
25件のアラートが、どういう内容で、どうやって、この脆弱性が見つかったのかは、まだ分かっていませんが、とにかくレポートを生成させてみます。コンテキストで「todo」を選択した状態で、レポート→Generate Report ... をクリックします。
すると、確認画面が出るので、Generate Report をクリックします。
生成された HTML ファイルをダブルクリックして、表示してみます。立派なレポートが出来ていました。
このレポートは、いろいろ見てみたのですが、今回の診断結果の詳細が書かれているというよりは、今回検出した脆弱性について、たくさん解説してくれているというレポートでした。それはそれで必要ですが、具体的にどの診断で、どういう脆弱性だったかは、レポート見るだけでは分からないものでした。
よって、結果の分析には、OWASP ZAP が起動した状態で、アラートを詳しく見る必要があるようです。脆弱性スキャンを毎回やるのは大変なので、現在の状態を保存しておきたいところです。
OWASP ZAPの状態(セッション)の保存方法と復元方法
OWASP ZAP は、セッションという形で、状態を自動で保存してくれています。「ファイル→セッションデータを開く...」で、保存したセッションを指定すると、脆弱性スキャンが完了した状態に復元してくれます。
自動でセッションを保存した場合のセッションの置き場所は、デフォルトでは ~/.ZAP/sessions/
に保存されています。
明示的に、自分でセッションを保存する場合は、「ファイル→セッションデータをファイルに保存」で保存できます。
Bad Todoのデータベースが壊れたときの復旧方法
OWASP ZAP の自動脆弱性スキャンを行うと、たまに、フリーズして動かなくなる時があります。再起動してみると、データベースが壊れているときがありました。
そこで、データベースの復旧方法をここにメモしておきます。
Bad Todoのデータベースのエクスポート
まず、既存のデータベースをエクスポートします。私の場合、既に壊れた後だったので、もう一度、OVAファイルをインポートして、別の wasbook を起動して、そこからデータベースをエクスポートしました。
Bad Todo で使われているデータベースは MySQL で、root のパスワードは、wasbook でした。
以下の1コマンドでエクスポートできます。(MySQL の)root のパスワードを聞かれるので、wasbook と入力してください。
$ mysqldump -u root -p todo > ./todo.db
この出力した todo.db がデータベースファイルで、後でインポートするときに使います。
Bad Todoのデータベースのインポート
ちょっと面倒ですが、既存のデータベース(todo という名前です)を削除して、同じ名前(todo)で新規にデータベースを作成し、そこにインポートする、という流れになります。
MySQL にログインして、既存のデータベース(todo)の削除、新規データベース(todo)の作成を行います。
$ mysql -u root -p
> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| phpmyadmin |
| roundcube |
| todo |
| wasbook |
+--------------------+
> drop database todo;
> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| phpmyadmin |
| roundcube |
| wasbook |
+--------------------+
> create database todo;
> exit
最後に、エクスポートしたデータベースファイルをインポートします。
$ mysql -u root -p todo < todo_org.db
Bad Todoのデータベースの復旧の手順は以上です。
おわりに
今回は、自動脆弱性スキャンをやってみました。設定項目が多くて大変でしたが、実際に設定してみると、何となく何を設定しているのかは理解できた気がします。
実際に見つかった脆弱性については、今後、内容の分析と、再現、対策を行っていきたいと思います。
今回は OWASP ZAP のロゴを使わせていただきました。OWASP ZAP は自動スキャンなど高機能ですが、なかなか扱いが難しいです。普段の解析は Burp Suite の方がやりやすいです。
最後になりましたが、エンジニアグループのランキングに参加中です。
気楽にポチッとよろしくお願いいたします🙇
今回は以上です!
最後までお読みいただき、ありがとうございました。