
POC_CVE-2026-45185 لـ nuclei-templates
هذا المستودع ليس مستودعًا عامًا لبراهين الاستغلال (PoC). إنه مختبر تحقق محلي لإعادة إنتاج ومراجعة سلوك قالب CVE-2026-45185 المُعدّ للمساهمة به في projectdiscovery/nuclei-templates.
The nuclei code template is not a version-only detector.
It directly controls STARTTLS, BDAT, TLS close_notify, and a following
SMTP plaintext byte on the same TCP connection.
This sequence matches in the local vulnerable Exim 4.99.2 GnuTLS lab and does
not match in the patched Exim 4.99.3 GnuTLS lab under the same conditions.
إشارة التحقق الحالية هي مُنبئ استجابة SMTP عن بُعد (response oracle)، وليست ملاحظة مباشرة لكتابة الاستخدام بعد التحرير (UAF) نفسها. داخليًا، هذه الثغرة هي استخدام بعد التحرير (use-after-free) حيث يمكن كتابة بايتات السطر الجديد (\r/\n) في مخزن نقل GnuTLS مُحرَّر بعد إيقاف TLS. عمليًا، لا يمكن للعميل ملاحظة تلك الكتابة في المخزن المُحرَّر مباشرةً عبر استجابات SMTP. لذلك، لا يدّعي هذا الملف README ولا القالب إثباتَ كتابة الاستخدام بعد التحرير bdat_ungetc -> tls_ungetc أو تنفيذ التعليمات البرمجية عن بُعد (RCE) بشكل مباشر. بدلًا من ذلك، يكتشف القالب فرقًا في استرداد حالة مكدس الاستقبال يظهر أثناء تدفق التشغيل.
أثناء تتبع آلية الثغرة، لاحظت أنه بعد close_notify الخاص بـ TLS أثناء معالجة STARTTLS + BDAT، يمكن أن تبقى مؤشرات دوال tls_* قديمة في الطبقة السفلية من مكدس استقبال BDAT بدلًا من استعادتها بشكل صحيح إلى مؤشرات دوال smtp_*. تصبح تلك الحالة مرئية في طريقة تعامل الخادم مع أمر SMTP التالي. بعد وصول BDAT المقسم إلى الاكتمال الأول، يؤدي إرسال NOOP على نفس الجلسة إلى جعل مختبر Exim 4.99.2 GnuTLS الضعيف يُرجع 421 lost input connection، بينما يعالجه مختبر Exim 4.99.3 GnuTLS المُصحَّح بشكل طبيعي مع 250 OK. يُستخدم هذا الفرق الواضح بين الاستجابة الضعيفة والمُصحَّحة كمطابق (matcher) لقالب nuclei code المحلي المصرح به.
لمراجعة أعمق لمسار الثغرة خطوة بخطوة، راجع CVE-2026-45185-Technical-Analysis.md.
| الهدف | الإصدار | خلفية TLS | STARTTLS | CHUNKING | المنفذ | نتيجة nuclei المتوقعة |
|---|---|---|---|---|---|---|
| ضعيف | Exim 4.99.2 | GnuTLS | نعم | نعم | 127.0.0.1:2525 | مطابق |
| مُصحَّح | Exim 4.99.3 | GnuTLS | نعم | نعم | 127.0.0.1:2526 | غير مطابق |
مستلم مغلف SMTP الشائع (RCPT TO):
[email protected]
قائمة التحكم بالوصول (ACL) lab_rcpt في مختبر Docker تقبل مستلم المغلف هذا. على هدف SMTP عام، إذا تم رفض RCPT TO، فقد لا يصل التسلسل إلى محلل نص BDAT، لذا يحتاج القالب إلى مستلم مقبول.
تختلف هذه القيمة عن ترويسة To: داخل نص BDAT. مستلم RCPT TO هو عنوان مغلف SMTP يجب أن يجتاز فحوصات المستلمين في الخادم. قيمة To: في نص BDAT هي مجرد نص ترويسة رسالة؛ ولا يلزم أن تكون موجودة أو مقبولة كصندوق بريد من قبل الخادم.
templates/CVE-2026-45185.yaml
اسم القالب:
Exim 4.97-4.99.2 GnuTLS STARTTLS BDAT - Same-Session Response Check
القالب مكتوب مع metadata.verified: true ويحتوي على وسمي code وintrusive.
شغّل الأوامر التالية من دليل POC_2026_45185/.
docker compose build
docker compose up -d
تحقق من صيغة القالب:
nuclei -duc -validate -code -t templates/CVE-2026-45185.yaml
وقّع قالب الكود المحلي قبل تشغيله:
nuclei -duc -code -t templates/CVE-2026-45185.yaml -sign
شغّله ضد المختبر الضعيف:
nuclei -code \
-t templates/CVE-2026-45185.yaml \
-u 127.0.0.1:2525 \
-var [email protected] \
-debug
النتيجة المتوقعة:
CVE-2026-45185: vulnerable response oracle matched
شغّله ضد المختبر المُصحَّح:
nuclei -code \
-t templates/CVE-2026-45185.yaml \
-u 127.0.0.1:2526 \
-var [email protected] \
-debug
النتيجة المتوقعة:
no match
NO-MATCH: patched-like response: NOOP succeeded after split trigger
لاحظ أن بروتوكول code في nuclei لا يُنفَّذ افتراضيًا، لذا فإن -code مطلوب. كما يمنع nuclei قوالب code غير الموقَّعة. إذا كان المفتاح الخاص المحلي لـ nuclei محميًا بعبارة مرور، فشغّل أمر التوقيع في طرفية تفاعلية وأدخل عبارة المرور تلك. أعد التوقيع بعد كل تغيير في القالب لأن الملخص (digest) يغطي محتوى القالب.
تعرض لقطات الشاشة هذه نتيجة مُنبئ الاستجابة للمختبر المحلي بعد توقيع القالب. وهي دليل تحقق على فرق الاستجابة لنفس الجلسة الموصوف أعلاه، وليست إثباتًا مباشرًا من مصحح الأخطاء أو ASAN على كتابة الاستخدام بعد التحرير الداخلية.
مختبر Exim 4.99.2 GnuTLS الضعيف على 127.0.0.1:2525:

مختبر Exim 4.99.3 GnuTLS المُصحَّح على 127.0.0.1:2526:

جوهر هذه الثغرة ليس شعار SMTP أو فحص إصدار. يحتاج القالب إلى إنشاء انتقال حالة النقل التالي على نفس اتصال TCP:
plaintext SMTP EHLO
-> STARTTLS
-> TLS handshake on the same TCP connection
-> TLS EHLO / MAIL FROM / RCPT TO / BDAT 70 LAST
-> first 69 bytes of the BDAT body as TLS application data
-> TLS close_notify without closing the TCP socket
-> final body byte as plaintext on the same TCP connection
-> same-session plaintext NOOP response check
يطبع كود Python داخل قالب YAML العلامة الثابتة فقط بعد استيفاء جميع الشروط التالية. يطابق مطابق nuclei تلك العلامة فقط.
Exim identity is found
AND STARTTLS is advertised in plaintext EHLO
AND CHUNKING is advertised in plaintext EHLO
AND STARTTLS is accepted
AND CHUNKING is advertised in TLS EHLO
AND MAIL FROM is accepted
AND RCPT TO is accepted
AND the split close_notify BDAT reaches first completion
AND first completion contains "250 OK id="
AND the same-session plaintext NOOP response contains "421"
AND the same-session plaintext NOOP response contains "lost input connection"
لا يطابق القالب على أيٍّ من الإشارات التالية بمفردها:
version-only
timeout-only
connection-drop-only
empty-response-only
recipient rejection
STARTTLS/CHUNKING advertisement only
يعالج كلا المختبرين رسالة BDAT المقسمة حتى الاكتمال الأول.
250- 70 byte chunk, total 72
250 OK id=...
يظهر الفرق عند إرسال أمر SMTP النصي التالي على نفس جلسة SMTP.
إصدار 4.99.2 الضعيف:
NOOP -> 421 exim-lab.local lost input connection
QUIT -> 421 exim-lab.local lost input connection
RSET -> 421 exim-lab.local lost input connection
إصدار 4.99.3 المُصحَّح:
NOOP -> 250 OK
QUIT -> 221 exim-lab.local closing connection
RSET -> 250 Reset OK
التفسير:
Observation:
Both labs reach split BDAT message completion.
Only the vulnerable lab fails to return cleanly to the next plaintext SMTP
command loop in the same session.
Evidence:
The vulnerable follow-up response is 421 lost input connection.
The patched follow-up response is 250 OK or 221 closing connection.
Inference:
This difference is consistent with the receive stack/state recovery difference
after STARTTLS close_notify.
يستخدم القالب الرسالة التالية المكوّنة من 70 بايتًا كنص BDAT.
From: [email protected]\r\n
To: [email protected]\r\n
Subject: poc\r\n
\r\n
body
يُمرَّر مستلم مغلف SMTP بشكل منفصل عبر متغير القالب recipient. ترويسة To: في النص هي نص وهي غير مرتبطة بما إذا كان SMTP RCPT TO مقبولًا، لذا لا يلزم أن تكون موجودة أو مقبولة من قبل الخادم.
شكل التقسيم:
BDAT 70 LAST
TLS body: first 69 bytes, ending with "bod"
TLS event: close_notify
Plaintext: final byte "y"
Follow-up: NOOP
يمكنك التحقق يدويًا من أن كلا المختبرين يعلنان عن Exim وSTARTTLS وCHUNKING.
printf 'EHLO lab-client.local\r\nQUIT\r\n' | nc -w 3 127.0.0.1 2525
printf 'EHLO lab-client.local\r\nQUIT\r\n' | nc -w 3 127.0.0.1 2526
الإشارات المتوقعة:
Exim
STARTTLS
CHUNKING
يمكنك أيضًا فحص المسار الطبيعي لـ STARTTLS: