アクセスログに /cgi-bin/.%2e/.%2e/.%2e/.../bin/sh が並んでいる、あるいはFortiGateのIPSログに Apache.HTTP.Server.cgi-bin.Path.Traversal が上がった。この記事にたどり着く入口はたいていそこです。正体はApache HTTP Serverのパストラバーサル脆弱性 CVE-2021-41773 と、その修正が不十分だったために公表された CVE-2021-42013 です。Apache公式勧告・NVD・CISA KEVの一次情報と、Apache Software Foundationのコミット差分をもとに、ログ文字列の読み分けと自サーバの影響判定を順に示します。
まとめ:CVE-2021-41773・CVE-2021-42013の要点
まず確認すべきは自分のApacheのバージョンで、そこで大半の判断が終わります。
- 影響を受けるのは 2.4.49 と 2.4.50 だけ。2.4.48以前と2.4.51以降は対象外で、現行の2.4.68も当然対象外。
- Apache公式勧告はどちらも severity を Critical と表記。一方NVDの基本値は両方9.8で、41773にだけCISA-ADPによる7.5の第二評価が併存する。
- 条件は2段構え。ドキュメントルート外がRequire all deniedで守られていなければファイルを読まれ、そこにCGIが有効だと任意コマンド実行(RCE)まで届く。
- ログの文字列で狙われているCVEが分かる。
.%2eだけなら41773狙い、%%32%65を含むなら2.4.50も対象に入れた42013狙い。 - CISA KEVには2021年11月3日に両方が収録済みで、ランサムウェアキャンペーンでの使用は Known と記録されている。
| 項目 | CVE-2021-41773 | CVE-2021-42013 |
|---|---|---|
| 影響バージョン | 2.4.49 のみ | 2.4.49 と 2.4.50 |
| 修正版 | 2.4.50 | 2.4.51 |
| Apache公式のseverity | Critical | Critical |
| NVD基本値(Primary) | 9.8 CRITICAL | 9.8 CRITICAL |
| CISA-ADP評価(Secondary) | 7.5 HIGH | 9.8 CRITICAL |
| CWE | CWE-22 | CWE-22 |
| NVD公開日 | 2021-10-05 | 2021-10-07 |
| 修正版リリース日 | 2021-10-04 | 2021-10-07 |
| CISA KEV登録日 | 2021-11-03 | 2021-11-03 |
| KEV是正期限 | 2021-11-17 | 2021-11-17 |
| ランサムでの使用 | Known | Known |
スコアとKEVの値はNVDとCISAの公開情報に基づくもので、NVDのレコードは更新されるため、スコアや更新日は各CVEの公開情報で確認してください。リリース日はApache公式勧告の Update 2.4.50 released: 2021-10-04 および Update 2.4.51 released: 2021-10-07 の記載によります。
ログとIPSアラートに出た攻撃文字列の読み分け
このCVEは「自分から調べに来る」より「ログに出た文字列を検索して行き着く」ほうが多い脆弱性です。文字列の形が3種類あり、どれが来ているかで狙われているCVEと、自分が危ないかどうかの前提が変わります。
ディレクトリトラバーサル(パストラバーサル)が狙うもの
URLのパスに .. に相当する並びを混ぜ込み、公開を意図していないディレクトリのファイルへ到達させる攻撃です。分類はCWE-22で、NVDもApache Software Foundation自身も両CVEにこの識別子を割り当てています。
Apacheのこのケースで重要なのは、入口が任意のURLではないことです。Apache公式のセキュリティ勧告は対象を the directories configured by Alias-like directives、つまりAliasやScriptAliasで別ディレクトリに割り当てたパスの配下と書いています。このため、既定のScriptAliasである /cgi-bin/ を入口にした攻撃例が知られています。自社で別名のAliasやScriptAliasを設定している場合は、そちらも確認対象に含めてください。攻撃類型そのものの仕組みと実装側の防ぎ方はディレクトリトラバーサルとは?攻撃の仕組みと正規化後検証による実装対策を解説で扱っています。
.%2e型の特徴とCVE-2021-41773の対象版
CVE-2021-41773を狙うリクエストの例です。
GET /cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/etc/passwd HTTP/1.1
なぜこれが2.4.49で通るのかは、2.4.49で新規に入ったパス正規化の実装に原因があります。この版の ap_normalize_path() はパーセントエンコードされたunreserved文字を先にデコードする一方、.. を畳む判定は素のドット2文字しか見ていませんでした。.%2e は「1文字目だけがドットで、2文字目はまだデコード前」という状態になり、上の階層へ戻す処理の対象から外れて素通りします。
ドットの並びが10回続くのは、cgi-binの位置から確実にルートまで戻るための余裕です。階層数そのものに意味はないので、7回でも12回でも同じ攻撃だと読んで構いません。
%%32%65型の特徴とCVE-2021-42013の対象版
次の形が来ていたら、送り手は2.4.50も標的に含めています。
GET /cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh HTTP/1.1
%%32%65 は、%32 が文字 2、%65 が文字 e に相当し、デコードすると %2e に、さらに解釈されるとドットになります。2.4.50の対策は %2e という文字の並びを見つけて上位階層への移動として畳む処理だったため、正規化を通る時点ではまだ %2e の形になっていないこの書き方が対象から外れます。2.4.50もCVE-2021-42013の影響対象です。ログにこの文字列がなくても安全とは判断せず、修正版への更新を進めてください。
素の../型とエンコード型の処理の違い
次の形もよくログに残りますが、性質が違います。
GET /cgi-bin/../../../../../../../../../../bin/sh HTTP/1.1
エンコードを使わない素のドット2文字の形は、2.4.49で問題になった正規化処理でも、それ以前の版でも、上の階層へ戻す処理として正しく畳まれます。つまりこの形だけが来ている場合、CVE-2021-41773やCVE-2021-42013の標的にされたとは言えません。パス種を総当たりするスキャナが網羅的に投げているものと読むのが妥当です。もっとも、Aliasの設定ミスや別ミドルウェアの脆弱性が背後にある可能性まで否定できるわけではないので、404以外が返っていれば設定側を点検してください。
Apache.HTTP.Server.cgi-bin.Path.Traversal などシグネチャ名で通知された場合
ログの文字列ではなく、IPS製品のアラート名で検索して来る人も多い領域です。FortiGateで表示される Apache.HTTP.Server.cgi-bin.Path.Traversal は、FortiGuardのIPSエンサイクロペディアに登録されたシグネチャ名で、名前のとおりApache HTTP Serverの /cgi-bin/ を入口としたパストラバーサルの検知を指します。ここで扱っている2件のCVEがまさにその形です。
ここで取り違えやすいのが、シグネチャ名はリクエストを検知したという記録であって、攻撃が成功したという記録ではない点です。遮断アクションは有力な判断材料ですが、それだけで完結させず、IPSログの遮断結果に加えてリクエスト当時のApacheのバージョン・設定、アクセスログ、error_logを照合し、どの通信がどの段階で遮断されたかを確認してください。自前でシグネチャを書いて検知側を組む場合の考え方はSuricataとは?導入からルール作成・IPSモード運用まで【8.0対応】にまとめています。
アクセスログによる攻撃兆候と追加調査の判断
以下は掲載した3形式と%2Eの表記を抽出する簡易例です。別のエンコード表現やローテーション済みログは網羅しないため、該当行がなくても攻撃がなかったとは判断できません。
grep -Ei '%2e|%%32%65|[.][.]/' /var/log/httpd/access_log
grep -Ei '%2e|%%32%65|[.][.]/' /var/log/apache2/access.log
403や404は拒否・未検出を示しますが、それだけで侵害を否定できません。応答した機器やCGIの処理を確認し、500などの応答も調査対象に含めます。200が返っていればファイルを読まれた可能性があり、さらにメソッドがPOSTで宛先が /bin/sh のようなシェルのパスなら、コマンド実行を試みられたと考えて侵害調査に移ります。CGI経由の実行が疑われる場合は、同時刻帯のerror_logとサーバ上の新規ファイル、cron、外向き通信もあわせて確認してください。何をどの順で見るかは不正アクセスのログ確認・解析方法|見るべきログと攻撃痕跡の調べ方を実践解説に、IPAの無償ツールで機械的に兆候を拾う方法はiLogScannerとは?IPA無料ツールで攻撃兆候を検出する使い方にあります。
自サーバが影響を受けるかの判定:3つの条件
Apache公式勧告は成立条件を明示しています。ドキュメントルート外のファイルが通常の既定設定である Require all denied で保護されていない場合にリクエストが成功し、さらにそれらのパスでCGIスクリプトが有効な場合にリモートコード実行が起こりうる、という書き方です。バージョンを含めて3条件として順に見ます。
条件1:稼働バージョンの2.4.49・2.4.50への該当
最初に確認するのはここで、ほとんどの環境はこの時点で判定が終わります。
httpd -v
apache2 -v
2.4.49ならCVE-2021-41773とCVE-2021-42013の両方、2.4.50ならCVE-2021-42013のみが対象です。2.4.48以前と2.4.51以降は、この2件については対象外になります。Apache公式のセキュリティ情報に記載されたリリース日は2.4.49が2021年9月16日、2.4.50が10月4日、2.4.51が10月7日で、対象版が現行リリースだったのは3週間でした。ただし対象版を使い続けている環境や、古い構築手順から対象版を再導入した環境では、修正版の公開後も影響が残ります。
条件2:Aliasの割り当て先の外にあるファイルの保護不足
Apacheの既定設定には、ファイルシステム全体をまず拒否してから必要な範囲だけ許可する次のブロックが入っています。
<Directory />
AllowOverride none
Require all denied
</Directory>
この拒否が到達先ファイルに対して有効なら、アクセスは拒否されます。ただし、別のDirectoryやLocationの認可設定で上書きされていないことも確認が必要です。逆に、このブロックを削った構成や、Aliasの割り当て先の外にある到達先ファイルまで許可している構成では、読み出しが成立し得ます。条件1に該当する版を使っていて、かつここを緩めている場合が実害の出る組み合わせです。
条件3:CGIが有効である(RCEに届く条件)
ファイル読み出しにとどまるか任意コマンド実行まで至るかを分けるのがこの条件です。
httpd -M | grep -i cgi
grep -R 'ScriptAlias' /etc/httpd/conf /etc/httpd/conf.d
cgi_module または cgid_module が読み込まれ、該当するAlias系パスでCGI実行が有効なら、条件1・2と合わせてRCEが成立し得ます。ScriptAliasに加え、SetHandlerやAddHandler、Optionsの設定も確認してください。CGIを使っていなければ、同じ攻撃でも被害はファイルの読み出しまでです。
| バージョン | CGI無効 | CGI有効 |
|---|---|---|
| 2.4.48以前 | 影響なし | 影響なし |
| 2.4.49 | ファイル読み出し | 任意コマンド実行 |
| 2.4.50 | ファイル読み出し | 任意コマンド実行 |
| 2.4.51以降 | 影響なし | 影響なし |
2.4.49と2.4.50の行は、条件2のRequire all deniedが外れていることが前提です。ファイル読み出しは条件1・2、RCEはさらに条件3が成立する場合に起こり得ます。
2つのCVEの違いと、2.4.50の修正が3日で破られた理由
2.4.50のリリースから3日後に、不十分な修正へ対応した2.4.51がリリースされました。なぜ最初の修正が足りなかったのかは、2つのコミット差分を並べると具体的に説明できます。
CVSS 9.8と7.5の評価主体・影響指標の違い
CVE-2021-41773をNVDで見ると、評価が2つ並んでいます。NVD自身によるPrimaryが9.8 CRITICAL、ベクタは CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H。もう一方はCISA-ADPによるSecondaryで7.5 HIGH、こちらは C:H/I:N/A:N と機密性への影響だけを計上しています。
両評価の差は完全性と可用性への影響を計上するかどうかにあります。9.8はCGIが有効でRCEに至る構成、7.5はCGIが無効でファイル読み出しにとどまる構成の評価とみると整合しますが、これはベクタからの解釈であって、評価主体が採点理由をそう説明しているわけではありません。CVE-2021-42013のほうはPrimaryもSecondaryも9.8で一致しており、割れているのは41773だけです。
実務上の結論は、優先度はスコアの数字ではなく前節の3条件を自分の環境に当てて決めるものだということです。7.5だけを見てCGI有効の環境を後回しにするのは危険ですし、CGIを使っていない静的配信のサーバでも、到達先に認証情報や鍵が置かれていれば読み出しだけで重大な被害になります。公開範囲と到達可能な情報を確認して対応期限を決めてください。スコアの読み方そのものはCVSSv3とは?スコアの計算方法と3つの評価基準・v3.1との違いを解説で整理しています。
2.4.50の修正:2つ目のドットのエンコード表記への対応
CVE-2021-41773に対する修正はリビジョンr1893775として2.4.xブランチに入りました。差分の中身は、.. を畳む判定に %2e と %2E のリテラル一致を足すというものです。追加されたコメントがそのまま設計意図を語っています。
/* Remove /xx/../ segments (or /xx/.%2e/ when
* AP_NORMALIZE_DECODE_UNRESERVED is set since we
* decoded only the first dot above).
*/
1つ目のドットだけを先にデコードしてしまう既存の挙動を前提に、そのまま残る2つ目のドットの表記 %2e を文字列として追加照合するという直し方です。観測された攻撃の形には確実に効きますが、防いでいるのは「その書き方」だけでした。
2.4.51の修正:再デコードの抑制と不正エンコードの拒否
二重エンコードで破られたあと、2.4.51ではリビジョンr1893977で方針が切り替わります。新設されたのが ap_unescape_url_ex() と AP_UNESCAPE_URL_KEEP_UNRESERVED フラグで、unreserved文字をデコードせずエンコードされた形のまま保持できるようにしました。リクエスト処理側の server/request.c に入ったコメントが、パターン照合ではなくデコードの回数を管理する設計に変わったことを示しています。
/* Unreserved chars were already decoded by ap_normalize_path() */
unsigned int unescape_flags = AP_UNESCAPE_URL_KEEP_UNRESERVED;
正規化の段階でいったんデコードしたのだから、後段のURLデコードでは二度目のデコードをしない、という制御です。
同じ差分で ap_normalize_path() にも変更が入りました。% の直後が16進2桁でない場合を Invalid encoding として扱い、正規化の戻り値を失敗にします。%%32%65 は % の次がまた % なのでこの判定に引っかかり、ドットに解釈される前の入口で落ちます。
この事例の教訓は、正規化後に追加のデコードが行われると、正規化時の検査をすり抜ける表記が生じ得るということです。2.4.50から2.4.51まで3日しかかからなかったのは、攻撃者が新しい発想に至ったからではなく、修正が表記の照合にとどまっていたからでした。自社実装で同種の対策を書くときも、危険な表記を列挙して弾く方向ではなく、デコードを終えて正規化した結果に対して境界を検証する方向を取ってください。入力検証をどの層でどう書くかの原則はセキュアコーディングとは?10原則と主要脆弱性のコード対策を実装目線で解説にまとめています。
対策:アップデートと、すぐ止められない場合の緩和
2.4.51以降へのアップデートが唯一の恒久対策
両方のCVEに一度で対応するには2.4.51以降へ上げます。2.4.50への更新はCVE-2021-41773の対策にしかならず、CVE-2021-42013の対象のままである点に注意してください。実運用では過去版で止めずに現行版へ合わせるのが妥当で、Apache HTTP Serverの現行リリースは2026年6月8日公開の2.4.68です。2.4.5x以降にも別系統の脆弱性が継続的に出ているため、版を上げたあとに何を見続けるべきかはApache HTTP Server 2.4の脆弱性まとめ:CVE-2026-33523ほか2.4.67/2.4.68の影響範囲と対応手順で追えます。
ディストリビューション版のバックポートと修正状況の確認
RHEL系やUbuntuのApacheパッケージは、上流の新しい版に載せ替えるのではなく、古い版番号のまま修正だけを取り込むバックポート方式を取ります。httpd -v が2.4.6や2.4.41と表示されても、それだけでは脆弱とも安全とも判断できません。影響の有無はディストリビューションの公式CVE情報とパッケージ版を照合します。以下の変更履歴検索は補助確認であり、結果が空でも未修正とは限りません。CVE-2021-42013も別途確認してください。
rpm -q --changelog httpd | grep -i 41773
apt changelog apache2 | grep -i 41773
そもそも今回の2件は2.4.49と2.4.50という狭い版域の問題なので、長期サポート系ディストリの標準パッケージを使っている環境は最初から対象外であることがほとんどです。影響を受けやすいのは、その時期にソースからビルドした、あるいはコンテナイメージのタグで版を固定した環境です。
すぐ更新できない場合の緩和策
メンテナンス枠が取れない場合の時間稼ぎとして、次の3つが効きます。
- 既定の
<Directory />にRequire all deniedを戻し、ドキュメントルート外への到達を拒否する。 - CGIを使っていなければ
cgi_moduleとcgid_moduleの読み込みとScriptAliasを外し、RCEの条件を消す。 - 前段のWAFやIPSで両CVEに対応したベンダー提供ルールを適用する。大文字・小文字や別のエンコード表現による回避があるため、この2文字列の一致だけを防御条件にしない。
ただしこれらは恒久対策ではありません。CISA KEVが両CVEに記載した requiredAction は Apply updates per vendor instructions. で、米国連邦機関向けの是正期限は2021年11月17日に設定されていました。緩和で止めている状態が長引くほど、設定の巻き戻りやWAFルールの誤設定といった別のリスクが積み上がります。単発のCVE対応ではなくWebサーバ全体の守りを組み直す段階なら、Webサーバーのセキュリティ対策|IPA20ヶ条と優先順位づけで優先順位のつけ方を確認してください。
公開から5年近いCVEが2026年も攻撃対象であり続ける理由
2021年10月の公開から約5年が経ちますが、このパターンのリクエストがログから消えないのには2つの理由があります。
1つ目は、攻撃側にとって投げ続けるコストがほぼゼロであること。Apache公式勧告はCVE-2021-41773について This issue is known to be exploited in the wild. と明記し、IPAの注意喚起も2021年10月7日の更新で本脆弱性を悪用したと思われる攻撃が国内で観測されたとの情報があると記載しました。CISA KEVには同年11月3日に両CVEが収録され、ランサムウェアキャンペーンでの使用は Known と記録されています。一度キャンペーンに組み込まれたペイロードは、スキャナのテンプレートに残り続けます。
2つ目は、危険な版が今も入手できることです。2.4.49と2.4.50の配布アーカイブはArchive of Apache HTTP Serverに2021年当時の日付のまま置かれています。当時の構築手順書やDockerfileが版番号を固定したまま残っていれば、2026年に実行しても2021年の脆弱な版がそのまま再現されます。攻撃が届く先は放置されたサーバだけでなく、古い手順が再生産される経路でもあるということです。
結果として、脆弱でない環境にもアラートだけは鳴り続けます。運用上は、対象版の有無と構成変更を基準に調査の要否を決めます。この2件について、ログに文字列が来るたびに調査を起こすのは無駄です。一度バージョンを確認して2.4.51以降だと分かったなら、対象の稼働バイナリと構成が変わらず、別の異常もなければ、この2件だけを理由に毎回侵害調査を始める必要はありません。構成変更時や異常な応答・通信がある場合は再評価してください。逆に、条件1に該当する版を使っている環境は、WAFルールを足して様子を見るのではなく即座に更新してください。公開PoCが複数あり自動化されている脆弱性で、緩和策を挟んだ観測期間を設ける判断は割に合いません。
そして見落としやすい失敗パターンを1つ挙げます。2021年にソースからビルドして以来バージョンを固定している構成と、コンテナイメージのタグを当時のまま pin している構成です。前者は脆弱性管理のスキャン対象にパッケージとして現れず、後者はイメージを再ビルドするたびに脆弱な版が復活します。どちらもディストリのパッケージ更新だけを追っている限り検知できません。この2件を調べた機会に、自社にソースビルドのApacheが残っていないかを棚卸ししておくことをおすすめします。
よくある質問
Apache 2.4.52はこの脆弱性の対象ですか?
CVE-2021-41773とCVE-2021-42013については対象外です。どちらも2.4.51で修正済みで、2.4.52はそれより後の版にあたります。ただし2.4.52以降にもApache HTTP Serverには別系統の脆弱性が公開されているため、「この2件は対象外」と「脆弱性がない」は別の話です。現行版までの脆弱性情報はApache HTTP Server 2.4の脆弱性まとめ:CVE-2026-33523ほか2.4.67/2.4.68の影響範囲と対応手順を参照してください。
CVE-2021-41773のPoCやMetasploitモジュールは公開されていますか?
公開されています。GitHubには検証コードのリポジトリが複数あり、Metasploit Frameworkにも脆弱性の有無を調べる auxiliary/scanner/http/apache_normalize_path と、RCEまで実行する exploit/multi/http/apache_normalize_path_rce の2つのモジュールが収録済みです。攻撃はすでに完全に自動化されている、という前提で対応の緊急度を決めてください。なお本記事は防御側の判断材料を目的としているため、動作するエクスプロイトの手順は掲載していません。検証が必要な場合は、自分が管理権限を持つ隔離環境に限って行ってください。
ログに攻撃文字列があれば侵害されたことになりますか?
なりません。判定材料は2つで、バージョンが2.4.49または2.4.50であるかどうかと、該当リクエストに200が返っているかどうかです。ただし、200以外でも攻撃失敗とは断定できません。CGIは実行後に出力形式の不備で500を返す場合もあるため、リクエスト当時のバージョン・設定と、error_logやプロセス・通信の記録を照合してください。
CVE-2021-41773のCVSSは7.5ですか、9.8ですか?
どちらも正しく、評価主体が異なります。NVD自身によるPrimaryが9.8 CRITICAL、CISA-ADPによるSecondaryが7.5 HIGHで、両方がNVDのレコードに併記されています。ベクタ上の差は完全性と可用性への影響を計上するかどうかで、RCEまで見るか読み出しまでで止めるかの違いと解釈できます(これはベクタからの読み取りで、公表された採点理由ではありません)。社内の脆弱性管理でどちらを採るか迷う場合は、CGIが有効かどうかで読み替えてください。
CVE-2021-41773とCVE-2021-42013は両方に対応が必要ですか?
2.4.51以降へ更新すれば一度で両方に対応できます。注意が必要なのは2.4.50で止めた場合で、これはCVE-2021-41773の対策にはなりますが、CVE-2021-42013の影響を受ける版のままです。当時の緊急対応で2.4.50を適用したまま更新を止めた環境が残っていないか、この機会に確認してください。