ماسح ضوئي للثغرات قائم على الصدفة لـ CVE-2026-45185 (Dead.Letter) في Exim MTA. يكتشف use-after-free في إصدارات GnuTLS، ويتحقق من الإصدار، ومكتبة TLS، وتكوين CHUNKING. ينتج مخرجات JSON للتكامل مع CI/CD.
سكريبت شل للكشف عما إذا كان نظام لينكس معرضًا لثغرة CVE-2026-45185، وهي ثغرة use-after-free في وكيل نقل البريد Exim يمكن أن تؤدي إلى تنفيذ تعليمات عن بعد.
مصمم للاستخدام في خطوط CI/CD وأدوات إدارة التهيئة وعمليات تدقيق النظام المخصصة. ينتج مخرجات قابلة للقراءة البشرية والآلة (JSON).
CVE-2026-45185 (الاسم المستعار: Dead.Letter) هي خطأ use-after-free في تحليل محتوى رسالة BDAT (البيانات الثنائية) في Exim، ويتم تشغيله عند معالجة TLS بواسطة GnuTLS.
أثناء إيقاف TLS، يقوم Exim بتحرير مخزن نقل TLS — لكن مُغلِّف استقبال BDAT المتداخل يمكنه معالجة البايتات الواردة واستدعاء ungetc()، مما يكتب بايت \n واحد في المنطقة المُحرَّرة. تكتب بايت واحد يُفسِد بيانات تعريف مخصص الكومة (heap allocator metadata)، والتي يمكن للمهاجم من خلالها الحصول على مزيد من بدائيات الذاكرة وتحقيق تنفيذ تعليمات عن بعد.
| الخاصية | التفاصيل |
|---|---|
| CVE | CVE-2026-45185 |
| الاسم المستعار | Dead.Letter |
| النوع | Use-After-Free (CWE-416) |
| المكون | معالج BDAT/CHUNKING في Exim (إصدارات GnuTLS فقط) |
| متجه الهجوم | شبكة — بدون مصادقة، يتطلب فقط اتصال TLS وإضافة CHUNKING |
| الإصدارات المتأثرة | Exim 4.97 – 4.99.2، إصدارات GnuTLS فقط |
| تم الإصلاح في | Exim 4.99.3 |
| اكتشفها | Federico Kirschbaum، مختبر XBOW لأمن المعلومات (تم الإبلاغ في 1 مايو 2026) |
إصدارات OpenSSL غير متأثرة. الثغرة خاصة بـ Exim المُجمَّع بـ
USE_GNUTLS=yes. إذا كان Exim لديك يرتبط بـ OpenSSL، فأنت لست معرضًا للخطر بغض النظر عن الإصدار.
يعمل السكريبت من خلال شجرة قرارات، ويتوقف ويُعلِّم النظام غير معرض بمجرد تأكيد شرط آمن قاطع:
الفحص 1 — وجود Exim
يبحث في $PATH ومواقع التثبيت الشائعة (/usr/sbin/exim، /usr/sbin/exim4، /usr/local/sbin/exim). إذا لم يتم العثور على Exim، فالنظام غير معرض ويخرج السكريبت فورًا.
الفحص 2 — إصدار Exim
يُحلل مخرجات exim -bV ويقارنها بالنطاق المتأثر (4.97 – 4.99.2). الإصدارات ≥ 4.99.3 تُعالج على أنها مصححة. الإصدارات خارج النطاق المعروف تُعلَّم غير معرضة (مع ملاحظة إذا كانت غير معروفة).
الفحص 3 — مكتبة TLS (البوابة الحرجة) يستخدم ثلاث طرق كشف بالتسلسل:
exim -bV (الأكثر موثوقية — يُبلغ Exim عن ميزاته في وقت التجميع، مثل Support for: GnuTLS)ldd المشتركةstrings (حل احتياطي)إذا تم الكشف عن OpenSSL → الحكم يتحول إلى غير معرض بغض النظر عن الإصدار. إذا تم الكشف عن GnuTLS → يتم تأكيد وجود سطح الهجوم. إذا لم يمكن تحديد أي منهما → النتيجة غير حاسمة.
الفحص 4 — تهيئة CHUNKING/BDAT (فحص الحل المؤقت)
يتم تشغيله فقط إذا كان النظام لا يزال مُعلَّمًا على أنه معرض في هذه النقطة. يتحقق مما إذا تم تعيين chunking_advertise_hosts صراحةً إلى قيمة فارغة في تهيئة Exim، مما يعطل إعلان BDAT ويمنع متجه الهجوم. يعالج كلًا من ملفات التهيئة المفردة وتخطيط التهيئة المقسم في دبيان (/etc/exim4/conf.d/).
ملاحظة: إذا كان
chunking_advertise_hostsغائبًا عن التهيئة (الافتراضي)، فإن Exim يُعلِن CHUNKING لجميع المضيفين (*). يجب تعيين الخيار صراحةً إلى قيمة فارغة لتعطيله.
الفحص 5 — معلومات تخفيف النظام لا يغير الحكم، لكنه يُبلِّغ عن العوامل التي تؤثر على قابلية الاستغلال:
/proc/sys/kernel/randomize_va_space) — يجب أن يكون 2checksec للثنائي Exim (PIE, RELRO, stack canaries) إذا كان checksec مثبتًاMemoryDenyWriteExecute، NoNewPrivileges، SystemCallFilter/proc (لفحص ASLR)grep، awk، ldd، headchecksec (اختياري — لتحليل تحصين الثنائي)systemctl (اختياري — لفحص وحدة systemd)Debian-exim على Debian/Ubuntu)لا توجد تبعيات خارجية مطلوبة لفحوصات الثغرة الأساسية.
chmod +x check_cve_2026_45185.sh
./check_cve_2026_45185.sh
| العلم | الوصف |
|---|---|
--json | إخراج النتائج ككائن JSON (انظر أدناه) |
--quiet | منع كل المخرجات؛ يتم تعيين رمز الخروج فقط |
--no-color | تعطيل رموز الألوان ANSI (مفيد لملفات السجل) |
--help / -h | طباعة معلومات الاستخدام |
| الرمز | المعنى |
|---|---|
0 | غير معرض (أو تم العثور على حالة آمنة قاطعة) |
1 | معرض |
2 | غير حاسم — لم يمكن تحديد حقيقة أو أكثر؛ تعامل معه على أنه يحتمل أن يكون معرضًا |
3 | خطأ في السكريبت أو بيئة غير مدعومة |
CVE-2026-45185 (Dead.Letter) — Exim Vulnerability Assessment
============================================================
[CHECK] Checking for Exim installation...
[WARN] Exim binary found: /usr/sbin/exim4
[CHECK] Checking Exim version...
Detected version: 4.99.1
[FAIL] Exim 4.99.1 is in the vulnerable range (4.97 – 4.99.2).
[CHECK] Checking TLS library linkage (GnuTLS vs OpenSSL)...
[FAIL] Exim is linked against GnuTLS — this build IS affected.
[CHECK] Checking CHUNKING (BDAT) advertisement config...
Config file: /etc/exim4/exim4.conf
[WARN] chunking_advertise_hosts is not disabled — BDAT is active (default advertises to all hosts).
Tip: add 'chunking_advertise_hosts =' (empty value) to your main config to disable BDAT as a workaround.
[CHECK] Checking system-level exploit mitigations (informational)...
[PASS] ASLR: full randomisation (randomize_va_space=2)
glibc version: 2.35 (2.32+ has stronger heap metadata checks)
[WARN] systemd: MemoryDenyWriteExecute not set — recommend adding to unit
[WARN] systemd: NoNewPrivileges not set
------------------------------------------------------------
VERDICT
------------------------------------------------------------
VULNERABLE — CVE-2026-45185
Reason: Exim version 4.99.1 is in vulnerable range 4.97–4.99.2
Recommended actions:
1. Upgrade Exim to 4.99.3 or later (primary fix)
2. As a workaround, set 'chunking_advertise_hosts =' (empty) in exim config
3. Add MemoryDenyWriteExecute=yes and NoNewPrivileges=yes to the systemd unit
4. Ensure ASLR is set to 2: echo 2 > /proc/sys/kernel/randomize_va_space
------------------------------------------------------------
--json){
"cve": "CVE-2026-45185",
"alias": "Dead.Letter",
"host": "mailserver-01",
"timestamp": "2026-05-12T17:00:00Z",
"verdict": "vulnerable",
"reason": "Exim version 4.99.1 is in vulnerable range 4.97–4.99.2",
"exit_code": 1,
"findings": {
"exim_binary": "/usr/sbin/exim4",
"exim_version": "4.99.1",
"exim_version_vulnerable": "true",
"tls_library": "gnutls",
"tls_library_detected": "gnutls",
"exim_config": "/etc/exim4/exim4.conf",
"chunking_advertised": "true",
"aslr_level": "2",
"glibc_version": "2.35"
},
"mitigations": [
"aslr=full"
]
}
- name: Check for CVE-2026-45185
run: |
chmod +x check_cve_2026_45185.sh
./check_cve_2026_45185.sh --json | tee vuln-report.json
exit $(jq '.exit_code' vuln-report.json)
- name: Upload vulnerability report
if: always()
uses: actions/upload-artifact@v4
with:
name: cve-2026-45185-report
path: vuln-report.json
check-exim-vuln:
stage: security
script:
- chmod +x check_cve_2026_45185.sh
- ./check_cve_2026_45185.sh --json > vuln-report.json
artifacts:
when: always
paths:
- vuln-report.json
allow_failure: false
- name: Run CVE-2026-45185 check
script: check_cve_2026_45185.sh --json
register: vuln_check
failed_when: vuln_check.rc == 1
changed_when: false
- name: Show vulnerability report
debug:
msg: "{{ vuln_check.stdout | from_json }}"
# Get just the verdict
./check_cve_2026_45185.sh --json | jq -r '.verdict'