HTTP/2ダウングレードにおけるリクエストスムージング
Reading time: 9 minutes
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HTTP/2は一般的に古典的なリクエストスムージングに対して免疫があると考えられていますが、フロントエンドプロキシがリクエストをHTTP/1.xに「ダウングレード」してバックエンドに転送する際、その保護は消えます。異なる2つのパーサー(HTTP/2フロントエンドとHTTP/1バックエンド)が、1つのリクエストが終了し次のリクエストが始まる場所について合意しようとすると、古いデシンクトリックがすべて戻ってきます - さらにいくつかの新しいものも。
ダウングレードが発生する理由
- ブラウザはすでにHTTP/2を話しますが、古いオリジンインフラストラクチャはまだHTTP/1.1しか理解していません。
- リバースプロキシ(CDN、WAF、ロードバランサー)は、したがって、エッジでTLS + HTTP/2を終了し、すべてのリクエストをHTTP/1.1としてオリジンに書き換えます。
- 翻訳ステップは、オリジンがボディの長さを決定できるようにするために、両方の
Content-Length
および/またはTransfer-Encoding: chunked
ヘッダーを作成する必要があります。
フロントエンドがHTTP/2フレームの長さを信頼しているが、バックエンドがCLまたはTEを信頼している場合、攻撃者はそれらが不一致になるように強制できます。
2つの主要なプリミティブクラス
バリアント | フロントエンドの長さ | バックエンドの長さ | 一般的なペイロード |
---|---|---|---|
H2.TE | HTTP/2フレーム | Transfer-Encoding: chunked | 最終的な 0\r\n\r\n が送信されない追加のチャンクメッセージボディを埋め込むことで、バックエンドは攻撃者が提供した「次の」リクエストを待ちます。 |
H2.CL | HTTP/2フレーム | Content-Length | 実際のボディよりも小さいCLを送信することで、バックエンドは境界を越えて次のリクエストを読み取ります。 |
これらは、古典的なTE.CL / CL.TEと精神的に同じであり、単にHTTP/2がパーサーの1つを置き換えています。
ダウングレードチェーンの特定
- TLSハンドシェイクでALPNを使用する(
openssl s_client -alpn h2 -connect host:443
)またはcurl:
curl -v --http2 https://target
* Using HTTP2
が表示される場合、エッジはH2を話します。
2. 意図的に不正なCL/TEリクエストをHTTP/2経由で送信します(Burp RepeaterにはHTTP/2を強制するためのドロップダウンがあります)。応答が400 Bad chunk
のようなHTTP/1.1エラーである場合、エッジが下流のHTTP/1パーサー用にトラフィックを変換した証拠があります。
攻撃ワークフロー(H2.TEの例)
:method: POST
:path: /login
:scheme: https
:authority: example.com
content-length: 13 # ignored by the edge
transfer-encoding: chunked
5;ext=1\r\nHELLO\r\n
0\r\n\r\nGET /admin HTTP/1.1\r\nHost: internal\r\nX: X
- フロントエンドは正確に13バイト(
HELLO\r\n0\r\n\r\nGE
)を読み取り、リクエストが終了したと考え、その分をオリジンに転送します。 - バックエンドはTEヘッダーを信頼し、2番目の
0\r\n\r\n
を見るまで読み続け、攻撃者の2番目のリクエストのプレフィックス(GET /admin …
)を消費します。 - 残り(
GET /admin …
)は被害者の後ろにキューイングされた新しいリクエストとして扱われます。
密輸されたリクエストを次のように置き換えます:
POST /api/logout
セッション固定を強制するためGET /users/1234
被害者特有のリソースを盗むため
h2cスムグリング(クリアテキストアップグレード)
2023年の研究では、フロントエンドがクリアテキストHTTP/2をサポートするバックエンドにHTTP/1.1 Upgrade: h2c
ヘッダーを渡すと、攻撃者が生のHTTP/2フレームをHTTP/1.1のみを検証したエッジを通してトンネルできることが示されました。これにより、ヘッダーの正規化、WAFルール、さらにはTLS終端を回避します。
主な要件:
- エッジは両方の
Connection: Upgrade
とUpgrade: h2c
を変更せずに転送します。 - オリジンはHTTP/2に増分し、リクエストキューイングを可能にする接続再利用のセマンティクスを保持します。
緩和策は簡単です – WebSocketを除いて、エッジでUpgrade
ヘッダーを削除またはハードコーディングします。
注目すべき実世界のCVE(2022-2025)
- CVE-2023-25690 – Apache HTTP Serverのmod_proxyリライトルールは、リクエスト分割とスムグリングのために連鎖させることができました。(2.4.56で修正)
- CVE-2023-25950 – HAProxy 2.7/2.6は、HTXパーサーがパイプライン化されたリクエストを誤って処理した場合にリクエスト/レスポンスのスムグリングが発生しました。
- CVE-2022-41721 – Goの
MaxBytesHandler
は、残りのボディバイトをHTTP/2フレームとして解析し、クロスプロトコルスムグリングを可能にしました。
ツール
- Burp Request Smuggler – v1.26以降、H2.TE/H2.CLおよび隠れたALPNサポートを自動的にテストします。拡張オプションで「HTTP/2プロービング」を有効にします。
- h2cSmuggler – Bishop Foxによるクリアテキストアップグレード攻撃を自動化するPython PoC:
python3 h2csmuggler.py -u https://target -x 'GET /admin HTTP/1.1\r\nHost: target\r\n\r\n'
- curl/
hyper
– 手動ペイロードの作成:curl --http2-prior-knowledge -X POST --data-binary @payload.raw https://target
。
防御策
- エンドツーエンドHTTP/2 – ダウングレード翻訳を完全に排除します。
- 長さの真実の単一ソース – ダウングレード時には、常に有効な
Content-Length
を生成し、ユーザー提供のContent-Length
/Transfer-Encoding
ヘッダーを削除**します。 - ルート前の正規化 – ルーティング/リライトロジックの前にヘッダーのサニタイズを適用します。
- 接続の隔離 – ユーザー間でバックエンドTCP接続を再利用しないでください。「1接続あたり1リクエスト」はキューに基づく攻撃を無効にします。
- WebSocketでない限り
Upgrade
を削除 – h2cトンネリングを防ぎます。
参考文献
- PortSwigger Research – “HTTP/2: The Sequel is Always Worse” https://portswigger.net/research/http2
- Bishop Fox – “h2c Smuggling: request smuggling via HTTP/2 clear-text” https://bishopfox.com/blog/h2c-smuggling-request
tip
AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。