
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · tomcat-rewrite-ns-loop
分類: DoS 到達範囲: リモート
Apache Tomcat 11.0.27 (52f3b364) - tomcat.apache.org
RewriteValve.parseRuleFlag は前方一致を行う。NC/NE の後、startsWith("N") に一致する残りのフラグは次を有効化する。httpd からコピーされた [NS] (nosubreq) と [NV] (novary) は [N] になる。置換 - は substitution を null のままにし、RewriteRule.evaluate は元の URL を返す。isNext() と非 null の newtest により、ラウンド上限なしで i = -1 が設定されるため、ルールに一致する単一の未認証 GET が、クライアントが切断するかプロセスが再起動するまで HTTP コネクタスレッドを固定する。明示的な [N] と [S=-1] も同じ固定を引き起こす。[L,NS] は isLast() が先に break するため安全である。
CVE-2026-65927 (Important, 11.0.25) は [N] が 2 番目のルールで再起動する問題を修正した。この固定には依然としてラウンド上限がない。11.0.27 以降の同日の main では、セキュリティアドバイザリなしで MAX_REWRITE_ROUNDS=1000 と厳密なフラグマッチング (2da9fddb, 8992dbdd) が追加された。
| ID | CVE 未割当 |
| 分類 | DoS |
| 到達範囲 | リモート (未認証 HTTP) |
| CWE | CWE-835 |
| CVSS | High: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| 製品 | Apache Tomcat |
| 影響 | 11.0.27 (52f3b364e5882a5dbcfc42cb8313a7c2ae532c64) RewriteValve |
| 認証 | 未認証 HTTP |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
タグ 11.0.27 を固定し、RewriteValve.invoke を読んだ。このバルブは標準の conf/server.xml には含まれていない。デフォルトの Host パスは conf/Catalina/localhost/rewrite.config である。ラボは 127.0.0.1:18910 上のループバック HTTP である。公式 11.0.27 tarball を使用。RCE ではない。
| 手法 | シンク | 権限 |
|---|---|---|
Host rewrite.config の RewriteRule ^/loop$ - [NS] に一致する未認証 GET /loop | トークン NS に対する startsWith("N") により RewriteValve.invoke の i = -1 | 可用性 (ラボ実証済み): クライアントが切断するかプロセスが再起動するまで 1 つの HTTP コネクタスレッドを固定。ラボ: /loop は 4.002 秒でタイムアウト。 |
明示的な [N] を伴う未認証 GET /next | 同じ isNext() 再起動 | 可用性 (ラボ実証済み): 同じ固定。ラボ: /next は 4.003 秒でタイムアウト。 |
[S=-1] を伴う未認証 GET /skip | i += -1 の後に for のインクリメント | 可用性 (ラボ実証済み): 同じ固定。ラボ: /skip は 4.002 秒でタイムアウト。 |
| ワーカーごとに 1 つの一致リクエスト | 同じシンク、maxThreads 個の同時一致 URL | 可用性 (推測): コネクタプールを埋め尽くす (ラボでは 32 を使用、標準デフォルトは 200)。新規リクエストはその後キューに入るか拒否される。1 つの /loop が実行中でも兄弟 /ok は応答し続けた。 |
/ok での 13ms の 404 に対するハング | next/skip と [L] のタイミング | 偵察 (ラボ実証済み): next/skip ルールが一致したことを判別できる。ラボ: 4.002 秒のハング対 0.013 秒の 404。 |
ラボ実証済みと推測: /loop [NS] ハング、/next [N] ハング、/skip [S=-1] ハング、/ok [L] が 13ms で 404、/safe [L,NS] が 5ms で 404、および /loop 実行中に兄弟 /ok が 404 となることはラボ実証済みである。プール枯渇は 1 スレッド固定と maxThreads から推測される。
必要条件: Host または Context 上の RewriteValve と、一致する rewrite.config ルール。バルブはオプトインであり、コメントアウトされた AJP と同じ分類である。コピーされた httpd の [NS] は一致ルールであり、意図的な無限 [N] ループではない。
| 面 | ラボ |
|---|---|
[L,NS] (httpd last+nosubreq) | /safe が 5ms で 404 (L-ns-safe=yes) |
| 1 つのスレッドが固定されている間の他の実行中リクエスト | /loop 中の /ok が 13ms で 404 (sibling-alive=yes) |
RewriteValve なしの標準 server.xml | バルブが存在せず、残存物は発火しない |
| CVE-2026-65927 の RCE / WEB-INF 読み取り / 制約バイパス | [N] はルール 0 で再起動するようになった。この残存物は可用性のみ |
| Manager / JMX / AJP / DefaultServlet PUT | 変更なし。PUT は依然として readonly |
Tomcat ユーザーとしてのコード実行はない。conf/ や WEB-INF の読み取りはない。セッション窃取はない。Manager デプロイはない。JVM は稼働し続け、プールが埋まるまで他のワーカーは応答し続ける。
cd lab
./run.sh
ループバック 127.0.0.1:18910 はコンテナの 8080 にマッピングされる。Compose プロジェクト tomcat-rewrite-ns-loop。イメージタグ tomcat-rewrite-ns-loop:11.0.27。公式 apache-tomcat-11.0.27.tar.gz SHA512 a617896307cada4884b24f80c4e977ddad8b3e0f88ce0e2a6eea29d5f332498e276ae5976c227a9c8daecf05c7c90def684a3766dd5a81f47a56d8b1adf43dc3。ウィットネス TOMCAT-REWRITE-NS-LOOP-WITNESS。最終行:
SUCCESS TOMCAT-REWRITE-NS-LOOP control-ok=yes ns-hang=yes L-ns-safe=yes n-hang=yes skip-hang=yes sibling-alive=yes TOMCAT-REWRITE-NS-LOOP-WITNESS
ラボの rewrite.config:
RewriteRule ^/loop$ - [NS]
RewriteRule ^/next$ - [N]
RewriteRule ^/skip$ - [S=-1]
RewriteRule ^/ok$ - [L]
RewriteRule ^/safe$ - [L,NS]
リライトのラウンド数を制限する (このタグ以降の main では MAX_REWRITE_ROUNDS=1000、コミット 2da9fddb)。厳密一致フラグにより [NS] はパースに失敗する (コミット 8992dbdd)。skip < 0 を拒否する。これらがリリースに取り込まれるまでは、一致ルールで [NS]/[NV]/[N]/[S=-1] を避けるか、RewriteValve を削除する。
52f3b364e5882a5dbcfc42cb8313a7c2ae532c64)RewriteValve.java の isNext() 再起動と startsWith("N")RewriteRule.java の置換 - は元の URL を返す