サイバーセキュリティ演習 ― Webセキュリティ基礎&実践― 9.偽リクエストによるサービスの不正利用対策 講義内容 1. 2*. Webサイトの仕組みとWebプログラミング基礎 3.4.5*. 不正スクリプトの実行対策 6.7*. データベースの不正操作対策 8 *. システムの不正操作対策とHTTPレスポンスの改竄対策 9 *. 偽リクエストによるサービスの不正利用対策 10*. セッションIDの不正取得対策 11. 総合演習(1) 12*. 公開ディレクトリの不正横断対策と認証認可制御の欠落 による不正アクセス対策とエラーメッセージからの情報 漏えい対策 13. 総合演習(2) 14. 総合演習(3) 15. 学期末試験 ※*はレポートがある回になります。 本日の内容 クロスサイト・リクエスト・フォージェリ (CSRF)の脆弱性攻撃体験と脆弱性の修正 意図しない命令の実行 不完全な対策 演習テーマ CSRF 「意図しない命令の実行」のリンクをクリックしま しょう。 クロスサイトリクエストフォー ジェリ(CSRF)とは、 Cross-Site Request Forgery サイト横断型リクエスト偽造 攻撃者が他人のWebサイトに罠のリンクを埋め込み、 偽造のリクエストを送信することで、認証済みの ページ上でしか行えない処理を不正に実行する脆弱 性 Webの認証状態の管理方法 Cookie 6 Cookie クライアントの端末にログインID、パスワード、認証状 態やアクセス履歴などセッション情報を一時的に保存す る仕組み オンラインショップにアクセス ID yamada PW ******** ログインページを送付 IDとパスワード入力 ユーザ専用ページを送付 セッション情報を通知 クライアント 購入ページにアクセス 次回から、ブラウ ザはCookieに保 存したセッション 情報を送信 購入ページを送信 ログアウト ログアウト後のページを送付 DBで管理する ID、パスワード を参照し認証 DB Webサーバ セッション情報をも とに個人を特定 セッション情報は一 定期間保持 HTTPレスポンスの例 HTTP/1.1 200 OK レスポンスメッセージ Date: Thu, 24 Sep 2015 01:05:20 GMT レスポンスヘッダ Server: Apache/2 Cache-Control: no-cache Expires: 0 Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=shift_jis Location: http://survey.html Set-Cookie: ssid=123456789;path=/var/www/html/ <html>(省略)</html> レスポンスボディ CSRFの攻撃方法の一例 (ログインしていない場合) 8 ID yamada PW ******** 脆弱性があるオンライン ショップWebサイト ④認証要求 DB クライアント ②第三者のWebサーバにア クセスした時に、罠のURLを クリックしてしまう Webサーバ ③クリックにより 意図しないリクエ ストが送信される 第三者の Webサーバ 攻撃者 ①事前に、罠の URLを張り付ける 意図しないリクエス トが実行されない CSRFの攻撃方法の一例 (ログイン中の場合) 9 脆弱性があるオンライン ショップWebサイト ログイン中 DB クライアント ②第三者のWebサーバに アクセスした時に、罠の URLをクリックしてしまう Webサーバ ③クリックにより 意図しないリクエ ストが送信される 第三者の Webサーバ 攻撃者 ①事前に、罠の URLを張り付ける ④意図しないリクエ ストが実行される パスワードの変更 公開設定の変更 など ログインしたユーザのみが変更可能な設定を不正に操作されてしまう。 CSRFとXSSの違い 10 XSSの場合、 ④レスポンスの意図しないスクリプトが実行される 不正スクリ プト実行 (XSS) 不正操作 (CSRF) ログイン中 クライアント ②第三者のWebサーバに アクセスした時に、罠の URLをクリックしてしまう DB Webサーバ ③クリックにより 意図しないリクエ ストが送信される 第三者の Webサーバ 攻撃者 ①事前に、罠の URLを張り付ける CSRFの場合、 ④意図しないリクエ ストが実行される 演習内容(疑似的な攻撃) 掲示板に罠のリンクを張り付け、クリックによってSNS サイトの個人情報公開設定を変更する 第三者のウェブサイト 掲示板 脆弱性がある ウェブサイト SNSサイト 演習の進め方 1. Webサイトの挙動を把握する 2. 脆弱性となる箇所を特定する 3. 罠のリンクを考える 4. 罠のリンクを掲示板に投稿する 5. 第三者の個人情報設定が変更されることを確認す る。 1.Webサイトの挙動を把握 する SNSにログイン後、設定変 更ページに移動し、個人情 報公開設定が「非公開」に なっていることを確認する。 IDは「yamada」、パ スーワードは 「P@ssword」 攻撃者として、利用できる ことを考える。 設定変更ページのソースを 確認しましょう。 公開/非公開設定した後の URLも確認しましょう。 2.脆弱性となる箇所を特定す る 公開と非公開が指定されたパラメータを確認できま したか? http://localhost/Web/Scenario113/VulSoft/sns.php ?page=4&secret_token=ialeltofu7c6v63hbtuol4nid 4&name=yamada&year=1990&month=1&day=1& mail=yamada%40example.com&public=1 public=1は公開 public=0は非公開 3.罠のリンクを考える SNSサイトの公開設定変更時には、次のURL文が作成され ます。 http://localhost/Web/Scenario113/VulSoft/sns.php?pag e=4&secret_token=ialeltofu7c6v63hbtuol4nid4&name=y amada&year=1990&month=1&day=1&mail=yamada%4 0example.com&public=1 「非公開」から「公開」に変更するURLを考えましょう。 不要なパラメータは削ってください。 secret_token, name, year, month, day, mail http://localhost/Web/Scenario113/VulSoft/sns.php?pag e=4&public=1 4.罠のリンクを掲示板に投稿 する 罠のリンクをURL欄に入 力し投稿しましょう。 http://localhost/We b/Scenario113/VulS oft/sns.php?page= 4&public=1 5.第三者の個人情報設定が変 更されることを確認する。 第三者のアカウントでログインをしましょう。 ログインIDは「sato」 パスワードは「sato310」 罠のURLをクリックすることによって、佐藤さんの 個人情報公開設定が「非公開」から「公開」になっ てしまうことを確認しましょう。 5.第三者の個人情報設定が変 更されることを確認する。 「Congratulations!!演習の目標を達成しまし た。」と表示されたら、OKです。 CSRFの一般的な影響 ログインユーザのみが利用可能なサービスを悪用される ショッピングサイトなどのウェブアプリケーションへユーザが 意図しないリクエストを送信させられることで、不正送金、商 品購入、退会処理など、ユーザに不利益となる被害や、不快と 思われる行為が、ユーザの気がつかないうちに実行されてしま う。 ログインユーザのみが編集可能な情報を改ざんされる SNSなどのウェブアプリケーションにユーザの意図しないリク エストを送信させられることで、各種設定の変更(管理者画面、 パスワードなど)、掲示板への不適切な書き込みなどが、ユー ザの気がつかないうちに実行されてしまう。 対処方法 原因 ログインしたユーザからのリクエストに対して、その ユーザが意図したリクエストであるかどうかを識別す る仕組みを持たないために、認証状態を悪用され、不 正な操作が実行されてしまう 対処方法 罠のURLを経由したリクエストと正規のリクエストを識 別できるよう、リクエストにトークン(秘密情報)を 付加し、検証する機能を実装する。 トークンとは 第三者が知りえない秘密情報として用いる暗号 理論的に安全な疑似乱数 ユーザからリクエストを受けた際に、ログイン時 のトークンとの比較により検証する HTMLのinputタグにhiddenパラメータとともに指 定され、ブラウザ上には表示されない SNSサイトの設定変更ページのソースコードを確 認してみましょう。 <input type="hidden" name="secret_token" value="ihv95674r654qgc926qfo9njk0"/> トークン処理の流れ GET送信とPOST送信 GET送信 URLに入力値を含めてデータを送信する 送信できるデータはテキストのみ 宣言しない場合はGETで送信される(デフォルト) GET送信でトークンを送付すると、外部サーバのア クセスログにトークンを含むURLが記録されてしま い、トークンが漏れる可能性があるので注意 POST送信 URLに入力値を含めずデータを送信する 送信できるデータはテキストとバイナリが可能 トークンを含むリクエストはPOST送信で実施すべき 演習内容(脆弱性の修正) SNSサイトのCSRFの脆弱性となるコードを特定し、 トークンをチェックし一致しない場合はログイン画面へ 遷移する実装を行う 修正プログラム SNSサイト sns.php sns113.class.php sns113.class.ph pの処理内容を ゲット SNSの内容(データベースの データ)の初期設定 メッセージ割り 当て 設定完了画面の処理 テンプレート表 示 日付チェック 攻撃成功判定 個人情報設定変更時の検証処理 SQL文の処置 生年月日、ユーザIDの取得 リファラ(参照元)チェック ログイン状態の検証 脆弱性の修正の手順 sns113.class.php public function validate_is_logined() 1. 処理内容の確認。 2. トークンチェック機能を追加する箇所の特定。 3. トークンチェック機能の実装。 1.処理内容の確認 public function validate_is_logined() { $session = $this->get_session(); $param = $this->get_param(); セッション情報とパ ラメータ情報を取得 parent::validate_is_logined(); return $this; } ログイン処理を実行 2.トークンチェック機能を追 加する箇所の特定 public function validate_is_logined() { $session = $this->get_session(); $param = $this->get_param(); parent::validate_is_logined(); return $this; } 3.トークンチェック機能の実 装 public function validate_is_logined() { $session = $this->get_session(); 「ページ番号が同じ」かつ「変数が セットされNULLではない」かつ 「トークンが異なる」場合 $param = $this->get_param(); if (($this->get_page() == parent::PAGE_SETTING) && isset($session[$this>get_login()]["secret"]) && ($session[$this->get_login()]["secret"] !== $param["secret_token"])) { $this->set_session($this->get_login(), false); $this->set_page(parent::PAGE_LOGIN); $this->set_content(self::WARNING9, true); return false; } else { ログイン処理結果を失敗に、 出力ページをログインペー ジに、出力メッセージを警 告メッセージに設定し、 falseを返す parent::validate_is_logined(); } } そうでない場合、ログイン処理を実行 動作確認 佐藤さんのアカウントでSNSにログインしましょう。 ログインIDは「sato」、パスワードは「sato310 」 掲示板のURL欄に次のURLを投稿しましょう http://localhost/Web/Scenario113/EditSoft/sns.p hp?page=4&public=1 「不正なリクエストです。」と出力され、佐藤さんの個 人情報公開設定が「非公開」から「公開」にならなけれ ばOKです。 本日の内容 クロスサイト・リクエスト・フォージェリ (CSRF)の脆弱性攻撃体験と脆弱性の修正 意図しない命令の実行 不完全な対策 演習テーマ CSRF 「不完全な対策」のリンクをクリックしましょう。 CSRFの不完全な対策 CSRFの対策として、リクエストにトークンを含ませる方 法は有効だが、トークンに規則性がある場合、悪意のある 人に推測され、対策を回避されてしまう可能性がある 演習内容(疑似的な攻撃) SNSサイトで利用されるトークンの規則性を発見する 脆弱性があるウェブサイト SNSサイト 演習の進め方 1. Webサイトの挙動を把握する 2. 脆弱性となる箇所を特定する 1.Webサイトの挙動を把握 する SNSにログイン後、設定変 更ページに移動し、設定変 更をしましょう。 IDは「yamada」、パ スーワードは 「P@ssword」 攻撃者として、利用できる ことを考える。 設定変更ページのソースを 確認しましょう。 2.脆弱性となる箇所を特定す る トークンの規則性を確認できましたか? <input type="hidden" name="secret" value="1000" /> トークンは連番で割り当てられます。 ログインし直すと、secretパラメータの値がインクリ メントされることが確認できます。 対処方法 原因 ログインしたユーザからのリクエストに対して発行す るトークンが規則性を有するため、トークンを推測さ れてしまい、不正な操作が実行されてしまう 対処方法 CSRFの対策として秘密情報を使用する場合は、安全な 疑似乱数を用いて、第三者に予測困難なトークンを利 用する 演習内容(脆弱性の修正) SNSサイトのCSRFの脆弱性となるコードを特定し、安 全な擬似乱数により生成したトークンを使用する実装を 行う 修正プログラム SNSサイト sns.php sns114.class.php sns114.class.ph pの処理内容を ゲット SNSの内容(データベースの データ)の初期設定 メッセージ割り 当て 設定入力画面の処理 テンプレート表 示 個人情報設定変更時の検証処理 ログイン処理 トークン割り当ての処理 脆弱性の修正の手順 sns114.class.php public function prepare_set_token() 1. 処理内容の確認。 2. トークンを割り当る箇所の特定。 3. 予測困難なトークン割り当ての実装。 1.処理内容の確認 public function prepare_set_token() { $db = $this->get_db(); $param = $this->get_param(); データベース情報、 パラメータ、セッ ション情報を取得 $session = $this->get_session(); $token = null; try { $get_stmt = $db->prepare(self::GET_TOKEN_SQL); $get_stmt->execute(); $token = $get_stmt->fetch(); } catch(Exception $e) { トークン検索のSQL を準備し、実行 throw new Exception((__LINE__ . json_encode($this->_db->errorInfo())), LogUtil::ERROR_DB_EXECUTE); } (次ページに続く) 1.処理内容の確認 (つづき) トークン更新のSQL 文を準備し実行 try { $update_stmt = $db->prepare(self::UPDATE_TOKEN_SQL); $update_stmt->execute(); } catch(Exception $e) { throw new Exception((__LINE__ . json_encode($this->_db>errorInfo())), LogUtil::ERROR_DB_EXECUTE); トークン割り当て } $session[$this->get_login()][self::TOKEN] = $token["value"]; $this->set_session($this->get_login(), $session[$this>get_login()]); セッション情報として return $this; セット } 2.トークンを割り当る箇所の 特定 (つづき) try { $update_stmt = $db->prepare(self::UPDATE_TOKEN_SQL); $update_stmt->execute(); } catch(Exception $e) { throw new Exception((__LINE__ . json_encode($this->_db>errorInfo())), LogUtil::ERROR_DB_EXECUTE); } $session[$this->get_login()][self::TOKEN] = $token["value"]; $this->set_session($this->get_login(), $session[$this>get_login()]); return $this; } 3.予測困難なトークン割り当 ての実装 (つづき) try { $update_stmt = $db->prepare(self::UPDATE_TOKEN_SQL); $update_stmt->execute(); } catch(Exception $e) { throw new Exception((__LINE__ . json_encode($this->_db>errorInfo())), LogUtil::ERROR_DB_EXECUTE); } $session[$this->get_login()][self::TOKEN] = session_id(); $this->set_session($this->get_login(), $session[$this>get_login()]); 今回はセッションIDで使われている return $this; 疑似乱数をそのまま利用している。 } (本来はNG) 動作確認 SNSにログインし、設定変更ページに移動しましょう。 ログインIDは「yamada」、パスワードは 「P@ssword 」 ソースコードを表示し、トークンが疑似乱数に変わって いればOKです。 CSRFの要点 CSRFの脆弱性の原因は、ユーザが意図したリクエ ストであるかどうかを識別する仕組みを持たない ことです。 Webページを出力する際には、第三者に予測困難 なトークンをhiddenパラメータに挿入するように しましょう。そして、ユーザからのリクエストを 受けた際には、hiddenパラメータの値と元のトー クンを比較し、一致しない場合は処理を行わない ようにしましょう。 課題 実際に、CSRFの脆弱性を突かれて被害を受 けた事件を調査し、1)被害の内容と時期、 2)攻撃方法とその攻撃で可能だったこと、 3)脆弱性が生まれた原因、4)実施され た対策について、参考にした情報源などを 引用しつつ簡潔にまとめてください。 本講義の感想、要望、質問などあれば、書 いてください。 https://moodle.artsci.kyushu-u.ac.jp/course/view.php?id=2661
© Copyright 2024 ExpyDoc