サイバーセキュリティ演習 ― Webセキュリティ基礎&実践― 10.セッションIDの不正取得対策 講義内容 1. 2*. Webサイトの仕組みとWebプログラミング基礎 3.4.5*. 不正スクリプトの実行対策 6.7*. データベースの不正操作対策 8 *. システムの不正操作対策とHTTPレスポンスの改竄対策 9 *. 偽リクエストによるサービスの不正利用対策 10*. セッションIDの不正取得対策 11. 総合演習(1) 12*. 公開ディレクトリの不正横断対策と認証認可制御の欠落 による不正アクセス対策とエラーメッセージからの情報 漏えい対策 13. 総合演習(2) 14. 総合演習(3) 15. 学期末試験 ※*はレポートがある回になります。 本日の内容 セッション管理の不備の脆弱性攻撃体験と 脆弱性の修正 セッションIDの固定化 セッションIDの推測 セッションとは セッションは一連のインタラクティブな操作のこと。 典型的には、ログインしてからログアウトするまでが 一つのセッション。 5 セッションIDとCookie セッションIDは、ログインID、パスワード、認証状態やアクセ ス履歴といったセッション情報の識別子 Cookieは、ブラウザにセッションIDを一時的に保存する仕組み オンラインショップにアクセス ID yamada PW ******** ログインページを送付 IDとパスワード入力 ユーザ専用ページを送付 セッションIDを通知 クライアント 購入ページにアクセス 次回から、ブラウ ザはCookieに保 存したセッション IDを送信 購入ページを送信 ログアウト ログアウト後のページを送付 DBで管理する ID、パスワード を参照し認証 DB Webサーバ セッションIDをもと に個人を特定 セッション情報は一 定期間保持 セッションIDを運ぶ手段 URL HTTPヘッダ HTTPボディ セッションハイジャック ログイン中の利用者のセッションIDを不正に取得する攻 撃方法 セッションIDの漏えい ネットワークの盗聴やXSSなどの脆弱性攻撃により、セッ ションIDを盗み出す セッションIDの固定化 セッションIDを盗み出す代わりに、セッションIDを利用者の ブラウザに設定する。攻撃者は利用者のセッションIDを 「知っている」状態となる。 セッションIDの推測 連番や日時・ユーザIDなどをもとにしたセッションIDの利用 により、第三者がセッションIDを容易に推測する。 セッションIDの漏えいの事例1 セッションIDのURL埋め込みによる漏えい なぜ、セッションIDがURLに埋 め込まれる? PHPの設定ファイル(php.ini) で設定されているため。 session.use_cookies セッションIDの保存にCookieを使う(デフォルトはON) session.use_cookies セッションIDをCookieのみに保存する(デフォルトはON) session.use_trans_sid URLにセッションIDを自動埋め込みする(デフォルトはOFF) セッションIDがURLに埋め込みになる条件 session.use_trans_sidがONの場合 session.use_trans_sidがOFFでも、 session.use_cookiesがON、session.use_cookiesがOFFで Cookieが使えない場合 (携帯電話向けWebアプリケーションなど) セッションIDの漏えいの事例2 Cookieのセキュア属性不備による漏えい 脆弱性があるオンライン ショップWebサイト ログイン中 SSL(通信暗号化) https://xxx.co.jp/443 クライアント ②第三者のWebサーバに アクセスして、罠のURL をクリック Webサーバ ③クリックによりhttpに変更 したリクエストが送信される http://xxx.co.jp/443 第三者の Webサーバ 攻撃者 ①事前に、罠の URLを張り付ける DB ④HTTPリクエストの Cookieを盗聴 Cookieのセキュア属性 HTTPS通信のみCookieを利用する場合に指定するオプ ション Cookieにsecure属性を設定していない場合は、HTTP通 信でもCookieにセッションIDが保持されるため、 HTTPS通信で発行したCookieでもHTTP通信の盗聴によ りCookie情報を不正に取得されてしまう可能性がある。 オンラインショッピングなどHTTP(商品カテゴリページ)と HTTPS(購入ページ)が混在する場合はオプションの指定が 難しい Set-Cookieヘッダの文法 Set-Cookie: [Cookie名=値]; [expires=期限]; [path=Cookieが使用されるURLのパス名]; [domain=Webサーバ名]; secure 参考:通信データキャプチャソフト Fiddler オープンソースのWebデバッグツール HTTP,HTTPSの通信データの閲覧、書き換えが可能 Windows OSに対応 Wireshark オープンソースの通信データ解析ツール HTTP, HTTPSだけでなくTCP, UDPなど800以上の通信 データの閲覧が可能 Windows, Mac, LinuxなどのOSに対応 セッション管理不備の一般的な 影響 ログインユーザのみが利用可能なサービスを悪用される 不正送金、商品購入、退会処理など。 ログインユーザのみが編集可能な情報を改ざん、新規登 録がされる 各種設定の変更(管理者画面、パスワードなど)、掲示板への 不適切な書き込みなど。 ログインユーザのみが閲覧可能な情報を閲覧される 非公開の個人情報を不正閲覧、ウェブメールを不正閲覧、コ ミュニティ会員専用の掲示板を不正閲覧など。 セッションIDの漏えい対策 セッションIDの漏えいの原因は、セッションIDがURLに 格納されていることです。 またCookieのセキュア属 性が無効になっていることです。 セッションIDは、URLパラメータに埋め込むのではなく、 Cookieに格納するか、POSTメソッドのhiddenパラ メータに格納する方法で受け渡しするようにしましょ う。また、特別な理由が無い限り、php.iniでセッショ ンIDをURLパラメータに格納する組み合わせの設定には しないようにしましょう。 HTTPS通信で利用するCookieは必ずsecure属性を設定 するようにしましょう。 secure属性が設定できない場 合はトークンを用いるようにしましょう。また、HTTP 通信でCookieを利用する場合は、HTTPS通信で発行す るCookieとは別のものを発行するようにしましょう。 本日の内容 セッション管理の不備の脆弱性攻撃体験と 脆弱性の修正 セッションIDの固定化 セッションIDの推測 演習テーマ セッション管理の不備 「セッションIDの固定化」のリンクをクリックしま しょう。 セッションIDの固定化の攻撃例1 セッションIDを使い続けている場合の攻撃事例 ID yamada PW ******** ③罠のURL をクリック クライアント ⑥再ログイン ログイン中 SSL(通信暗号化) ⑤認証再要求 HTTPヘッ ダインジェ クション DB Webサーバ ④無意識に攻撃者のセッションID によるリクエストが送信される ①ログインしてセッションIDを取得 攻撃者 ②フィッシング メールを送付 ⑦利用者になりすまして不正操作 セッションIDの固定化の攻撃例2 ID18 yamada PW ******** ⑥再ログイン ⑤再認証が求められ、レスポンスに含 まれる不正スクリプトが実行される 不正スクリ プト実行 (XSS) クライアント ③第三者のWebサーバに アクセスした時に、罠の URLをクリックしてしまう ログイン中 SSL(通信暗号化) DB Webサーバ ④クリックにより 意図しないリクエ ストが送信される 第三者の ①ログインして ②事前に、罠の Webサーバ セッションIDを 取得 URLを張り付ける 攻撃者 ⑦利用者になりすまして不正操作 演習内容(疑似的な攻撃) 掲示板に罠のリンクを張り付け、XSSによってセッショ ンIDを固定化する 第三者のウェブサイト 掲示板 脆弱性がある ウェブサイト ネット証券 演習の進め方 1. 2種類のブラウザを用意する 2. Webサイトの挙動を把握する 3. 脆弱性となる箇所を特定する 4. セッションIDを固定化するスクリプトを考える 5. 罠のリンクを考える 6. 罠のリンクを掲示板に投稿する 7. 標的の利用者になりすましが可能なことを確認す る。 1.2種類のブラウザを用意す る 正規のユーザ用と攻撃者用の2種類のブラウザが必要になり ますので用意しましょう。 資料上は正規のユー ザ用のブラウザをIE とします。 資料上は攻撃者のブ ラウザをChromeと します。 2.Webサイトの挙動を把握 する ネット証券に攻撃者のアカウ ントでログインして、いろい ろ操作をしてみましょう。 IDは「sato」、パスーワード は「sato310」 ログインボタンを押すと擬似 ウェブデバッガが動作し、リ クエストのデータを確認でき ます。 佐藤さんであることを確認し ましょう。 Cookieの値を確認しましょう。 Submitボタンを押すとログイ ンできます。 3.脆弱性となる箇所を特定す る <script>のタグをそれぞれの入力フォームに入力して 投稿してみましょう。 エスケープ処理がされておらず、ソースコードに <script>タグが追記される箇所はどこでしょうか? 4.セッションIDを固定化するスク リプトを考える セッションIDを固定化するスクリプトを考えましょう。 DOMベースのCookieの設定方法は以下の通りです。 <script>document.cookie=“ ”</script> Set-Cookieヘッダの文法は以下の通りです。 Set-Cookie: [Cookie名=値]; [expires=期限]; [path=Cookieが使用されるURLのパス名]; [domain=Webサーバ名]; secure Cookie名は「PHPSESSID」としましょう。 Cookieが使用されるURLのパスは「/」としましょう。 セッションIDを固定化するスクリプトは以下になります。 <script>document.cookie=“PHPSESSID=gll3n7kettiscjlj bju47o0b23;path=/"</script> 5.罠のリンクを考える ネット証券のお問い合わせには、次のURL文が作成されます。 http://localhost/Web/Scenario127/VulSoft/bon d.php?page=9&from_name=a&mail=b%40xxx. co.jp&comment=ccc %40はURL上では@を意味する セッションIDを固定化するスクリプトを含むURLを考えま しょう。 スクリプトを含めるURL上のパラメータは「mail」です。 http://localhost/Web/Scenario127/VulSoft/bond.php?pa ge=9&mail=<script>document.cookie="PHPSESSID=gll3n7 kettiscjljbju47o0b23;path=/"</script> 6.罠のリンクを掲示板に投稿 する 罠のリンクをURL欄に入 力し投稿しましょう。 http://localhost/We b/Scenario127/VulS oft/bond.php?pag e=9&mail=<script>d ocument.cookie="P HPSESSID=gll3n7ketti scjljbju47o0b23;pat h=/"</script> 7.標的の利用者になりすまし が可能なことを確認する 一旦、ネット証券の攻撃者のアカウントはログアウ トしておきましょう。 7.標的の利用者になりすまし が可能なことを確認する ネット証券に正規ユーザのアカ ウントでログインしましょう。 IDは「yamada」、パスー ワードは「P@ssword」 山田さんであることを確認しま しょう。 攻撃者のCookieの値と異なる ことを確認しましょう。 7.標的の利用者になりすまし が可能なことを確認する 罠のリンクをクリックしましょう。 7.標的の利用者になりすまし が可能なことを確認する ネット証券のお問い合わせのエラーページに飛ばさ れます。株の購入タグをクリックしましょう。 7.標的の利用者になりすまし が可能なことを確認する 再度ログインが求められますので、正規ユーザのID とパスワードでログインし、Cookieの値が攻撃者 のセッションIDになっていることを確認しましょう。 7.標的の利用者になりすまし が可能なことを確認する 最後に、攻撃者のIDとパスワードで再度ログイン して、「Congratulations!!演習の目標を達成しま した。」と表示され、正規ユーザのアカウントに なっていたら、OKです。 対処方法 原因 ログイン前後で同じセッションIDを使いまわしている ために、セッションIDが固定化され、なりすましによ る不正な操作が実行されてしまう 対処方法 攻撃者が用意したセッションIDによる不正アクセスを 防ぐために、ログイン認証後にセッションIDの変更を 行う。 セッションIDの変更ができない場合は、トークンを用い て正規のリクエストを識別する 演習内容(脆弱性の修正) ネット証券サイトのセッションID固定化の脆弱性となる コードを特定し、ログイン後にセッションIDを再発行 (リフレッシュ)する実装を行う セッションIDリフレッシュPHP 関数 session_regenerate_id() 現在のセッションIDを新しく生成したものと置き換える。 認証状態などのセッション情報は維持される。 関連付けられた古いセッションを削除する場合は引数に trueを入れる <?php session_regenerate_id(); $new_sessionid = session_id(); session_start(); ?> 修正プログラム ネット証券サイト Bond.php bond127.class.phpの処理内容をゲット ヘッダの設定 メッセージ割り当て テンプレート表示 bond127.class.php ネット証券の内容(データベースのデータ)の初期設定 ログイン処理 お問い合わせ内容送信時の検証処理 攻撃成功判定 脆弱性の修正の手順 bond127.class.php public function login() 1. 処理内容の確認。 2. セッションIDのリフレッシュ機能を追加する箇所の特 定。 3. セッションIDのリフレッシュ機能の実装。 1.処理内容の確認 public function login() { $db = $this->get_db(); $param = $this->get_param(); データベース情報、 セッション情報、パ ラメータ情報を取得 $session = $this->get_session(); $stmt = $db->prepare(parent::LOGIN_SQL); $stmt->execute(array(parent::ID => $param[parent::ID], parent::PASSWORD => $param[parent::PASSWORD])); $user = $stmt->fetch(); (次ページに続く) アカウント情報をデー タベースから検索 1.処理内容の確認 (つづき) データベースにアカウントが存 在する(認証OKの)場合、 ユーザ専用ページ の設定 if ($user) { $this->set_session(ScenarioEnvironment::ENV_ID_NAME, "Web"); $this->set_session($this->get_login(), $user); $this->set_name(); ログイン処理の実行および return true; ユーザ名を設定 } else { $this->proc_logout(); $this->set_content(parent::WARNING3, true); $this->set_content(parent::WARNING4, false); return false; ログアウト処理および警告 } ページの設定 } 2.セッションIDのリフレッ シュ機能を追加する箇所の特定 if ($user) { $this->set_session(ScenarioEnvironment::ENV_ID_NAME, "Web"); $this->set_session($this->get_login(), $user); $this->set_name(); return true; } else { $this->proc_logout(); $this->set_content(parent::WARNING3, true); $this->set_content(parent::WARNING4, false); return false; } } 3.セッションIDのリフレッ シュ機能の実装 if ($user) { session_regenerate_id(); $this->set_session(ScenarioEnvironment::ENV_ID_NAME, "Web"); $this->set_session($this->get_login(), $user); $this->set_name(); return true; } else { $this->proc_logout(); $this->set_content(parent::WARNING3, true); $this->set_content(parent::WARNING4, false); return false; } } 動作確認 攻撃者のセッションIDを確認しましょう。 ログインIDは「sato」、パスワードは「sato310 」 掲示板のURL欄に次のURLを投稿しましょう http://localhost/Web/Scenario127/VulSoft/bon d.php?page=9&mail=<script>document.cooki e="PHPSESSID=gll3n7kettiscjljbju47o0b23;path=/ "</script> 動作確認 正規ユーザのブラウザ上で罠のリンクをクリックし ましょう。 正規ユーザのIDとパスワードでログインしましょう。 Cookieの値が攻撃者のセッションIDにならなければ OKです。 セッションID固定化の要点 セッションID固定化の脆弱性の原因は、ログイン前後で 同じセッションIDを使いまわしていることです。 セッションハイジャックを防ぐために、ログイン認証後 にセッションIDをリフレッシュするようにしましょう。 なお、セッションIDの変更ができない場合は、第三者に 予測困難なトークンを用いるようにして正規のリクエス トを識別できるようにしましょう。 本日の内容 セッション管理の不備の脆弱性攻撃体験と 脆弱性の修正 セッションIDの固定化 セッションIDの推測 演習テーマ セッション管理の不備 「セッションIDの推測」のリンクをクリックしましょ う。 セッションIDの推測の事例 セッションIDが連番で生成されている場合、 ありがちなセッションIDの生成 規則 演習内容(疑似的な攻撃) オンラインバンキングで利用されるセッションIDの規則 性を発見する 脆弱性があるウェブサイト オンラインバンキング 演習の進め方 1. Webサイトの挙動を把握する 2. 脆弱性となる箇所を特定する 1.Webサイトの挙動を把握 する オンラインバンキングにロ グインを繰り返し、セッ ションIDの変化を確認しま しょう。 IDは「yamada」、パ スーワードは 「P@ssword」 攻撃者として、利用できる ことを考える。 擬似ウェブデバッガの Cookie値を確認して、 セッションIDの生成規則を 見極めて推測しましょう。 2.脆弱性となる箇所を特定す る セッションIDの規則性を確認できましたか? 日時を使用して推測してみましょう。 2015/11/30 1回目:30121149201558、2回目:30121150201525 2015/12/1 1回目:1111253201513、2回目:111125520154 日+時+月+分+年+秒 30 12 11 49 2015 58 対処方法 原因 ログインしたユーザからのリクエストに対して発行す るセッションIDが規則性を有するため、推測されてし まい、不正な操作が実行されてしまう 対処方法 セッションIDの推測の対策としては、PHPのセッショ ンID生成機能を用いて、第三者に予測困難なセッショ ンIDを利用する 演習内容(脆弱性の修正) オンラインバンキングのセッションID推測の脆弱性とな るコードを特定し、推測が困難なセッションIDを使用す る実装を行う セッションID生成のPHP関数 session_id() 自動的に疑似乱数を設定する。現在のセッション ID を 取得 または指定のセッションIDの設定も可能。 <?php $sessionid = session_id(); session_start(); ?> mcrypt関数 暗号理論的に安全な疑似乱数を生成することが可能。 セッション管理機構を自作しなければいけない場合は、 mcrypt関数を利用しましょう。 修正プログラム オンラインバンキング bank.php bank128.class.phpの処理内容をゲット メッセージ割り当て ヘッダの設定 テンプレート表示 bank128.class.php オンラインバンキングの内容(データベースのデータ) の初期設定 ログイン処理 ログアウト処理 脆弱性の修正の手順 bank128.class.php public function login() 1. 処理内容の確認。 2. セッションIDを割り当る箇所の特定。 3. 推測困難なセッションID割り当ての実装。 1.処理内容の確認 public function login() { $user = parent::login(); if ($user) { $dtoken = getdate(); データベースにアカウントが存 在する(認証OKの)場合、 日時情報を取得 $stoken = $dtoken['mday'].$dtoken['hours'].$dtoken['mon'].$dtoken['minutes'].$dtoken['year'].$dtoken[' seconds']; setcookie('SESSIONID', $stoken, time()+300, '/Web/Scenario128/EditSoft'); return true; } else { $this->proc_logout(); 300秒の有効期限付きセッションID をWebページに設定 $this->set_content(parent::WARNING3, true); $this->set_content(parent::WARNING4, false); return false; } } 2.セッションIDを割り当る箇 所の特定 public function login() { $user = parent::login(); if ($user) { $dtoken = getdate(); $stoken = $dtoken['mday'].$dtoken['hours'].$dtoken['mon'].$dtoken['minutes'].$dtoken['year'].$dtoken[' seconds']; setcookie('SESSIONID', $stoken, time()+300, '/Web/Scenario128/EditSoft'); return true; } else { $this->proc_logout(); $this->set_content(parent::WARNING3, true); $this->set_content(parent::WARNING4, false); return false; } } 3.推測困難なセッションID割 り当ての実装 public function login() { $user = parent::login(); if ($user) { $dtoken = getdate(); $stoken = session_id(): setcookie('SESSIONID', $stoken, time()+300, '/Web/Scenario128/EditSoft'); return true; } else { $this->proc_logout(); $this->set_content(parent::WARNING3, true); $this->set_content(parent::WARNING4, false); return false; } } 動作確認 オンラインバンキングに繰り返しログインしましょう。 ログインIDは「yamada」、パスワードは 「P@ssword 」 セッションIDが複雑で規則性が無く推測が困難な疑似乱 数に変わっていればOKです。 セッションID推測の要点 セッションID推測の脆弱性の原因は、規則性のあるセッ ションIDを生成し使用していることです。 セッションハイジャックを防ぐために、PHPのセッショ ンID生成機能を用いて第三者に推測が困難なセッション IDを生成しましょう。なお、どうしてもセッション管理 機構を自作しなければいけない場合は、暗号理論的に安 全な疑似乱数を生成するPHPの関数を用いて十分な桁数 のセッションIDを生成するようにしましょう。 課題 実際に、セッションハイジャックの被害を 受けた事件を調査し、1)被害の内容と時 期、2)攻撃方法とその攻撃で可能だった こと、3)脆弱性が生まれた原因、4)実 施された対策について、参考にした情報源 などを引用しつつ簡潔にまとめてください。 本講義の感想、要望、質問などあれば、書 いてください。 https://moodle.artsci.kyushu-u.ac.jp/course/view.php?id=2661
© Copyright 2025 ExpyDoc