Cookies Hacking
Try Hard Security Group
Cookie属性
Cookieには、ユーザーのブラウザでの動作を制御するいくつかの属性が付属しています。以下はこれらの属性についての概要です(より受動的な声で):
有効期限とMax-Age
Cookieの有効期限はExpires
属性によって決定されます。逆に、Max-age
属性はCookieが削除されるまでの秒数を定義します。より現代的な慣行を反映するためにMax-age
を選択してください。
ドメイン
Cookieを受け取るホストはDomain
属性で指定されます。デフォルトでは、これはCookieを発行したホストに設定されており、そのサブドメインは含まれません。ただし、Domain
属性が明示的に設定されている場合、サブドメインも含まれます。これにより、Domain
属性の指定は、サブドメイン間でCookieを共有する必要があるシナリオに役立つより制限の少ないオプションとなります。たとえば、Domain=mozilla.org
を設定すると、developer.mozilla.org
などのサブドメインでCookieにアクセスできます。
パス
要求されたURLに存在する必要がある特定のURLパスは、Path
属性で示されます。この属性は、/
文字をディレクトリセパレータとして考慮し、サブディレクトリでも一致させることができます。
順序付けルール
同じ名前の2つのCookieがある場合、送信するCookieは次の基準に基づいて選択されます:
要求されたURL内の最も長いパスに一致するCookie。
パスが同じ場合は、最も最近に設定されたCookie。
SameSite
SameSite
属性は、サードパーティドメインからのリクエストでCookieが送信されるかどうかを指示します。3つの設定があります:Strict: サードパーティリクエストでCookieの送信を制限します。
Lax: サードパーティウェブサイトによって開始されたGETリクエストでCookieの送信を許可します。
None: 任意のサードパーティドメインからCookieの送信を許可します。
Cookieを構成する際には、これらの属性を理解することで、さまざまなシナリオで期待どおりに動作することを確認できます。
リクエストタイプ | 例のコード | Cookieの送信時 |
リンク | <a href="..."></a> | NotSet*, Lax, None |
プリレンダー | <link rel="prerender" href=".."/> | NotSet*, Lax, None |
フォーム GET | <form method="GET" action="..."> | NotSet*, Lax, None |
フォーム POST | <form method="POST" action="..."> | NotSet*, None |
iframe | <iframe src="..."></iframe> | NotSet*, None |
AJAX | $.get("...") | NotSet*, None |
画像 | <img src="..."> | NetSet*, None |
Invictiからの表と若干変更されています。 SameSite属性を持つCookieは、ログインセッションが必要なCSRF攻撃を緩和します。
*Chrome80(2019年2月)から、SameSite属性のないCookieのデフォルト動作はlaxになります (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/). この変更を適用した後、Chromeでは、SameSiteポリシーのないCookieは、最初の2分間はNoneとして扱われ、その後はトップレベルのクロスサイトPOSTリクエストに対してLaxとして扱われます。
Cookiesフラグ
HttpOnly
これにより、クライアントがCookieにアクセスできなくなります(たとえば、document.cookie
を使用したJavaScriptなど)。
バイパス
ページがリクエストの応答としてCookieを送信している場合(たとえば、PHPinfoページなど)、XSSを悪用してこのページにリクエストを送信し、応答からCookieを盗むことが可能です(例はこちら)。
この方法は、サーバーからの応答としてTRACE HTTPリクエストを送信することでバイパスできます(このHTTPメソッドが利用可能な場合)。この技術はCross-Site Trackingと呼ばれます。
この技術は、現代のブラウザがJSからTRACEリクエストの送信を許可しないことによって回避されます。ただし、IE6.0 SP2に対して
TRACE
の代わりに\r\nTRACE
を送信するなど、特定のソフトウェアでこれをバイパスする方法が見つかっています。他の方法は、ブラウザのゼロ/デイ脆弱性を悪用することです。
Cookie Jarオーバーフローアタックを実行することで、HttpOnly Cookieを上書きすることが可能です:
Cookie Smuggling攻撃を使用してこれらのCookieを外部に送信することが可能です
Secure
リクエストは、通常HTTPSを介して送信される場合にのみ、HTTPリクエストでCookieを送信します。
Cookiesの接頭辞
__Secure-
で始まるCookieは、HTTPSで保護されたページから設定されたsecure
フラグと共に設定する必要があります。
__Host-
で始まるCookieには、いくつかの条件があります:
secure
フラグで設定する必要があります。HTTPSで保護されたページから発信する必要があります。
ドメインを指定することは禁止されており、サブドメインに送信されることを防ぎます。
これらのCookieのパスは
/
に設定する必要があります。
__Host-
で始まるCookieは、スーパードメインやサブドメインに送信することが許可されていません。この制限は、アプリケーションCookieを分離するのに役立ちます。したがって、すべてのアプリケーションCookieに__Host-
接頭辞を使用することは、セキュリティと分離を向上させるための良い慣行と考えられます。
Cookieの上書き
したがって、__Host-
接頭辞のCookieの保護の1つは、サブドメインからの上書きを防ぐことです。たとえば、Cookie Tossing attacksを防ぎます。Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper)というトークでは、例えば、パーサーをだまして、サブドメインから__HOST-接頭辞のCookieを設定することが可能であることが示されています。たとえば、名前の先頭や先頭と末尾に"="を追加するなどのトリックを使って:
または、PHPでは、Cookie名の先頭に他の文字を追加することが可能で、これらはアンダースコア文字に置換され、__HOST-
Cookieを上書きすることができました:
Cookie攻撃
カスタムCookieに機密データが含まれている場合は、それを確認してください(特にCTFをプレイしている場合)。脆弱性がある可能性があります。
Cookieのデコードと操作
Cookieに埋め込まれた機密データは常に検証する必要があります。Base64や類似の形式でエンコードされたCookieはしばしばデコードできます。この脆弱性により、攻撃者はCookieの内容を変更し、変更したデータをCookieにエンコードして他のユーザーをなりすますことができます。
セッションハイジャック
この攻撃は、ユーザーのCookieを盗んでアプリケーション内のアカウントに不正アクセスすることを含みます。盗んだCookieを使用することで、攻撃者は合法的なユーザーをなりすますことができます。
セッションフィクセーション
このシナリオでは、攻撃者が被害者を特定のCookieを使用してログインさせるようにだまします。アプリケーションがログイン時に新しいCookieを割り当てない場合、元のCookieを持っている攻撃者は被害者をなりすますことができます。この技術は、被害者が攻撃者から提供されたCookieでログインすることに依存しています。
サブドメインでXSSを見つけた場合やサブドメインを制御している場合は、次を参照してください:
pageCookie Tossingセッション寄付
ここでは、攻撃者が被害者に攻撃者のセッションCookieを使用するよう説得します。被害者は、自分のアカウントにログインしていると信じて、実際には攻撃者のアカウントのコンテキストで操作を行うことになります。
サブドメインでXSSを見つけた場合やサブドメインを制御している場合は、次を参照してください:
pageCookie Tossing前述のリンクをクリックして、JWTの欠陥について説明したページにアクセスしてください。
Cookieで使用されるJSON Web Tokens(JWT)には脆弱性が存在する可能性があります。JWTのハッキングに関する詳細情報やそれらを悪用する方法については、リンクされたJWTのハッキングに関する文書にアクセスすることをお勧めします。
クロスサイトリクエストフォージェリ(CSRF)
この攻撃は、現在認証されているWebアプリケーションでログインしているユーザーに、望ましくないアクションを実行させることを強制します。攻撃者は、脆弱なサイトに送信されるすべてのリクエストに自動的に送信されるCookieを悪用することができます。
空のCookie
(元の研究で詳細を確認してください)ブラウザは、名前のないCookieの作成を許可します。これはJavaScriptを使用して次のように示すことができます:
以下は、送信されたCookieヘッダーの結果です:a=v1; test value; b=v2;
。興味深いことに、空の名前Cookieが設定されると、他のCookieを制御する可能性があります。特定の値に空のCookieを設定することで、他のCookieを操作できます。
Chromeのバグ: Unicodeサロゲートコードポイントの問題
Chromeでは、設定されたクッキーにUnicodeサロゲートコードポイントが含まれている場合、document.cookie
が破損し、その後空の文字列が返されます。
これにより、document.cookie
が空の文字列を出力し、永続的な破損が示されます。
パーシングの問題によるCookieスマグリング
(元の研究で詳細を確認してください)Java(Jetty、TomCat、Undertow)およびPython(Zope、cherrypy、web.py、aiohttp、bottle、webob)を含むいくつかのWebサーバーは、古いRFC2965サポートのためにCookie文字列を誤処理しています。セミコロンを含む場合でも、ダブルクォートで囲まれたCookie値を通常はキーと値のペアを区切るはずのセミコロンとして読み取ります。
Cookie Injection Vulnerabilities
(詳細はオリジナルリサーチを参照) サーバーによるクッキーの誤った解析、特にUndertow、Zope、Pythonのhttp.cookie.SimpleCookie
およびhttp.cookie.BaseCookie
を使用しているサーバーは、クッキーインジェクション攻撃の機会を作成します。これらのサーバーは新しいクッキーの開始を適切に区切れず、攻撃者がクッキーをスプーフィングすることを可能にします:
Undertowは、セミコロンなしで引用された値の直後に新しいクッキーを期待します。
Zopeは、次のクッキーの解析を開始するためにコンマを探します。
Pythonのクッキークラスは、スペース文字で解析を開始します。
この脆弱性は、クッキーをベースとするCSRF保護に依存するWebアプリケーションにおいて特に危険であり、攻撃者がスプーフィングされたCSRFトークンクッキーを注入し、セキュリティ対策を迂回する可能性があります。この問題は、Pythonが重複するクッキー名の処理によって悪化し、最後の出現が以前のものを上書きする点に関して懸念があります。また、安全でないコンテキストでの__Secure-
および__Host-
クッキーについても懸念があり、クッキーがスプーフィングに対して脆弱なバックエンドサーバーに渡された場合、認可のバイパスにつながる可能性があります。
追加の脆弱なクッキーチェック
基本的なチェック
クッキーはログインごとに同じです。
ログアウトして同じクッキーを使用してみてください。
同じクッキーを使用して同じアカウントに2つのデバイス(またはブラウザ)でログインしようとしてみてください。
クッキーに情報が含まれているかどうかを確認し、それを変更してみてください。
ほぼ同じユーザー名で複数のアカウントを作成し、類似点が見られるかどうかを確認してください。
存在する場合は「remember me」オプションをチェックして、その動作を確認してください。存在し、脆弱である場合は、常に他のクッキーなしでremember meのクッキーを使用してください。
パスワードを変更した後も以前のクッキーが機能するかどうかを確認してください。
高度なクッキー攻撃
ログイン時にクッキーが同じ(またはほぼ同じ)ままである場合、おそらくクッキーはアカウントのいくつかのフィールドに関連しています(おそらくユーザー名)。その場合、次のことができます:
非常に類似したユーザー名で多くのアカウントを作成し、アルゴリズムがどのように機能しているかを推測してみてください。
ユーザー名をブルートフォースしてみてください。クッキーがユーザー名の認証方法としてのみ保存されている場合、ユーザー名が「Bmin」のアカウントを作成し、クッキーの各ビットをブルートフォースしてみてください。その中には「admin」に属するクッキーの1つが含まれる可能性があります。
パディング オラクルを試してみてください(クッキーの内容を復号化できます)。padbusterを使用してください。
パディングオラクル - Padbusterの例
Padbusterは複数の試行を行い、どの条件がエラー条件であるか(有効ではない条件)を尋ねます。
その後、クッキーの復号化を開始します(数分かかる場合があります)。
攻撃が成功した場合、任意の文字列を暗号化してみることができます。たとえば、user=administratorを暗号化したい場合
この実行では、文字列user=administratorが内部に含まれたクッキーが正しく暗号化およびエンコードされます。
CBC-MAC
クッキーには値が含まれ、CBCを使用して署名される可能性があります。その後、値の整合性は、同じ値を使用してCBCを使用して作成された署名です。 IVとしてヌルベクトルを使用することが推奨されているため、この種の整合性チェックは脆弱になる可能性があります。
攻撃
ユーザー名administの署名を取得する = t
ユーザー名rator\x00\x00\x00 XOR tの署名を取得する = t'
クッキーに値**administrator+t'**を設定する(t'は(rator\x00\x00\x00 XOR t)XOR tの有効な署名になります = rator\x00\x00\x00
ECB
クッキーがECBを使用して暗号化されている場合、脆弱になる可能性があります。 ログインするときに受け取るクッキーは常に同じでなければなりません。
検出および攻撃方法:
ほぼ同じデータ(ユーザー名、パスワード、メールなど)を持つ2つのユーザーを作成し、与えられたクッキーの中にパターンがあるかどうかを調べてみてください。
たとえば「aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa」という名前のユーザーを作成し、クッキーにパターンがあるかどうかを確認します(ECBは同じ鍵でブロックごとに暗号化するため、ユーザー名が暗号化されると同じ暗号化されたバイトが現れる可能性があります)。
パターンがあるはずです(使用されるブロックのサイズで)。したがって、一連の「a」がどのように暗号化されるかを知っている場合、ユーザー名を作成できます: "a"*(ブロックのサイズ)+"admin"。その後、クッキーから1つのブロックの「a」の暗号化されたパターンを削除できます。そして、ユーザー名「admin」のクッキーを取得できます。
参考文献
Try Hard Security Group
Last updated