Cookies Hacking
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Cookiesには、ユーザーのブラウザでの動作を制御するいくつかの属性があります。これらの属性の概要は以下の通りです。
Cookieの有効期限はExpires
属性によって決まります。対照的に、Max-age
属性はCookieが削除されるまでの秒数を定義します。Max-age
を選択することをお勧めします。これはより現代的な慣行を反映しています。
Cookieを受け取るホストはDomain
属性によって指定されます。デフォルトでは、これはCookieを発行したホストに設定され、サブドメインは含まれません。しかし、Domain
属性が明示的に設定されると、サブドメインも含まれます。これにより、サブドメイン間でのCookie共有が必要なシナリオで役立つ、Domain
属性の指定が制限されないオプションとなります。たとえば、Domain=mozilla.org
を設定すると、developer.mozilla.org
のようなサブドメインでCookieにアクセスできます。
Cookie
ヘッダーが送信されるために要求されたURLに存在しなければならない特定のURLパスは、Path
属性によって示されます。この属性は/
文字をディレクトリセパレーターとして考慮し、サブディレクトリ内での一致も可能にします。
同じ名前のCookieが2つある場合、送信されるCookieは以下に基づいて選択されます:
要求されたURL内で最も長いパスに一致するCookie。
パスが同じ場合は、最も最近設定されたCookie。
SameSite
属性は、Cookieがサードパーティのドメインからのリクエストで送信されるかどうかを決定します。3つの設定があります:
Strict: サードパーティのリクエストでCookieが送信されるのを制限します。
Lax: サードパーティのウェブサイトによって開始されたGETリクエストでCookieが送信されることを許可します。
None: どのサードパーティのドメインからでもCookieが送信されることを許可します。
Cookieを設定する際には、これらの属性を理解することで、さまざまなシナリオで期待通りに動作することを確保できます。
Request Type
Example Code
Cookies Sent When
Link
<a href="..."></a>
NotSet*, Lax, None
Prerender
<link rel="prerender" href=".."/>
NotSet*, Lax, None
Form GET
<form method="GET" action="...">
NotSet*, Lax, None
Form POST
<form method="POST" action="...">
NotSet*, None
iframe
<iframe src="..."></iframe>
NotSet*, None
AJAX
$.get("...")
NotSet*, None
Image
<img src="...">
NetSet*, None
Table from Invicti and slightly modified. _SameSite_属性を持つCookieは、CSRF攻撃を軽減します。ログインセッションが必要です。
*Chrome80(2019年2月)以降、CookieにSameSite属性がない場合のデフォルトの動作はLaxになります (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/). この変更を適用した後、ChromeではSameSiteポリシーのないCookieは最初の2分間はNoneとして扱われ、その後はトップレベルのクロスサイトPOSTリクエストに対してLaxとして扱われます。
これはクライアントがCookieにアクセスするのを防ぎます(例えばJavascript経由:document.cookie
)。
ページがリクエストのレスポンスとしてCookieを送信している場合(例えばPHPinfoページ)、XSSを悪用してこのページにリクエストを送り、レスポンスからCookieを盗むことが可能です(例はこちらを参照)。
TRACE HTTPリクエストを使用することでバイパス可能です。サーバーからのレスポンスは送信されたCookieを反映します。この技術はCross-Site Trackingと呼ばれます。
この技術は、モダンブラウザがJSからTRACEリクエストを送信することを許可しないことによって回避されます。ただし、IE6.0 SP2に対してTRACE
の代わりに\r\nTRACE
を送信するなど、特定のソフトウェアでのバイパスが見つかっています。
ブラウザのゼロデイ脆弱性を悪用することも可能です。
Cookie Jarオーバーフロー攻撃を実行することでHttpOnly Cookieを上書きすることが可能です:
Cookie Smuggling攻撃を使用してこれらのCookieを外部に持ち出すことが可能です。
リクエストは、HTTPSなどの安全なチャネルを介して送信される場合にのみ、HTTPリクエストでCookieを送信します。
__Secure-
で始まるCookieは、HTTPSで保護されたページからsecure
フラグとともに設定される必要があります。
__Host-
で始まるCookieには、いくつかの条件が満たされなければなりません:
secure
フラグで設定されなければなりません。
HTTPSで保護されたページから発信されなければなりません。
ドメインを指定することは禁じられており、サブドメインへの送信を防ぎます。
これらのCookieのパスは/
に設定されなければなりません。
__Host-
で始まるCookieは、スーパードメインやサブドメインに送信されることは許可されていないことに注意することが重要です。この制限は、アプリケーションCookieを隔離するのに役立ちます。したがって、すべてのアプリケーションCookieに__Host-
プレフィックスを使用することは、セキュリティと隔離を強化するための良いプラクティスと見なされます。
したがって、__Host-
で始まるCookieの保護の1つは、サブドメインから上書きされるのを防ぐことです。たとえば、Cookie Tossing attacksを防ぎます。トークでCookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper)では、パーサーを騙すことでサブドメインから__HOST-で始まるCookieを設定することが可能であることが示されています。たとえば、最初や最後に=
を追加することなどです:
また、PHPではCookie名の最初に他の文字を追加することで、アンダースコア文字に置き換えられ、__HOST-
Cookieを上書きすることが可能でした:
カスタムCookieに機密データが含まれている場合は、それを確認してください(特にCTFをプレイしている場合)、脆弱性があるかもしれません。
Cookieに埋め込まれた機密データは常に精査されるべきです。Base64や類似の形式でエンコードされたCookieは、しばしばデコード可能です。この脆弱性により、攻撃者はCookieの内容を変更し、修正されたデータを再度Cookieにエンコードすることで他のユーザーを偽装することができます。
この攻撃は、ユーザーのCookieを盗むことで、アプリケーション内のアカウントに不正アクセスを得ることを含みます。盗まれたCookieを使用することで、攻撃者は正当なユーザーを偽装できます。
このシナリオでは、攻撃者が被害者を特定のCookieを使用してログインさせるように仕向けます。アプリケーションがログイン時に新しいCookieを割り当てない場合、攻撃者は元のCookieを持っているため、被害者を偽装できます。この技術は、被害者が攻撃者が提供したCookieでログインすることに依存しています。
サブドメインにXSSを見つけた場合やサブドメインを制御している場合は、次をお読みください:
ここでは、攻撃者が被害者に攻撃者のセッションCookieを使用させるように仕向けます。被害者は自分のアカウントにログインしていると信じて、攻撃者のアカウントのコンテキストで意図せずにアクションを実行します。
サブドメインにXSSを見つけた場合やサブドメインを制御している場合は、次をお読みください:
前のリンクをクリックして、JWTの可能な欠陥を説明するページにアクセスしてください。
Cookieで使用されるJSON Web Tokens (JWT)も脆弱性を示す可能性があります。潜在的な欠陥とそれを悪用する方法についての詳細情報を得るには、JWTをハッキングするためのリンクされた文書にアクセスすることをお勧めします。
この攻撃は、ログイン中のユーザーに対して、現在認証されているWebアプリケーションで不要なアクションを実行させるものです。攻撃者は、脆弱なサイトへのすべてのリクエストに自動的に送信されるCookieを悪用できます。
(詳細は元の研究を参照してください)ブラウザは名前のないCookieの作成を許可しており、JavaScriptを通じて次のように示すことができます:
送信されたクッキー ヘッダーの結果は a=v1; test value; b=v2;
です。興味深いことに、これは空の名前のクッキーが設定されている場合にクッキーを操作することを可能にし、空のクッキーを特定の値に設定することで他のクッキーを制御する可能性があります。
これにより、ブラウザはすべてのウェブサーバーによって a
という名前のクッキーと b
という値を持つクッキーとして解釈されるクッキー ヘッダーを送信します。
Chrome では、Unicode サロゲート コードポイントが設定されたクッキーの一部である場合、document.cookie
が破損し、その後空の文字列を返します:
この結果、document.cookie
が空の文字列を出力し、永続的な破損を示します。
(詳細は元の研究を参照) Java(Jetty、TomCat、Undertow)やPython(Zope、cherrypy、web.py、aiohttp、bottle、webob)を含むいくつかのウェブサーバーは、古いRFC2965サポートのためにクッキー文字列を誤って処理します。彼らは、セミコロンを含んでいても、ダブルクオートされたクッキー値を単一の値として読み取ります。これは通常、キーと値のペアを区切るべきです。
(Check further details in theoriginal research) サーバーによるクッキーの不適切な解析、特にUndertow、Zope、およびPythonのhttp.cookie.SimpleCookie
とhttp.cookie.BaseCookie
を使用しているものは、クッキーインジェクション攻撃の機会を生み出します。これらのサーバーは新しいクッキーの開始を適切に区切ることができず、攻撃者がクッキーを偽装することを可能にします:
Undertowは、セミコロンなしで引用された値の直後に新しいクッキーを期待します。
Zopeは、次のクッキーの解析を開始するためにカンマを探します。
Pythonのクッキークラスは、スペース文字で解析を開始します。
この脆弱性は、クッキーベースのCSRF保護に依存するWebアプリケーションにとって特に危険です。攻撃者が偽装されたCSRFトークンクッキーを注入できるため、セキュリティ対策を回避する可能性があります。この問題は、Pythonが重複したクッキー名を処理する方法によって悪化し、最後の出現が以前のものを上書きします。また、__Secure-
および__Host-
クッキーが不安全なコンテキストで扱われることに対する懸念も生じ、クッキーが偽装に対して脆弱なバックエンドサーバーに渡されると、認可のバイパスが発生する可能性があります。
According to this blogpost, **$Version=1
というクッキー属性を使用して、RFC2109のためにバックエンドが古いロジックを使用してクッキーを解析することが可能かもしれません。さらに、$Domain
や$Path
**のような他の値も、クッキーを使用してバックエンドの動作を変更するために使用できます。
この解析は、クッキー内のエスケープされた値をアンエスケープすることを示しています。したがって、"\a"は"a"になります。これはWAFを回避するのに役立つ可能性があります:
eval('test') => forbidden
"\e\v\a\l\(\'\t\e\s\t\'\)" => allowed
RFC2109では、カンマをクッキー値の区切りとして使用できることが示されています。また、等号の前後にスペースやタブを追加することも可能です。したがって、クッキー$Version=1; foo=bar, abc = qux
は、クッキー"foo":"bar, admin = qux"
を生成するのではなく、クッキーfoo":"bar"
と"admin":"qux"
を生成します。2つのクッキーが生成され、adminの前後のスペースが削除されたことに注意してください。
最後に、異なるバックドアは、異なるクッキーヘッダーで渡された異なるクッキーを文字列に結合します。
これにより、この例のようにWAFをバイパスできる可能性があります:
クッキーがログインするたびに同じです。
ログアウトして、同じクッキーを使用してみてください。
2つのデバイス(またはブラウザ)で同じアカウントに同じクッキーを使ってログインしてみてください。
クッキーに情報が含まれているか確認し、変更を試みてください。
ほぼ同じユーザー名でいくつかのアカウントを作成し、類似点が見えるか確認してください。
"ログイン状態を保持する"オプションが存在する場合、それがどのように機能するか確認してください。存在し、脆弱である可能性がある場合は、他のクッキーを使用せずにログイン状態を保持するのクッキーを常に使用してください。
パスワードを変更しても前のクッキーが機能するか確認してください。
ログイン時にクッキーが同じ(またはほぼ同じ)である場合、これはおそらくクッキーがあなたのアカウントのいくつかのフィールド(おそらくユーザー名)に関連していることを意味します。次に、あなたは:
非常に似たユーザー名でたくさんのアカウントを作成し、アルゴリズムがどのように機能しているかを推測してみてください。
ユーザー名をブルートフォースしてみてください。クッキーがあなたのユーザー名の認証方法としてのみ保存されている場合、ユーザー名"Bmin"でアカウントを作成し、クッキーのすべてのビットをブルートフォースすることができます。なぜなら、あなたが試すクッキーの1つは"admin"に属するものだからです。
パディング オラクルを試してください(クッキーの内容を復号化できます)。padbusterを使用してください。
パディングオラクル - Padbusterの例
Padbusterは複数回の試行を行い、どの条件がエラー条件(無効なもの)であるかを尋ねます。
その後、クッキーの復号を開始します(数分かかる場合があります)。
攻撃が成功した場合、任意の文字列を暗号化してみることができます。たとえば、encrypt 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"として作成できます。その後、クッキーから「a」のブロックの暗号化パターンを削除することができます。そして、ユーザー名「admin」のクッキーを得ることができます。
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)