Cache Poisoning and Cache Deception
Last updated
Last updated
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Trickestを使用して、世界で最も高度なコミュニティツールによって駆動されるワークフローを簡単に構築し、自動化します。 今すぐアクセスを取得:
ウェブキャッシュポイズニングとウェブキャッシュデセプションの違いは何ですか?
ウェブキャッシュポイズニングでは、攻撃者がアプリケーションに悪意のあるコンテンツをキャッシュに保存させ、そのコンテンツが他のアプリケーションユーザーに提供されます。
ウェブキャッシュデセプションでは、攻撃者がアプリケーションに他のユーザーに属する機密コンテンツをキャッシュに保存させ、攻撃者がそのコンテンツをキャッシュから取得します。
キャッシュポイズニングは、クライアント側のキャッシュを操作して、クライアントが予期しない、部分的、または攻撃者の制御下にあるリソースを読み込むように強制することを目的としています。影響の程度は、影響を受けるページの人気に依存し、汚染された応答は、キャッシュ汚染の期間中にそのページを訪れるユーザーにのみ提供されます。
キャッシュポイズニング攻撃の実行には、いくつかのステップが含まれます:
未キー入力の特定:これらは、リクエストがキャッシュされるために必須ではないパラメータですが、サーバーが返す応答を変更する可能性があります。これらの入力を特定することは重要であり、キャッシュを操作するために悪用される可能性があります。
未キー入力の悪用:未キー入力を特定した後、次のステップは、攻撃者に利益をもたらす方法でサーバーの応答を変更するためにこれらのパラメータを誤用する方法を見つけることです。
汚染された応答がキャッシュされることを確認:最終ステップは、操作された応答がキャッシュに保存されることを確認することです。これにより、キャッシュが汚染されている間に影響を受けるページにアクセスするユーザーは、汚染された応答を受け取ります。
通常、応答がキャッシュに保存された場合、それを示すヘッダーが存在します。どのヘッダーに注意を払うべきかは、この投稿で確認できます:HTTPキャッシュヘッダー。
応答がキャッシュに保存されていると考えている場合、不正なヘッダーでリクエストを送信してみることができます。これにはステータスコード400で応答されるべきです。その後、リクエストに通常アクセスして、応答が400ステータスコードであれば、それが脆弱であることがわかります(DoSを実行することも可能です)。
さらにオプションを見つけることができます:
Cache Poisoning to DoSただし、時々これらのステータスコードはキャッシュされないため、このテストは信頼できない可能性があります。
Param Minerを使用して、ページの応答を変更する可能性のあるパラメータやヘッダーをブルートフォースすることができます。たとえば、ページがX-Forwarded-For
ヘッダーを使用してクライアントにスクリプトをそこから読み込むように指示している場合:
パラメータ/ヘッダーが特定されたら、それがどのようにサニタイズされているか、またどこで応答に反映されているかを確認します。これを悪用することはできますか(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されることになります:
Note that this will poison a request to /en?region=uk
not to /en
クッキーはページのレスポンスに反映されることもあります。これを悪用してXSSを引き起こすことができれば、悪意のあるキャッシュレスポンスを読み込む複数のクライアントでXSSを利用できる可能性があります。
注意してください。脆弱なクッキーがユーザーによって非常に使用されている場合、定期的なリクエストがキャッシュをクリーニングします。
確認してください:
Cache Poisoning via URL discrepanciesこのレポートは https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123
のようなURLでOpenAI APIキーを盗むことが可能だった理由を説明しています。/share/*
に一致するものはすべてキャッシュされ、リクエストがウェブサーバーに到達したときにCloudflareがURLを正規化しなかったためです。
これは以下でもより詳しく説明されています:
Cache Poisoning via URL discrepancies時には、キャッシュを悪用するために複数のキーなし入力を悪用する必要があります。例えば、X-Forwarded-Host
をあなたが管理するドメインに設定し、X-Forwarded-Scheme
をhttp
に設定すると、オープンリダイレクトを見つけることができるかもしれません。もしサーバーがすべてのHTTPリクエストをHTTPSに転送し、リダイレクトのドメイン名としてX-Forwarded-Scheme
ヘッダーを使用している場合、リダイレクトによってページが指す場所を制御できます。
Vary
ヘッダーを利用した攻撃もし X-Host
ヘッダーが JSリソースを読み込むためのドメイン名 として使用されているが、レスポンスの Vary
ヘッダーが User-Agent
を示している場合、被害者のUser-Agentを抽出し、そのUser-Agentを使用してキャッシュを汚染する方法を見つける必要があります。
URLとボディの両方にリクエストを含むGETリクエストを送信します。ウェブサーバーがボディのものを使用するが、キャッシュサーバーがURLのものをキャッシュする場合、そのURLにアクセスする誰もが実際にはボディのパラメータを使用します。James KettleがGithubウェブサイトで見つけた脆弱性のように:
There it a portswigger lab about this: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
例えば、パラメータをrubyサーバーで**;
文字を使って&
**の代わりに分離することが可能です。これを利用して、キーのないパラメータの値をキーのあるものの中に入れ込み、悪用することができます。
Portswigger lab: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking
HTTPリクエストスムージングを悪用したキャッシュポイズニング攻撃の実行方法についてここで学びます。
Web Cache Vulnerability Scannerを使用して、ウェブキャッシュポイズニングを自動的にテストできます。多くの異なる技術をサポートしており、高度にカスタマイズ可能です。
使用例: wcvs -u example.com
ATSはURL内のフラグメントを削除せずに転送し、ホスト、パス、クエリのみを使用してキャッシュキーを生成しました(フラグメントを無視)。そのため、リクエスト/#/../?r=javascript:alert(1)
はバックエンドに/#/../?r=javascript:alert(1)
として送信され、キャッシュキーにはペイロードが含まれておらず、ホスト、パス、クエリのみでした。
content-typeヘッダーに不正な値を送信すると、405キャッシュレスポンスがトリガーされました。キャッシュキーにはクッキーが含まれていたため、認証されていないユーザーのみを攻撃することが可能でした。
GitLabは静的コンテンツを保存するためにGCPバケットを使用しています。GCPバケットは**ヘッダーx-http-method-override
**をサポートしています。したがって、ヘッダーx-http-method-override: HEAD
を送信し、キャッシュを毒して空のレスポンスボディを返すことが可能でした。また、PURGE
メソッドもサポートされていました。
Ruby on Railsアプリケーションでは、Rackミドルウェアがよく利用されます。Rackコードの目的は、**x-forwarded-scheme
**ヘッダーの値を取得し、それをリクエストのスキームとして設定することです。ヘッダーx-forwarded-scheme: http
が送信されると、同じ場所への301リダイレクトが発生し、そのリソースに対してサービス拒否(DoS)を引き起こす可能性があります。さらに、アプリケーションはX-forwarded-host
ヘッダーを認識し、指定されたホストにユーザーをリダイレクトする可能性があります。この動作により、攻撃者のサーバーからJavaScriptファイルが読み込まれ、セキュリティリスクが生じる可能性があります。
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は、ヘッダー名における許可される文字を指定しています。指定されたtchar範囲外の文字を含むヘッダーは、理想的には400 Bad Requestレスポンスをトリガーするべきです。実際には、サーバーは常にこの標準に従うわけではありません。特に注目すべき例は、Akamaiが無効な文字を含むヘッダーを転送し、cache-control
ヘッダーが存在しない限り、400エラーをキャッシュすることです。不正な文字(例:\
)を含むヘッダーを送信すると、キャッシュ可能な400 Bad Requestエラーが発生するという悪用可能なパターンが特定されました。
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
キャッシュデセプションの目的は、クライアントにキャッシュによって保存されるリソースをその機密情報で読み込ませることです。
まず、拡張子(例:.css
、.js
、.png
など)が通常キャッシュに保存されるように設定されていることに注意してください。したがって、www.example.com/profile.php/nonexistent.js
にアクセスすると、キャッシュはおそらくレスポンスを保存します。なぜなら、.js
拡張子を見ているからです。しかし、アプリケーションが_swww.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。 この例では、_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リクエストスムージングを悪用したキャッシュデセプション攻撃の実行方法についてここで学びます。
toxicache:URLのリスト内でウェブキャッシュポイズニングの脆弱性を見つけ、複数の注入技術をテストするためのGolangスキャナー。
Trickestを使用して、世界で最も高度なコミュニティツールによって駆動されるワークフローを簡単に構築し、自動化します。 今すぐアクセスを取得:
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE) GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)