脆弱性体験学習ツール「AppGoat」まとめ

#はじめに

　セキュリティに関する研修の一環で、脆弱性体験学習ツール「AppGoat」に取り組みました。「XSS」「SQLインジェクション」「CSRF」「バッファオーバーフロー」「ディレクトリ・トラバーサル」「OSコマンド・インジェクション」「セッション管理の不備」について自分なりにまとめます。

#テーマ１：XSS(クロスサイトスクリプティング)

##XSSの脆弱性とは

　不正なスクリプトが何らかの形でウェブページに埋め込まれ、スクリプトを含むHTMLを出力し、ブラウザ上で実行されてしまう脆弱性。

##XSSによる被害


- 本物のWebサイト上での偽のWebページの表示。

- ブラウザに保存されているCookieの取得。

- 任意のCookieの保存。


##XSSの種類

- 格納型
　Webアプリのデータ格納領域に不正なスクリプトが入力、格納され、ページ閲覧のたびにスクリプトが実行される。

- 反射型
　Webアプリが、入力に含まれる不正なスクリプトをそのまま出力、実行してしまう。

- DOMベース
　DOMを利用しているスクリプトがDOMツリーにある不正なスクリプトをWebページの表示に利用してしまうことによって実行される。


##XSSの脆弱性の発見方法

- 画面の入力欄やURLのクエリストリングにHTMLなどのスクリプトを入力し、リクエスト送信の後、ソースコードにエスケープ処理されないまま記述されていないか確認する。

- 画面のURLの末尾にあるクエリストリングを書き換える。POSTリクエストの場合は送信パラメータを検査ツールなどを使用して加工し、検査を行う。


##XSSの対策

 - 出力する要素に対してエスケープ処理を行う。PHPであれば、htmlspecialchars()の第１引数に入れ、エスケープ処理をしてから出力するようにする。

 

#テーマ２：SQLインジェクション

##SQLインジェクションの脆弱性とは

　悪意のあるリクエストにより、意図しないSQL文を注入し、不正にデータベースを操作されてしまう脆弱性。

##SQLインジェクションによる被害

- データベースの非公開情報の閲覧。

- データベースの情報の改ざん、消去。

- 認証回避による不正ログイン。

- ストアドプロージャー(一連の処理が保存され、一つの要求で複数のSQL文を実行できるもの)などを利用したOSコマンドの実行。

##SQLインジェクションの種類

- 文字列リテラル型
　SQL文の文字列要素にSQL文を入力することで、データベースを不正に操作する。

- 数値リテラル型
　SQL文の数値要素にSQL文を入力することで、データベースを不正に操作する。

##SQLインジェクションの発見方法

- 画面の入力欄に「’」を入れて、リクエストを送信し、データベースエラーが起こるか確認する。

- 画面のURLの末尾にあるクエリストリングを「’」に書き換える。POSTリクエストの場合は送信パラメータを検査ツールなどを使用して加工し、検査を行う。

##SQLインジェクションの対策

- 静的プレースホルダを用いてデータベース側でバインドする。

- 動的プレースホルダを用いてSQL文の組み立てを行い(疑問符パラメータを用いる等)プレースホルダに入力値をバインドする。

 

#テーマ３：CSRF(クロスサイト・リクエスト・フォージェリ)

##CSRFの脆弱性とは

　Webサイトにログインしたユーザが悪意ある人によって予め用意された罠により意図しないリクエストを実行させられてしまう脆弱性。

##CSRFによる被害

- ログインしたユーザのみが利用可能なサービスの悪用。

- ログインしたユーザのみが編集可能な情報の改ざん。

##クロスサイト・リクエスト・フォージェリの脆弱性の発見方法

- トークンの有無を確認する。まず、重要な処理が行われる画面のソースコードを表示し、formタブのhidden属性で不規則な英数字の値があるか確認する。また、推測可能な値であるかも確認する。

- 重要な処理が行われる画面からパラメータを設定して送信し、パスワードが再確認されるか確認する。

- Referer(リクエスト元のページがどこか)の確認がされるか調べ、重要な処理が行われるページのHTMLソースを取得し、ローカルに保存する。保存したソースをテキストエディタ等で開き、formタブのaction属性にある相対URLを絶対URLに変更。保存したソースをブラウザで開き、画面項目に値を入力してリクエストを送信し、処理されないか確認する。(処理された場合に脆弱性がある。)

##クロスサイト・リクエスト・フォージェリの対策

 - 重要な処理の前には推測不可能なトークンを設定する。リクエスト送信側のhidden属性の値に関数(PHPの場合はsession_id()等)を用いて設定し、処理実行側の該当の処理の前に、関数と送られたトークンが合致しているかを判断する処理をif文等を用いて行う。

 - 重要な処理の前にパスワードの入力を求める処理を行う。

 

#テーマ４：バッファオーバーフロー

##バッファオーバーフローの脆弱性とは

　データを格納するためにメモリ上に確保される領域のことをバッファといい、外部からのデータ入力によって、そのバッファからデータが溢れ、コンピュータの制御が第三者に奪われてしまう脆弱性。

##バッファオーバーフローによる被害

 - プログラムの異常終了。

 - 外部からの任意のマシンコードの実行。

##バッファオーバーフローの脆弱性の種類

 - スタック領域型
　ローカル変数などのために確保される領域で発生する。

 - ヒープ領域型
　特別な関数によって明示的に確保される領域で発生する。

##バッファオーバーフローの脆弱性の発見方法

- 画面の入力パラメータに検査ツールを用いてバッファを超える文字列を入力し、リクエストを送信して確認する。

- 該当の入力画面のURLのクエリストリングを編集(name等の値を制限文字数以上のものに書き換える等)、送信し、確認する。POSTリクエストの場合は送信パラメータを検査ツールなどを使用して加工し、検査を行う。

##バッファオーバーフローの対策

- 送信する文字列をサイズを指定してコピーできる安全な関数を利用する。

- 動的に必要な分のバッファを確保できるクラスを利用する。

 

#テーマ５：ディレクトリ・トラバーサル

##ディレクトリ・トラバーサルの脆弱性とは

　ファイル名を指定する機能に於いて、入力されたファイル名へのチェックが不十分であり、非公開のファイルを閲覧、悪用されてしまう脆弱性。

##ディレクトリ・トラバーサルの被害

- Webサーバ内のファイルの閲覧、改ざん、削除。

##ディレクトリ・トラバーサルの脆弱性の発見方法

- ファイル名の入力欄に親ディレクトリを示す「../」を含む値を入力して、送信し、不正なファイルの閲覧が行われないか確認する。

- 該当の入力画面のURLのクエリストリングを「../」を含む形のファイル名にして送信し、確認する。POSTリクエストの場合は送信パラメータを検査ツールなどを使用して加工し、検査を行う。

##ディレクトリ・トラバーサルの対策

- 外部からファイル名を指定できる使用を避ける。

- ファイル名にディレクトリ名を含まないようにする。(PHPであれば、basename()等を使用してディレクトリ階層を除外する）

 

#テーマ６：OSコマンド・インジェクション

##OSコマンド・インジェクションの脆弱性とは

　ユーザーからの入力値をそのまま利用して、シェル経由によるOSコマンド実行を行うWebアプリケーションに存在しうる脆弱性。

##OSコマンド・インジェクションによる被害

- サーバ内のファイルの不正な操作。

- システムの不正な操作。

- 不正なプログラムのダウンロード、及び実行。

- システムの乗っ取りによる他のシステムへ攻撃などの二次被害。

##OSコマンド・インジェクションの脆弱性の発見方法

- 画面の入力パラメータにOSコマンド(&/windows/system32/ping-n 127.0.0.1 等)を入れ、送信し、処理の遅延が起こるか確認する。

- 該当の入力画面のURLのクエリストリングをOSコマンドを含む形に変更して送信し、確認する。POSTリクエストの場合は送信パラメータを検査ツールなどを使用して加工し、検査を行う。

##OSコマンド・インジェクションの対策

- シェルを起動できる言語機能の利用を避け、他の関数に代替する。

 

#テーマ７：セッション管理の不備

##セッション管理の不備とは

　ユーザを識別するセッションIDの発行や管理に対するセキュリティが不足している状態である。これにより、セッションIDの漏洩や固定化、推測されてしまう恐れがある。

##セッション管理の不備による被害

- ログイン後の利用者のみが利用可能なサービスの悪用。

- ログイン後の利用者のみが編集可能な情報の改ざん、新規登録。

- ログイン後の利用者のみが閲覧できる情報の閲覧。

##セッション管理の不備の発見方法

- ログイン前とログイン後のセッションIDを検査ツール等用いて比較し、変化しているか、また推測可能なものではないか確認する。

##セッション管理の不備の対策

- セッションIDを発行する処理では、日時やアドレスなど推測可能なもので自作せず、言語API等を用いて複雑なセッションIDを発行する。

- URIのクエリストリングにセクションIDを埋め込まない。

- HTTP通信で利用するCookieにセキュア属性を付与する。

- 言語APIを用いて、ログイン前とログイン後のセッションIDをリフレッシュし変更する。