93 KiB
Raw Blame History

XS-Search/XS-Leaks

{{#include ../../banners/hacktricks-training.md}}

基本情報

XS-Searchは、サイドチャネル脆弱性を利用してクロスオリジン情報を抽出するための手法です。

この攻撃に関与する主要なコンポーネントは以下の通りです:

  • 脆弱なウェブ: 情報を抽出することを目的としたターゲットウェブサイト。
  • 攻撃者のウェブ: 攻撃者が作成した悪意のあるウェブサイトで、被害者が訪問し、エクスプロイトをホストしています。
  • インクルージョンメソッド: 脆弱なウェブを攻撃者のウェブに組み込むために使用される技術window.open、iframe、fetch、hrefを持つHTMLタグなど
  • リーク技術: インクルージョンメソッドを通じて収集された情報に基づいて、脆弱なウェブの状態の違いを識別するために使用される技術。
  • 状態: 攻撃者が区別しようとする脆弱なウェブの2つの潜在的な条件。
  • 検出可能な違い: 攻撃者が脆弱なウェブの状態を推測するために依存する観察可能な変化。

検出可能な違い

脆弱なウェブの状態を区別するために分析できるいくつかの側面:

  • ステータスコード: サーバーエラー、クライアントエラー、または認証エラーなど、さまざまなHTTPレスポンスステータスコードをクロスオリジンで区別する。
  • API使用: 特定のJavaScript Web APIを使用しているかどうかを明らかにするために、ページ間でのWeb APIの使用を特定する。
  • リダイレクト: HTTPリダイレクトだけでなく、JavaScriptやHTMLによってトリガーされる異なるページへのナビゲーションを検出する。
  • ページコンテンツ: HTTPレスポンスボディやページのサブリソースにおける埋め込まれたフレームの数や画像のサイズの違いを観察する。
  • HTTPヘッダー: 特定のHTTPレスポンスヘッダーの存在またはその値を記録する。X-Frame-Options、Content-Disposition、Cross-Origin-Resource-Policyなどのヘッダーが含まれる。
  • タイミング: 2つの状態間の一貫した時間の違いに気付く。

インクルージョンメソッド

  • HTML要素: HTMLは、スタイルシート、画像、スクリプトなど、クロスオリジンリソースのインクルージョンのためのさまざまな要素を提供し、ブラウザに非HTMLリソースを要求させる。これに関する潜在的なHTML要素の一覧はhttps://github.com/cure53/HTTPLeaksで見つけることができます。
  • フレーム: iframeobject、およびembedなどの要素は、攻撃者のページにHTMLリソースを直接埋め込むことができます。ページがフレーミング保護を欠いている場合、JavaScriptはcontentWindowプロパティを介してフレーム化されたリソースのウィンドウオブジェクトにアクセスできます。
  • ポップアップ: window.openメソッドは、新しいタブまたはウィンドウでリソースを開き、JavaScriptがSOPに従ってメソッドやプロパティと対話するためのウィンドウハンドルを提供します。ポップアップは、シングルサインオンでよく使用され、ターゲットリソースのフレーミングおよびクッキー制限を回避します。ただし、最新のブラウザはポップアップの作成を特定のユーザーアクションに制限しています。
  • JavaScriptリクエスト: JavaScriptは、XMLHttpRequestsFetch APIを使用してターゲットリソースへの直接リクエストを許可します。これらのメソッドは、HTTPリダイレクトに従うかどうかを選択するなど、リクエストに対する正確な制御を提供します。

リーク技術

  • イベントハンドラー: XS-Leaksにおける古典的なリーク技術で、onloadonerrorのようなイベントハンドラーがリソースの読み込み成功または失敗に関する洞察を提供します。
  • エラーメッセージ: JavaScriptの例外や特別なエラーページは、エラーメッセージから直接またはその存在と不在を区別することによってリーク情報を提供できます。
  • グローバル制限: メモリ容量や他の強制されたブラウザ制限など、ブラウザの物理的制限は、しきい値に達したときに信号を送ることができ、リーク技術として機能します。
  • グローバル状態: ブラウザのグローバル状態(例:履歴インターフェース)との検出可能な相互作用を悪用できます。たとえば、ブラウザの履歴のエントリ数は、クロスオリジンページに関する手がかりを提供できます。
  • パフォーマンスAPI: このAPIは、現在のページのパフォーマンス詳細を提供し、ドキュメントや読み込まれたリソースのネットワークタイミングを含み、要求されたリソースに関する推測を可能にします。
  • 読み取り可能な属性: 一部のHTML属性はクロスオリジンで読み取り可能であり、リーク技術として使用できます。たとえば、window.frame.lengthプロパティは、JavaScriptがクロスオリジンのウェブページに含まれるフレームの数をカウントすることを可能にします。

XSinatorツールと論文

XSinatorは、いくつかの既知のXS-Leaksに対してブラウザをチェックする自動ツールです。詳細はその論文に説明されています:https://xsinator.com/paper.pdf

ツールにはhttps://xsinator.com/アクセスできます

Warning

除外されたXS-Leaks: 他のリークに干渉するため、サービスワーカーに依存するXS-Leaksを除外する必要がありました。さらに、特定のウェブアプリケーションの誤設定やバグに依存するXS-Leaksも除外することにしました。たとえば、CrossOrigin Resource Sharing (CORS)の誤設定、postMessageリーク、またはCross-Site Scriptingです。加えて、時間ベースのXS-Leaksも除外しました。なぜなら、これらはしばしば遅く、イズが多く、不正確であるからです。

タイミングベースの技術

以下の技術のいくつかは、ウェブページの可能な状態の違いを検出するプロセスの一部としてタイミングを使用します。ウェブブラウザで時間を測定する方法はいくつかあります。

時計: performance.now() APIは、開発者が高解像度のタイミング測定を取得することを可能にします。
攻撃者が暗黙の時計を作成するために悪用できるAPIは多数ありますBroadcast Channel APIMessage Channel APIrequestAnimationFramesetTimeout、CSSアニメーションなど。
詳細については、https://xsleaks.dev/docs/attacks/timing-attacks/clocksを参照してください。

イベントハンドラ技術

Onload/Onerror

{{#ref}} cookie-bomb-+-onerror-xs-leak.md {{#endref}}

コード例はJSからスクリプトオブジェクトを読み込もうとしますが他のタグ(オブジェクト、スタイルシート、画像、オーディオなど)も使用できます。さらに、タグを直接挿入し、タグ内でonloadおよびonerrorイベントを宣言することも可能ですJSから挿入するのではなく

この攻撃にはスクリプトなしのバージョンもあります:

<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>

この場合、example.com/404 が見つからない場合、attacker.com/?error が読み込まれます。

Onload Timing

{{#ref}} performance.now-example.md {{#endref}}

Onload Timing + Forced Heavy Task

この技術は前のものと似ていますが、attacker関連する時間 をかける アクションを強制 し、応答が肯定的または否定的 の場合にその時間を測定します。

{{#ref}} performance.now-+-force-heavy-task.md {{#endref}}

unload/beforeunload Timing

リソースを取得するのにかかる時間は、unload および beforeunload イベントを利用して測定できます。beforeunload イベントは、ブラウザが新しいページに移動しようとしているときに発生し、unload イベントは、実際にナビゲーションが行われているときに発生します。これら2つのイベント間の時間差を計算することで、ブラウザがリソースを取得するのにかかった時間 を特定できます。

Sandboxed Frame Timing + onload

Framing Protections がない場合、ページとそのサブリソースがネットワーク上で読み込まれるのにかかる時間を攻撃者が測定できることが観察されています。この測定は、iframe の onload ハンドラーがリソースの読み込みと JavaScript の実行が完了した後にのみトリガーされるため、通常可能です。スクリプト実行によって導入される変動を回避するために、攻撃者は <iframe> 内で sandbox 属性を使用することがあります。この属性を含めることで、多くの機能が制限され、特に JavaScript の実行が制限されるため、ネットワークパフォーマンスによって主に影響を受ける測定が容易になります。

// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>

#ID + error + onload

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info:
  • Summary: 正しいコンテンツにアクセスしたときにページがエラーを出し、任意のコンテンツにアクセスしたときに正しく読み込まれるようにできる場合、時間を測定することなくすべての情報を抽出するためのループを作成できます。
  • Code Example:

ページに秘密のコンテンツをIframe内に挿入できると仮定します。

被害者にIframeを使用して"flag"を含むファイルを検索させることができます例えば、CSRFを悪用。Iframe内では、_onload event_が常に少なくとも一度は実行されることがわかっています。次に、URLiframeを変更できますが、URL内のハッシュ内容のみを変更します。

例えば:

  1. URL1: www.attacker.com/xssearch#try1
  2. URL2: www.attacker.com/xssearch#try2

最初のURLが正常に読み込まれた場合、URLのハッシュ部分を変更すると、onloadイベントは再度トリガーされません。しかし、ページが読み込み時に何らかのエラーを持っていた場合、onloadイベントは再度トリガーされます

これにより、正しく読み込まれたページと、アクセス時にエラーが発生したページを区別できます。

Javascript Execution

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info:
  • Summary: ページが機密コンテンツを返す、またはユーザーによって制御可能なコンテンツを返す場合。ユーザーは無効な場合に有効なJSコードを設定し、各試行を**<script>タグ内で読み込むことができます。無効な場合、攻撃者のコード実行され**、有効な場合は何も実行されません。
  • Code Example:

{{#ref}} javascript-execution-xs-leak.md {{#endref}}

CORB - Onerror

  • Inclusion Methods: HTML Elements
  • Detectable Difference: Status Code & Headers
  • More info: https://xsleaks.dev/docs/attacks/browser-features/corb/
  • Summary: **Cross-Origin Read Blocking (CORB)**は、攻撃から保護するために特定の機密クロスオリジンリソースの読み込みを防ぐセキュリティ対策です。しかし、攻撃者はその保護動作を悪用できます。CORBの対象となる応答がnosniff2xxステータスコードを持つ_CORB保護された_ Content-Typeを返すと、CORBは応答の本文とヘッダーを削除します。これを観察する攻撃者は、ステータスコード(成功またはエラーを示す)とContent-TypeCORBによって保護されているかどうかを示す)の組み合わせを推測し、潜在的な情報漏洩につながります。
  • Code Example:

攻撃に関する詳細情報は、より多くの情報リンクを確認してください。

onblur

iframe内にページを読み込むことができ、#id_valueを使用して、指定されたifのiframeの要素にフォーカスを当てることができます。次に、**onblur信号がトリガーされると、ID要素が存在します。
同様の攻撃を
portal**タグで実行できます。

postMessage Broadcasts

  • Inclusion Methods: Frames, Pop-ups
  • Detectable Difference: API Usage
  • More info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
  • Summary: postMessageから機密情報を収集するか、postMessagesの存在をオラクルとして使用してページ内のユーザーのステータスを知る
  • Code Example: Any code listening for all postMessages.

アプリケーションは、異なるオリジン間で通信するためにしばしばpostMessage broadcastsを利用します。しかし、この方法は、targetOriginパラメータが適切に指定されていない場合、機密情報を不注意に露出させる可能性があります。さらに、メッセージを受信する行為自体がオラクルとして機能する可能性があります。たとえば、特定のメッセージは、ログインしているユーザーにのみ送信される場合があります。したがって、これらのメッセージの存在または不在は、ユーザーの状態やアイデンティティに関する情報を明らかにすることができます。

Global Limits Techniques

WebSocket API

ターゲットページが使用しているWebSocket接続の数を特定することが可能です。これにより、攻撃者はアプリケーションの状態を検出し、WebSocket接続の数に関連する情報を漏洩させることができます。

あるオリジン最大数のWebSocket接続オブジェクトを使用している場合、接続状態に関係なく、新しいオブジェクトの作成はJavaScript例外を引き起こします。この攻撃を実行するために、攻撃者のウェブサイトはターゲットウェブサイトをポップアップまたはiframeで開き、ターゲットウェブが読み込まれた後、可能な限り最大数のWebSocket接続を作成しようとします。スローされた例外の数は、ターゲットウェブサイトのWebSocket接続の数です。

Payment API

このXS-Leakは、攻撃者がクロスオリジンページが支払いリクエストを開始したときを検出できるようにします。

支払いリクエストAPIを使用しているターゲットウェブサイトがある場合、同時にアクティブにできるのは1つのリクエストのみであるため、APIを使用しようとするさらなる試みは失敗し、JavaScript例外を引き起こします。攻撃者は、定期的にPayment API UIを表示しようとすることでこれを悪用できます。1回の試行で例外が発生した場合、ターゲットウェブサイトは現在それを使用しています。攻撃者は、作成後すぐにUIを閉じることで、これらの定期的な試行を隠すことができます。

Timing the Event Loop

{{#ref}} event-loop-blocking-+-lazy-images.md {{#endref}}

JavaScriptはシングルスレッドのイベントループの並行モデルで動作し、同時に1つのタスクしか実行できません。この特性は、異なるオリジンからのコードの実行にかかる時間を測定するために悪用できます。攻撃者は、固定プロパティを持つイベントを継続的にディスパッチすることで、イベントループ内で自分のコードの実行時間を測定できます。これらのイベントは、イベントプールが空のときに処理されます。他のオリジンも同じプールにイベントをディスパッチしている場合、攻撃者は自分のタスクの実行の遅延を観察することで、これらの外部イベントの実行にかかる時間を推測できます。遅延を監視するこの方法は、異なるオリジンからのコードの実行時間を明らかにし、機密情報を露出させる可能性があります。

Warning

実行時間の測定では、ネットワーク要因排除してより正確な測定を得ることが可能です。たとえば、ページを読み込む前に使用されるリソースを読み込むことによって。

Busy Event Loop

  • Inclusion Methods:
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
  • Summary: ウェブ操作の実行時間を測定する1つの方法は、スレッドのイベントループを意図的にブロックし、イベントループが再び利用可能になるまでの時間を測定することです。ブロッキング操作長い計算や同期API呼び出しなどをイベントループに挿入し、その後のコードが実行を開始するまでの時間を監視することで、ブロッキング期間中にイベントループで実行されていたタスクの期間を推測できます。この技術は、タスクが順次実行されるJavaScriptのシングルスレッドの性質を利用し、同じスレッドを共有する他の操作のパフォーマンスや動作に関する洞察を提供できます。
  • Code Example:

イベントループをロックして実行時間を測定する技術の大きな利点は、サイト分離を回避できる可能性です。サイト分離は、異なるウェブサイトを別々のプロセスに分離するセキュリティ機能であり、悪意のあるサイトが他のサイトから機密データに直接アクセスするのを防ぐことを目的としています。しかし、共有イベントループを通じて他のオリジンの実行タイミングに影響を与えることで、攻撃者はそのオリジンの活動に関する情報を間接的に抽出できます。この方法は、他のオリジンのデータに直接アクセスすることに依存せず、共有イベントループに対するそのオリジンの活動の影響を観察することで、サイト分離によって確立された保護バリアを回避します。

Warning

実行時間の測定では、ネットワーク要因排除してより正確な測定を得ることが可能です。たとえば、ページを読み込む前に使用されるリソースを読み込むことによって。

Connection Pool

  • Inclusion Methods: JavaScript Requests
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
  • Summary: 攻撃者はすべてのソケットを1つを除いてロックし、ターゲットウェブを読み込み、同時に別のページを読み込むことができ、最後のページが読み込みを開始するまでの時間がターゲットページの読み込みにかかった時間です。
  • Code Example:

{{#ref}} connection-pool-example.md {{#endref}}

ブラウザはサーバー通信のためにソケットを利用しますが、オペレーティングシステムとハードウェアのリソースが限られているため、ブラウザは同時に使用できるソケットの数に制限を設けざるを得ません。攻撃者は次の手順を通じてこの制限を悪用できます。

  1. ブラウザのソケット制限を確認します。例えば、256のグローバルソケット。
  2. 255のソケットを長時間占有するために、さまざまなホストに255のリクエストを開始し、接続を開いたままにします。
  3. 256番目のソケットを使用してターゲットページにリクエストを送信します。
  4. 別のホストに257番目のリクエストを試みます。すべてのソケットが使用中であるため手順2と3に従って、このリクエストはソケットが利用可能になるまでキューに入れられます。このリクエストが進行するまでの遅延は、256番目のソケットターゲットページのソケットに関連するネットワーク活動に関するタイミング情報を攻撃者に提供します。この推測が可能なのは、手順2の255のソケットがまだ使用中であるため、新たに利用可能なソケットは手順3から解放されたものである必要があるからです。したがって、256番目のソケットが利用可能になるまでの時間は、ターゲットページへのリクエストが完了するのにかかる時間に直接関連しています。

詳細については、https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/を参照してください。

Connection Pool by Destination

  • Inclusion Methods: JavaScript Requests
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info:
  • Summary: 前の技術と似ていますが、すべてのソケットを使用するのではなく、Google Chrome同じオリジンに対して6つの同時リクエストの制限を設けています。もし5つをブロックし、次に6番目のリクエストを発信すると、タイミングを測定でき、被害者ページが同じエンドポイントにリクエストを送信するようにできた場合、6番目のリクエスト長くかかり、それを検出できます。

Performance API Techniques

Performance APIは、ウェブアプリケーションのパフォーマンスメトリックに関する洞察を提供し、Resource Timing APIによってさらに強化されます。Resource Timing APIは、リクエストの期間など、詳細なネットワークリクエストのタイミングを監視することを可能にします。特に、サーバーが応答にTiming-Allow-Origin: *ヘッダーを含めると、転送サイズやドメインルックアップ時間などの追加データが利用可能になります。

この豊富なデータは、performance.getEntriesperformance.getEntriesByNameなどのメソッドを介して取得でき、パフォーマンス関連情報の包括的なビューを提供します。さらに、APIはperformance.now()から取得したタイムスタンプの差を計算することで、実行時間の測定を容易にします。ただし、Chromeなどのブラウザでは、performance.now()の精度がミリ秒に制限される場合があり、タイミング測定の粒度に影響を与える可能性があります。

タイミング測定を超えて、Performance APIはセキュリティ関連の洞察にも利用できます。たとえば、Chromeのperformanceオブジェクトにページが存在するかどうかは、X-Frame-Optionsの適用を示す可能性があります。具体的には、X-Frame-Optionsによってフレーム内でのレンダリングがブロックされているページは、performanceオブジェクトに記録されないため、ページのフレーミングポリシーに関する微妙な手がかりを提供します。

Error Leak

HTTP応答ステータスコードを区別することが可能です。なぜなら、エラーを引き起こすリクエストはパフォーマンスエントリを作成しないからです。

Style Reload Error

前の技術では、GCのブラウザバグにより、リソースが読み込まれないときに2回読み込まれる2つのケースが特定されました。これにより、Performance APIに複数のエントリが生成され、検出可能になります。

Request Merging Error

この技術は、前述の論文の表に見つかりましたが、技術の説明は見つかりませんでした。ただし、https://xsinator.com/testing.html#Request%20Merging%20Error%20Leakでソースコードを確認することができます。

Empty Page Leak

攻撃者は、リクエストが空のHTTP応答ボディを引き起こしたかどうかを検出できます。なぜなら、空のページは一部のブラウザでパフォーマンスエントリを作成しないからです。

XSS-Auditor Leak

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info: https://xsinator.com/paper.pdf (5.2)
  • Summary: セキュリティアサーションでXSS Auditorを使用することで、攻撃者は特定のウェブページ要素を検出できます。これは、作成されたペイロードが監査人のフィルタリングメカニズムをトリガーしたときの応答の変化を観察することによって行われます。
  • Code Example: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak

セキュリティアサーションSAにおいて、元々クロスサイトスクリプティングXSS攻撃を防ぐために設計されたXSS Auditorは、逆説的に機密情報を漏洩させるために悪用される可能性があります。この組み込み機能はGoogle ChromeGCから削除されましたが、SAにはまだ存在します。2013年、BraunとHeiderichは、XSS Auditorが正当なスクリプトを誤ってブロックし、偽陽性を引き起こす可能性があることを示しました。これに基づいて、研究者たちは情報を抽出し、クロスオリジンページ上の特定のコンテンツを検出する技術を開発しました。この概念はXS-Leaksとして知られ、最初にTeradaによって報告され、Heyesによってブログ投稿で詳述されました。これらの技術はGCのXSS Auditorに特有でしたが、SAではXSS AuditorによってブロックされたページはPerformance APIにエントリを生成しないことが発見され、機密情報が漏洩する可能性がある方法が明らかになりました。

X-Frame Leak

ページがiframe内でレンダリングされることが許可されていない場合、パフォーマンスエントリを作成しません。その結果、攻撃者は応答ヘッダー**X-Frame-Options**を検出できます。
embed タグを使用した場合も同様です。

Download Detection

前述のXS-Leakと同様に、ContentDispositionヘッダーによってダウンロードされるリソースパフォーマンスエントリを作成しません。この技術はすべての主要なブラウザで機能します。

Redirect Start Leak

一部のブラウザがクロスオリジンリクエストに対して過剰な情報を記録する動作を悪用するXS-Leakのインスタンスが見つかりました。標準では、クロスオリジンリソースに対してゼロに設定すべき属性のサブセットが定義されています。しかし、SAでは、ターゲットページによってユーザーがリダイレクトされたかどうかを、Performance APIを照会し、redirectStartタイミングデータを確認することで検出できます。

Duration Redirect Leak

GCでは、リダイレクトを引き起こすリクエストの持続時間であり、リダイレクトが発生しないリクエストと区別できます。

CORP Leak

場合によっては、nextHopProtocolエントリを漏洩技術として使用できます。GCでは、CORPヘッダーが設定されている場合、nextHopProtocolはになります。SAでは、CORP対応リソースに対してパフォーマンスエントリがまったく作成されないことに注意してください。

Service Worker

サービスワーカーは、オリジンで実行されるイベント駆動型スクリプトコンテキストです。これらはウェブページのバックグラウンドで実行され、リソースをインターセプト、変更、およびキャッシュしてオフラインウェブアプリケーションを作成できます。
サービスワーカーによってキャッシュされたリソースiframeを介してアクセスされると、そのリソースはサービスワーカーキャッシュから読み込まれます
リソースがサービスワーカーキャッシュから**読み込まれたかどうかを検出するために、Performance APIを使用できます。
これもタイミング攻撃で行うことができます(詳細については論文を参照してください)。

Cache

Performance APIを使用して、リソースがキャッシュされているかどうかを確認できます。

Network Duration

Error Messages Technique

Media Error

// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false)
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg
}

function startup() {
let audioElement = document.getElementById("audio")
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener(
"click",
function () {
audioElement.src = document.getElementById("testUrl").value
},
false
)
// Create the event handler
var errHandler = function () {
let err = this.error
let message = err.message
let status = ""

// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if (
message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1 ||
message.indexOf("Failed to init decoder") != -1
) {
status = "Success"
} else {
status = "Error"
}
displayErrorMessage(
"<strong>Status: " +
status +
"</strong> (Error code:" +
err.code +
" / Error Message: " +
err.message +
")<br>"
)
}
audioElement.onerror = errHandler
}

MediaErrorインターフェースのメッセージプロパティは、成功裏に読み込まれたリソースを一意に識別する特定の文字列を持っています。攻撃者はこの機能を利用して、メッセージの内容を観察することで、クロスオリジンリソースの応答ステータスを推測できます。

CORSエラー

この技術により、攻撃者はクロスオリジンサイトのリダイレクト先を抽出することができます。具体的には、CORS対応リクエストがユーザーの状態に基づいてリダイレクトを発行するターゲットサイトに送信され、ブラウザがそのリクエストを拒否した場合、リダイレクトのターゲットの完全なURLがエラーメッセージ内に開示されます。この脆弱性は、リダイレクトの事実を明らかにするだけでなく、リダイレクトのエンドポイントや含まれる可能性のある機密のクエリパラメータも公開します。

SRIエラー

攻撃者は冗長なエラーメッセージを利用して、クロスオリジンの応答のサイズを推測できます。これは、サブリソース整合性(SRI)のメカニズムによるもので、整合性属性を使用して、CDNから取得されたリソースが改ざんされていないことを検証します。SRIがクロスオリジンリソースで機能するためには、これらがCORS対応である必要があります。そうでない場合、整合性チェックの対象にはなりません。セキュリティアサーション(SA)において、CORSエラーXSリークと同様に、整合性属性を持つフェッチリクエストが失敗した後にエラーメッセージをキャプチャできます。攻撃者は、任意のリクエストの整合性属性に偽のハッシュ値を割り当てることで、このエラーを意図的にトリガーできます。SAでは、結果として得られるエラーメッセージが要求されたリソースのコンテンツ長を意図せず明らかにします。この情報漏洩により、攻撃者は応答サイズの変動を識別でき、洗練されたXSリーク攻撃への道を開きます。

CSP違反/検出

XSリークは、CSPを使用してクロスオリジンサイトが異なるオリジンにリダイレクトされたかどうかを検出できます。このリークはリダイレクトを検出できますが、さらにリダイレクトターゲットのドメインも漏洩します。この攻撃の基本的なアイデアは、攻撃者サイトでターゲットドメインを許可することです。ターゲットドメインにリクエストが発行されると、リダイレクトがクロスオリジンドメインに行われます。CSPはそのアクセスをブロックし、違反レポートを作成してリーク技術として使用します。ブラウザによっては、このレポートがリダイレクトのターゲット位置を漏洩する可能性があります
最新のブラウザは、リダイレクト先のURLを示しませんが、クロスオリジンリダイレクトがトリガーされたことを検出することはできます。

キャッシュ

ブラウザは、すべてのウェブサイトに対して1つの共有キャッシュを使用する場合があります。オリジンに関係なく、ターゲットページが特定のファイルを要求したかどうかを推測することが可能です

ページがユーザーがログインしている場合にのみ画像を読み込む場合、リソースを無効にし(キャッシュされていない場合はそうなります、詳細情報リンクを参照)、そのリソースを読み込む可能性のあるリクエストを実行し、不正なリクエスト(例:過剰なリファラーヘッダーを使用)でリソースを読み込もうとします。リソースの読み込みがエラーをトリガーしなかった場合、それはキャッシュされていたからです。

CSPディレクティブ

Google Chrome(GC)の新機能により、ウェブページはiframe要素に属性を設定することでコンテンツセキュリティポリシー(CSP)を提案でき、ポリシーディレクティブがHTTPリクエストと共に送信されます。通常、埋め込まれたコンテンツはこれをHTTPヘッダーを介して承認する必要があり、さもなければエラーページが表示されます。ただし、iframeがすでにCSPによって管理されており、新たに提案されたポリシーがより制限的でない場合、ページは通常通り読み込まれます。このメカニズムは、攻撃者がクロスオリジンページの特定のCSPディレクティブを検出するための道を開きます。エラーページを特定することができる新しいリーク技術が発見され、根本的な問題が完全に解決されていないことを示唆しています。

CORP

CORPヘッダーは比較的新しいウェブプラットフォームのセキュリティ機能で、設定されると指定されたリソースへのno-corsクロスオリジンリクエストをブロックします。ヘッダーの存在は検出可能で、CORPで保護されたリソースは取得されるとエラーを発生させます

CORB

攻撃についての詳細情報はリンクを確認してください。

オリジンリフレクションの誤設定によるCORSエラー

OriginヘッダーAccess-Control-Allow-Originヘッダーに反映されている場合、攻撃者はこの動作を悪用してCORSモードでリソースを取得しようとできます。エラートリガーされない場合、それはウェブから正しく取得されたことを意味し、エラーがトリガーされる場合、それはキャッシュからアクセスされたことを意味しますエラーは、キャッシュが元のドメインを許可するCORSヘッダーを持つ応答を保存しているために発生します
オリジンが反映されていないがワイルドカードが使用されている場合(Access-Control-Allow-Origin: *)、これは機能しません。

読み取り可能な属性技術

フェッチリダイレクト

redirect: "manual"などのパラメータを使用してFetch APIを介してリクエストを送信すると、response.type属性を読み取ることができ、opaqueredirectと等しい場合、応答はリダイレクトでした。

COOP

攻撃者は、クロスオリジンHTTP応答におけるクロスオリジンオープナーポリシー(COOP)ヘッダーの存在を推測できます。COOPは、外部サイトが任意のウィンドウ参照を取得するのを妨げるためにウェブアプリケーションによって使用されます。このヘッダーの可視性は、contentWindow参照にアクセスしようとすることで判断できます。COOPが条件付きで適用されるシナリオでは、openerプロパティが明白な指標となりますCOOPが有効な場合は未定義であり、無効な場合は定義されています

URL最大長 - サーバーサイド

サーバーサイドリダイレクトがリダイレクト内でユーザー入力を使用し追加データを持つ場合、この動作を検出することが可能です。通常、サーバーにはリクエスト長の制限があります。もしユーザーデータがその長さ - 1であれば、リダイレクトそのデータを使用し何かを追加しているため、エラーがトリガーされ、エラーイベントを介して検出可能です

ユーザーにクッキーを設定できる場合、十分なクッキーを設定することによってこの攻撃を実行することもできます(クッキーボム)。その結果、正しい応答のサイズが増加しエラーがトリガーされます。この場合、同じサイトからこのリクエストをトリガーすると、<script>が自動的にクッキーを送信するため(エラーを確認できます)。
クッキーボム + XS-Searchの例は、この書き込みの意図された解決策に見つけることができます: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended

SameSite=Noneまたは同じコンテキストにいることが、この種の攻撃には通常必要です。

URL最大長 - クライアントサイド

Chromiumのドキュメントによると、Chromeの最大URL長は2MBです。

一般的に、_ウェブプラットフォーム_にはURLの長さに制限はありませんただし、2^31は一般的な制限です。_Chrome_は、実用的な理由とプロセス間通信におけるサービス拒否問題を回避するために、URLを最大2MBに制限しています。

したがって、リダイレクトURLの応答が一方のケースで大きい場合2MBを超えるURLでリダイレクトさせることが可能です。これが発生すると、Chromeは**about:blank#blocked**ページを表示します。

顕著な違いは、リダイレクト完了した場合、window.originエラーをスローすることです。クロスオリジンはその情報にアクセスできません。しかし、制限が****に達し、読み込まれたページが**about:blank#blockedであった場合、ウィンドウのoriginのものであり、これはアクセス可能な情報**です。

2MBに達するために必要なすべての追加情報は、最初のURLにハッシュを追加することで追加でき、リダイレクトで使用されます

{{#ref}} url-max-length-client-side.md {{#endref}}

最大リダイレクト

ブラウザの最大リダイレクト数が20の場合、攻撃者は19のリダイレクトでページを読み込もうとし、最終的に被害者をテストされたページに送信することができます。エラーがトリガーされる場合、そのページは被害者をリダイレクトしようとしていたことになります。

履歴の長さ

History APIは、JavaScriptコードがブラウザの履歴を操作できるようにし、ユーザーが訪れたページを保存します。攻撃者は、長さプロパティをインクルージョンメソッドとして使用できますJavaScriptとHTMLのナビゲーションを検出するために。
history.lengthを確認し、ユーザーにページに移動させ、同じオリジンに戻すことで、history.lengthの新しい値を確認します。

同じURLでの履歴の長さ

  • インクルージョンメソッド: フレーム、ポップアップ
  • 検出可能な違い: URLが推測されたものと同じかどうか
  • 概要: 履歴の長さを悪用して、フレーム/ポップアップの位置が特定のURLにあるかどうかを推測できます。
  • コード例: 以下

攻撃者は、JavaScriptコードを使用してフレーム/ポップアップの位置を推測されたものに操作しすぐにそれを**about:blankに変更することができます。履歴の長さが増加した場合、それはURLが正しかったことを意味し、同じであれば再読み込みされないため、増加する時間がありました。増加しなかった場合、それは推測されたURLを読み込もうとした**が、すぐにabout:blankを読み込んだため、履歴の長さは増加しなかったことを意味します。

async function debug(win, url) {
win.location = url + "#aaa"
win.location = "about:blank"
await new Promise((r) => setTimeout(r, 500))
return win.history.length
}

win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=c"))

win.close()
win = window.open("https://example.com/?a=b")
await new Promise((r) => setTimeout(r, 2000))
console.log(await debug(win, "https://example.com/?a=b"))

フレームカウント

iframe または window.open を介して開かれた ウェブのフレームの数をカウントすることで、そのページ上のユーザーの状態を特定するのに役立つかもしれません。
さらに、ページが常に同じ数のフレームを持っている場合、フレームの数を継続的にチェックすることで、情報が漏洩する可能性のあるパターンを特定するのに役立つかもしれません。

この技術の例として、Chrome では PDFフレームカウント によって 検出 されることがあります。なぜなら、内部で embed が使用されているからです。zoomviewpagetoolbar などのコンテンツに対する制御を許可する Open URL Parameters があり、この技術が興味深い場合があります。

HTMLElements

HTML要素を通じた情報漏洩は、特にユーザー情報に基づいて動的メディアファイルが生成される場合や、メディアサイズを変更する透かしが追加される場合に、ウェブセキュリティの懸念事項です。攻撃者は、特定のHTML要素によって公開された情報を分析することで、可能な状態を区別するためにこれを悪用することができます。

HTML要素によって公開される情報

  • HTMLMediaElement: この要素はメディアの durationbuffered 時間を明らかにし、そのAPIを介してアクセスできます。HTMLMediaElementについての詳細
  • HTMLVideoElement: videoHeightvideoWidth を公開します。一部のブラウザでは、webkitVideoDecodedByteCountwebkitAudioDecodedByteCount、および webkitDecodedFrameCount などの追加プロパティが利用可能で、メディアコンテンツに関するより詳細な情報を提供します。HTMLVideoElementについての詳細
  • getVideoPlaybackQuality(): この関数は、totalVideoFrames を含むビデオ再生品質に関する詳細を提供し、処理されたビデオデータの量を示すことができます。getVideoPlaybackQuality()についての詳細
  • HTMLImageElement: この要素は画像の heightwidth を漏洩します。ただし、画像が無効な場合、これらのプロパティは0を返し、image.decode() 関数は拒否され、画像が正しく読み込まれなかったことを示します。HTMLImageElementについての詳細

CSSプロパティ

ウェブアプリケーションは、ユーザーの状態に応じてウェブサイトのスタイリングを変更することがあります。クロスオリジンのCSSファイルは、HTMLリンク要素を使用して攻撃者のページに埋め込むことができ、ルールは攻撃者のページに適用されます。ページがこれらのルールを動的に変更する場合、攻撃者はユーザーの状態に応じてこれらの違い検出できます。
漏洩技術として、攻撃者は window.getComputedStyle メソッドを使用して特定のHTML要素のCSSプロパティを読み取ることができます。その結果、影響を受ける要素とプロパティ名が知られている場合、攻撃者は任意のCSSプロパティを読み取ることができます。

CSS履歴

Note

これによると、これはヘッドレスChromeでは機能しません。

CSSの :visited セレクタは、ユーザーが以前に訪問した場合にURLを異なるスタイルで装飾するために使用されます。過去には、getComputedStyle() メソッドを使用してこれらのスタイルの違いを特定することができました。しかし、現代のブラウザは、このメソッドがリンクの状態を明らかにするのを防ぐためのセキュリティ対策を実装しています。これらの対策には、リンクが訪問されたかのように常に計算されたスタイルを返し、:visited セレクタで適用できるスタイルを制限することが含まれます。

これらの制限にもかかわらず、リンクの訪問状態を間接的に見分けることは可能です。1つの技術は、ユーザーをCSSに影響を与える領域に対話させることを含み、特に mix-blend-mode プロパティを利用します。このプロパティは、要素とその背景をブレンドすることを可能にし、ユーザーの対話に基づいて訪問状態を明らかにする可能性があります。

さらに、リンクのレンダリングタイミングを悪用することで、ユーザーの対話なしに検出を行うことができます。ブラウザは、訪問済みリンクと未訪問リンクを異なる方法でレンダリングする可能性があるため、レンダリングにおける測定可能な時間の違いを生じさせることがあります。概念実証PoCは、Chromiumのバグ報告で言及されており、この技術を使用して複数のリンクを利用してタイミングの違いを増幅し、タイミング分析を通じて訪問状態を検出可能にすることを示しています。

これらのプロパティとメソッドの詳細については、ドキュメントページを訪れてください:

ContentDocument X-Frame漏洩

Chromeでは、X-Frame-Options ヘッダーが "deny" または "same-origin" に設定されたページがオブジェクトとして埋め込まれると、エラーページが表示されます。Chromeは、iframeや他のブラウザとは異なり、このオブジェクトの contentDocument プロパティに対して空のドキュメントオブジェクト(null ではなくを一意に返します。攻撃者は、空のドキュメントを検出することでこれを悪用し、特に開発者がX-Frame-Optionsヘッダーを不一致に設定し、エラーページを見落とすことが多いため、ユーザーの状態に関する情報を明らかにする可能性があります。意識とセキュリティヘッダーの一貫した適用が、こうした漏洩を防ぐために重要です。

ダウンロード検出

Content-Disposition ヘッダー、特に Content-Disposition: attachment は、ブラウザにコンテンツをインラインで表示するのではなく、ダウンロードするよう指示します。この動作は、ユーザーがファイルダウンロードをトリガーするページにアクセスできるかどうかを検出するために悪用される可能性があります。Chromiumベースのブラウザでは、このダウンロード動作を検出するためのいくつかの技術があります

  1. ダウンロードバーの監視:
  • Chromiumベースのブラウザでファイルがダウンロードされると、ブラウザウィンドウの下部にダウンロードバーが表示されます。
  • ウィンドウの高さの変化を監視することで、ダウンロードバーの出現を推測し、ダウンロードが開始されたことを示唆できます。
  1. iframeを使用したダウンロードナビゲーション:
  • ページが Content-Disposition: attachment ヘッダーを使用してファイルダウンロードをトリガーすると、ナビゲーションイベントは発生しません。
  • コンテンツをiframeに読み込み、ナビゲーションイベントを監視することで、コンテンツの配置がファイルダウンロードを引き起こすかどうかナビゲーションなしを確認できます。
  1. iframeなしのダウンロードナビゲーション:
  • iframe技術と同様に、この方法はiframeの代わりに window.open を使用します。
  • 新しく開かれたウィンドウでナビゲーションイベントを監視することで、ファイルダウンロードがトリガーされたかどうか(ナビゲーションなし)を明らかにすることができます。

ログインユーザーのみがそのようなダウンロードをトリガーできるシナリオでは、これらの技術を使用して、ブラウザのダウンロードリクエストに対する応答に基づいてユーザーの認証状態を間接的に推測することができます。

パーティション化されたHTTPキャッシュバイパス

Warning

この技術が興味深い理由は、Chromeが現在キャッシュパーティショニングを持っており、新しく開かれたページのキャッシュキーは (https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m=xxx) ですが、ngrokページを開いてfetchを使用すると、キャッシュキーは (https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx) になります。キャッシュキーが異なるため、キャッシュは共有できません。詳細はここで確認できます: キャッシュのパーティショニングによるセキュリティとプライバシーの向上
こちらからのコメント

サイト example.com*.example.com/resource からリソースを含む場合、そのリソースは、リソースがトップレベルナビゲーションを介して直接リクエストされた場合と同じキャッシングキーを持ちます。これは、キャッシングキーがトップレベルの eTLD+1 とフレーム eTLD+1 で構成されているためです。

キャッシュにアクセスする方がリソースを読み込むよりも速いため、ページの位置を変更し、20ms例えば後にそれをキャンセルすることを試みることができます。停止後にオリジンが変更された場合、それはリソースがキャッシュされていたことを意味します。
または、潜在的にキャッシュされたページにいくつかのfetchを送信し、かかる時間を測定することができます

手動リダイレクト

AbortControllerを使用したFetch

fetchsetTimeout を使用して AbortController で、リソースがキャッシュされているかどうかを検出し、特定のリソースをブラウザキャッシュから排除します。さらに、このプロセスは新しいコンテンツをキャッシュせずに行われます。

スクリプト汚染

サービスワーカー

このシナリオでは、攻撃者は自分のドメインの1つ、具体的には "attacker.com" に サービスワーカーを登録することから始めます。次に、攻撃者はメインドキュメントからターゲットウェブサイトに新しいウィンドウを開き、サービスワーカーにタイマーを開始するよう指示します。新しいウィンドウが読み込まれ始めると、攻撃者は前のステップで取得した参照をサービスワーカーによって管理されているページにナビゲートします。

前のステップで開始されたリクエストが到着すると、サービスワーカー204 (No Content) ステータスコードで応答し、ナビゲーションプロセスを効果的に終了します。この時点で、サービスワーカーは前のステップで開始されたタイマーからの測定値をキャプチャします。この測定値は、ナビゲーションプロセスの遅延を引き起こすJavaScriptの持続時間によって影響を受けます。

Warning

実行タイミングでは、ネットワーク要因を排除してより正確な測定値を取得することが可能です。たとえば、ページを読み込む前にページで使用されるリソースを読み込むことによってです。

Fetchタイミング

クロスウィンドウタイミング

HTMLまたは再インジェクションを使用して

ここでは、クロスオリジンHTMLから情報を抽出するための技術を見つけることができます。HTMLコンテンツを注入することができる場合に興味深い技術です。これらの技術は、何らかの理由でHTMLを注入できるが、JSコードを注入できない場合に興味深いです。

ダンギングマークアップ

{{#ref}} ../dangling-markup-html-scriptless-injection/ {{#endref}}

画像の遅延読み込み

コンテンツを抽出する必要があり、秘密の前にHTMLを追加できる場合は、一般的なダンギングマークアップ技術を確認する必要があります。
ただし、何らかの理由で文字ごとに行う必要がある場合(キャッシュヒットを介して通信する場合など)、このトリックを使用できます。

HTMLの画像には、値がlazyである "loading" 属性があります。この場合、画像はページが読み込まれるときではなく、表示されたときに読み込まれます。

<img src=/something loading=lazy >

したがって、あなたができることは、秘密の前にウェブページを埋めるために多くのジャンク文字を追加することです(例えば、何千もの"W")。または、

のようなものを追加します。

例えば、私たちのインジェクションがフラグの前に現れると、画像は読み込まれますが、フラグの後に現れると、フラグ + ジャンクが読み込まれるのを防ぎます(どれだけのジャンクを置くかは調整が必要です)。これはこの書き込みで起こったことです。

もう一つのオプションは、許可されている場合はscroll-to-text-fragmentを使用することです

Scroll-to-text-fragment

ただし、あなたはボットにページにアクセスさせる必要があります。

#:~:text=SECR

ウェブページは次のようになります: https://victim.com/post.html#:~:text=SECR

ここで、post.html には攻撃者のジャンク文字と遅延読み込み画像が含まれ、その後にボットの秘密が追加されます。

このテキストが行うのは、ボットがページ内の SECR というテキストを含む任意のテキストにアクセスすることです。そのテキストは秘密であり、画像のすぐ下にあるため推測された秘密が正しい場合にのみ画像が読み込まれます。これにより、秘密を文字ごとに抽出するためのオラクルが得られます

これを利用するためのコード例: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e

画像の遅延読み込み時間ベース

もし外部画像を読み込むことができない場合、攻撃者に画像が読み込まれたことを示す別のオプションは、文字を何度も推測してそれを測定することです。画像が読み込まれると、すべてのリクエストは画像が読み込まれない場合よりも長くかかります。これは、この書き込みの解決策 において使用されたものです

{{#ref}} event-loop-blocking-+-lazy-images.md {{#endref}}

ReDoS

{{#ref}} ../regular-expression-denial-of-service-redos.md {{#endref}}

CSS ReDoS

jQuery(location.hash) が使用される場合、HTML コンテンツが存在するかどうかをタイミングで確認することが可能です。これは、セレクタ main[id='site-main'] が一致しない場合、残りのセレクタをチェックする必要がないためです。

$(
"*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']"
)

CSSインジェクション

{{#ref}} css-injection/ {{#endref}}

防御策

https://xsinator.com/paper.pdf およびウィキの各セクション https://xsleaks.dev/ で推奨される緩和策があります。これらの技術から保護する方法についての詳細は、そちらをご覧ください。

参考文献

{{#include ../../banners/hacktricks-training.md}}