CVE-2024-4577: 2012年の対策をすり抜けた PHP-CGI RCE
PHP-CGI では 2012 年、クエリ文字列がコマンドライン引数として解釈され、危険なオプションを注入できる脆弱性(CVE-2012-1823)が問題になりました。これに対し PHP 側では、- で始まる入力を危険なオプションとして扱う防御が導入されていました。しかし攻撃者は、通常のハイフンではなくソフトハイフン(%AD)を送信することで、この防御を迂回しました。
攻撃の流れ
1
PHP-CGI 側の防御:
入力は %AD(ソフトハイフン / 0xAD)であり、通常の -(0x2D)ではないため、「危険なオプションではない」と判断して通過させる。
2
Windows の Best-Fit 変換:
特定コードページ環境(CP932 / 936 / 950 など)では、0xAD が通常のハイフン 0x2D として扱われる。
3
結果:
12 年間守り続けた防御を迂回して PHP-CGI のオプション注入が成立し、リモートコード実行(RCE)に至る。
影響を受けるのは「Windows 上の PHP 全般」ではなく、Windows 上で Apache + PHP-CGI を CGI モードで動かしている構成や、php-cgi.exe / php.exe が外部に露出している構成が中心です。
補足:観測された悪用例(Cisco Talos)
この脆弱性は理論上の問題にとどまらず、実際の攻撃でも悪用されています。Cisco Talos は、CVE-2024-4577 が初期アクセスに利用され、その後 PowerShell 経由で Cobalt Strike reverse HTTP shellcode が実行され、TaoWu キットを用いた後続活動が観測された日本国内の攻撃キャンペーンを報告しています。ただしこれは「脆弱性の仕様」ではなく「観測された悪用パターン」であることに注意が必要です。
Argument Splitting: 意図しない引数の注入
Pythonなどの言語からWindows上の外部コマンド(例:wget.exe)を呼び出す際、呼び出し元では安全に引数化したはずの文字列が、呼び出し先プログラム側のANSI API経由でBest-Fit変換され、引数の境界が崩れる事例です。
開発者が書いたコード
run(['wget.exe', 'example.tld/" --use-askpass=calc ".txt'])
開発者の想定:
"(U+FF02 / Fullwidth Quotation Mark)は単なるファイル名の一部。
実際の挙動:
呼び出し先の wget.exe が ANSI API 経由でコマンドラインを取得すると、" が半角の " に変換される。
wget.exe 側で解釈されるコマンドライン
wget.exe "example.tld/" --use-askpass=calc ".txt"
全角ダブルクォート " が半角の " に変換されたことで、本来 1 つの引数だった文字列が分割され、--use-askpass=calc が独立したオプションとして解釈されます。wget.exe の --use-askpass オプションは外部プログラムを呼び出すため、結果として calc.exe が起動します。
補足:危険な文字はコードページで変わる
この全角ダブルクォート " による Argument Splitting は、主に CP125x / 874 系コードページで説明される例です。日本語環境の CP932 では、円記号 ¥ がバックスラッシュ \ に変換され、クォートやパス解釈を壊すパターンも重要です(次タブの Cuckoo Sandbox 脱出が該当)。つまり、危険な文字はコードページによって変わります。
Sandboxからの脱出: 日本語環境特有のパス遡行
マルウェア解析環境である「Cuckoo Sandbox」での皮肉な被害です。攻撃者は解析環境を破壊するため、特殊なファイル名を送り込みました。
入力ファイル名:
AAAA¥ .¥ .¥ .¥ .¥ .¥ .¥conf¥cuckoo.conf
※ ¥ はキーボードの半角円マークではなく、Unicode の U+00A5
日本語環境のWindowsでは、この ¥ がBest-fit mappingにより \(ディレクトリ区切り文字)に無条件変換されます。その結果、ただの長いファイル名が ..\..\..\ というパストラバーサル攻撃へと変貌し、Sandbox外の設定ファイルを読み取られてしまいました。
補足:これは Cuckoo 2.x 系の話
これは「Cuckooというサンドボックス全体が危険」という意味ではなく、問題の文脈は 公式版 Cuckoo Sandbox 2.x 系 です。PyPI 上の Cuckoo は最新版 2.0.7(2019年6月公開)が Python 2.7 前提で、cuckoosandbox/cuckoo リポジトリも 2021 年にアーカイブされ「2.x is currently unmaintained」と明記されています。一方、Python 3 系の Cuckoo3(CERT-EE)は別プロジェクトとして現在も更新中です。ここで問題なのは Cuckoo3 ではなく、Python 2.7 に依存した旧 Cuckoo 2.x 系で、Cuckoo Host 側のファイル処理が ANSI API 由来の Best-Fit 挙動を受けた点でした。