それでは、解答を説明します。
はじめに
CSRF対策の不備として、ありがちなパターンは以下のとおりです。- トークンが予測可能(ユーザIDのハッシュ値をトークンとして用いている等)
- 他人のトークンが利用できてしまう(参考記事)
- トークンのチェック方法に不備がある。
$_POST['token']は攻撃者が自由に設定できますが、正規のトークンの値は乱数なので予想できません。そこで、$_SESSION['token']がどのような値をとるか調べてみましょう。ログイン直後(mypage.php)にはこの変数は設定されていません。そして、PHPの場合、設定されていない変数を参照するとNULLが返ります(警告が表示され処理は継続される)。つまり、$_SESSION['token']の見かけの初期値はNULLということになります。そして、入力フォーム(chgmailform.php)に遷移するとトークンが設定され、メールアドレス変更(chgmail.php)の際にNULL(未定義)に戻ります。この様子を状態遷移図として下図に示します。if ($_POST['token'] !== $_SESSION['token']) { // ワンタイムトークン確認 die('正規の画面からご使用ください'); }
$_SESSION['token']に通常NULLが入っていることを使ってCSRF攻撃ができます。$_POST['token']がNULLであれば、上記のif文はNULL同士の比較になるので、チェックを回避できます。具体的には、POSTパラメータtokenを消してしまうことによって、$_POST['token']がNULLとなり、CSRFチェックを回避できます。
スクリプトを動かして確認してみる
ここで、Burp Suite(無償のCommunity Editionを想定)を用いて、上記を確認してみましょう。プロキシとしてBurp Suiteを設定した状態で、サンプルプログラムのメールアドレス変更を実行します。そして、chgmail.phpへのPOSTリクエストを選択し、コンテキストメニューを表示(Windowsの場合は右マウスクリック)して、「Send To Repeater」をクリックします。下図のようにRepeaterタブが赤色表示に変わるので、このRepeaterタブをクリックします。
以下のように、HTTPリクエストの内容が表示されます。
ここで、リクエストボディ(上記赤枠の中)からtoken=以下をまるごと削除し、mail=も適当なメールアドレスに変更します(下図)。
この状態でRepeaterの「Go」ボタンを押すと、下図右半分のように、「aliceさんのメールアドレスをevil@wasbook.orgに変更しました」と表示されます。
すなわち、tokenパラメータを削除しても、更新処理が正常に完了することがわかりました。
PoCの作成
それでは、PoC(概念実証コード)を作成しましょぅ。Burp SuiteのProfessional版やOWASP ZAPにはCSRFのPoC生成ツールが利用できますが、このケースはPoCも単純なので、手で作ってしまいましょう。要件としては、http://example.jp/chgmail.phpに対して、POSTリクエストでmail=... というパラメータを送信するだけです。そのようなHTMLを作成します。手動でサブミットでもいいのですが、以下はフォームが表示されてから5秒後に自動的にサブミットするようにしています。
これを動かしてみましょう。あなたは現在被害者の立場です。mypage.phpを閲覧して対象スクリプトにログインします。<body onload="setTimeout('document.forms[0].submit()', 6000)"> <form action="http://example.jp/chgmail.php" method="post"> <input name="mail" value="evil@example.com"> <input type="submit"> <form> <body>
この状態で、あなた(被害者)は、CSRFの罠をうっかり閲覧してしまいました。
罠の中のJavaScript(body要素のonloadイベント)により上記FormがPOSTされ、以下のように無事(?)メールアドレスが変更されました。
参考文献
平成29年春季の情報処理安全確保支援士試験 午後Ⅰ問2(問題、解答、講評)にこの知識を問う問題が出題されました。たまたまこの試験を私も受けていましたw拙著「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」のP194には、この内容についての解説があります。
以上で、初級問題の解答編は終わりです。よろしければ「中級編」にもチャレンジしてみてください。
0 件のコメント:
コメントを投稿