第 4 章 セッション管理の脆弱性を突いた攻撃の実行 20
4.3 CSRF の実行による検査手法
4.3.3 開発者から獲得した操作情報の解析
提案機構は,開発者から獲得した情報を解析することでCSRFを実行するため に必要な情報を自動的に抽出する.自動的に抽出する情報を以下に列挙する.
• セッションIDを伝播する方法
• ログインリクエスト
• ログインリクエスト内にユーザ名とパスワードを埋め込む箇所
• ログインのためのリクエスト
セッションIDを伝播する方法は,ステップ11においてセッションIDを獲得し,
ステップ12においてセッションIDをリクエストに埋め込むために特定する.ロ グインのためのリクエストは,ステップ10と11において検査対象のウェブアプ リケーションにログインするために特定する.ログインリクエストとそのリクエ スト内にユーザ名とパスワードを埋め込む箇所は,ステップ11においてログイン リクエストに被害者のユーザ名とパスワードを埋め込むために特定する.
これらの情報を抽出するために,提案機構はステップ6で獲得したHTTPリク エストとレスポンスをウェブアプリケーション特有の情報で解析する.セッション IDの伝播方法を特定するために,ステップ6で獲得したレスポンスを開発者から 獲得したセッションIDの名前で解析する.レスポンスのCookieとURI,hidden
fieldにセッションIDの名前があるかを確認する.HTTPレスポンスのCookieに
セッション IDの名前を発見した場合,セッション IDがCookie によって伝播さ れると判断する.CookieにセッションIDの名前を発見しなかった場合,URIか hidden fieldがセッションIDの伝播方法になるためにURIとhidden fieldを確認す る.例えば,表4.1に示したように開発者によって指定されたセッションIDの名前 が“phpbbmysql sid”であると仮定する.レスポンスのCookieとURI,hidden field に“phpbbmysql sid”があるかを確認する.HTTPレスポンスのCookie “Set-cookie:
phpbbmysql sid=6da54ea....; path=/”に“phpbbmysql sid”を発見した場合,セッショ
ンIDがCookieによって伝播されると判断する.
ログインリクエストを特定するために,提案機構はステップ6で獲得したHTTP リクエストとレスポンスを解析する.ログインリクエストを特定する上で,ログ インリクエストを発行するフォームのinput要素にあるtype属性が“password”で あると仮定する.なぜなら,ログインフォームのパスワードを入力する欄のtype 属性は,他者にパスワードを盗み見られないように“password”になっていること が一般的だからである.
まず,提案機構はあるリクエストAがGETメソッドかPOSTメソッドであるか を確認する.なぜなら,多くのウェブアプリケーションがログインリクエストを POSTメソッドで送信しているためである.そのリクエストAがPOSTメソッド であれば,提案機構はリクエストAを発行したフォームを特定する.また,リク エストAがGETメソッドであれば,提案機構はリクエストAをログインリクエ ストでないと判断する.フォームを特定するために,リクエストAのメッセージ ボディ内の全ての変数とリクエストAを発行したページ内にあるフォームのinput 要素が持つname属性を比較する.これらの変数とname属性が一致する時,リク
エストAは一致したフォームから送られたと判断する.この一致したフォームの input要素が持つtype属性が“password”のとき,提案機構はこのリクエストAが ログインリクエストであると判断する.
提案機構がログインリクエストを特定する一例を示す.開発者が次のログイン フォームを利用してログインリクエストを発行し,
<form method="POST" action="./login_check.php">
User name: <input type="text" name="username">
Password: <input type="password" name="pwd">
<input type="submit" value="Submit">
</form>
次のリクエストのメッセージボディが生成されたことを想定する.
username=tester&pwd=tester_pwd
このリクエストを受け取ると,提案機構はこのリクエストがどのフォームから送 信されたものかを調査する.リクエストのメッセージボディ内にある全ての変数 名を取り出し,それぞれのフォームの値と比較する.この場合,提案機構はメッ セージボディ内の変数名 “username”と “pwd”を取り出し,上記のフォームと比 較する.それぞれの変数名と値が一致することから提案機構はこのリクエストが 上記のログインフォームから発行されたと判断する.このフォームにtype属性が
“password”であるinput要素があるために,このリクエストがログインリクエスト
であると判断する.
ログインリクエストに関する情報を利用して,ログインリクエストにユーザ名 とパスワードを埋め込む箇所を特定する.ログインフォームの中にユーザ名の入 力欄とパスワードの入力欄が設置されており,ユーザ名の入力欄が上 (または左) に設置されていると仮定する.まず,提案機構はパスワードを埋め込む箇所を特 定するためにログインフォームのinput要素を確認する.input要素Aのtype属性
が “password”であるname属性を獲得する.獲得したname属性と一致するログ
インリクエストのメッセージボディ内にある変数名を特定する.そして,この変 数名の値がパスワードを埋め込む箇所であると判断する.
次に,提案機構はログインリクエスト内のユーザ名を埋め込む箇所を特定する.
ユーザ名の入力欄はパスワードの入力欄の上(または左)に設定されているために,
type属性が“password”のinput要素Aより前に設置されたinput要素Bを確認す
る.input要素Bのname属性と一致するログインリクエストのメッセージボディ内 の変数名を特定し,この変数名の値がユーザ名を埋め込む箇所であると判断する.
提案機構がログインリクエストにユーザ名とパスワードを埋め込む箇所を特定 する一例を示す.上記の例と同様に開発者が次のログインフォームを利用してロ グインリクエストを発行し,
<form method="POST" action="./login_check.php">
User name: <input type="text" name="username">
Password: <input type="password" name="pwd">
<input type="submit" value="Submit">
</form>
次のログインリクエストのメッセージボディが生成されたことを想定する.
username=tester&pwd=tester_pwd
まず,このログインフォームの input要素のtype属性が“password” であるname
属性“pwd”を特定する.この“pwd”と一致するログインリクエストのメッセージ
ボディ内の変数名が持つ値“tester pwd” がパスワードを埋め込む箇所である.そ して,type属性が“password”のinput要素より先に設置されたinput要素を確認す る.input要素のname属性“username”と一致するログインリクエストのメッセー ジボディ内の変数名が持つ値“tester”がユーザ名を埋め込む箇所であると判断する.
提案機構が,ログインリクエストを利用してログインするためのリクエストを 特定する.提案機構は,開発者が最初にリクエストを発行した時から開発者がロ グインリクエストに対するレスポンスを得た時までをログインのリクエストと判 断する.さらに,ログイン後から開発者が最後のレスポンスを獲得する時までが 検査対象の機能のためのリクエストであると判断する.