
Dead.Letter CVE-2026-45185 Script de Detección de Vulnerabilidades de EXIM
Un script de shell para detectar si un sistema Linux es vulnerable a CVE-2026-45185, un use-after-free en el agente de transferencia de correo Exim que puede conducir a la ejecución remota de código.
Diseñado para su uso en canalizaciones de CI/CD, herramientas de gestión de configuración y auditorías de sistema ad hoc. Produce una salida legible para humanos y legible por máquina (JSON).
CVE-2026-45185 (alias: Dead.Letter) es un fallo de use-after-free en el análisis del cuerpo del mensaje BDAT (datos binarios) de Exim, que se activa cuando TLS es gestionado por GnuTLS.
Durante el cierre de TLS, Exim libera su búfer de transferencia TLS — pero un
envoltorio receptor BDAT anidado aún puede procesar bytes entrantes y llamar a
ungetc(), escribiendo un único byte \n en la región liberada. Esa escritura
de un byte corrompe los metadatos del asignador de heap, a partir de los cuales
un atacante puede obtener primitivas de memoria adicionales y lograr la
ejecución remota de código.
| Propiedad | Detalle |
|---|---|
| CVE | CVE-2026-45185 |
| Alias | Dead.Letter |
| Tipo | Use-After-Free (CWE-416) |
| Componente | Manejador BDAT/CHUNKING de Exim (solo compilaciones con GnuTLS) |
| Vector de ataque | Red — no autenticado, requiere solo una conexión TLS y la extensión CHUNKING |
| Versiones afectadas | Exim 4.97 – 4.99.2, solo compilaciones con GnuTLS |
| Corregido en | Exim 4.99.3 |
| Descubierto por | Federico Kirschbaum, XBOW Security Lab (reportado el 1 de mayo de 2026) |
Las compilaciones con OpenSSL no están afectadas. La vulnerabilidad es específica de Exim compilado con
USE_GNUTLS=yes. Si su Exim enlaza contra OpenSSL, no es vulnerable independientemente de la versión.
El script recorre un árbol de decisión, deteniéndose y marcando el sistema como no vulnerable en cuanto se confirma una condición segura definitiva:
Comprobación 1 — Presencia de Exim
Busca en $PATH y en ubicaciones de instalación comunes (/usr/sbin/exim,
/usr/sbin/exim4, /usr/local/sbin/exim). Si no se encuentra Exim, el sistema
no es vulnerable y el script sale inmediatamente.
Comprobación 2 — Versión de Exim
Analiza la salida de exim -bV y la compara con el rango afectado
(4.97 – 4.99.2). Las versiones ≥ 4.99.3 se tratan como parcheadas. Las versiones
fuera del rango conocido se marcan como no vulnerables (con una nota si no son
reconocidas).
Comprobación 3 — Biblioteca TLS (el punto crítico) Utiliza tres métodos de detección en secuencia:
exim -bV (la más fiable — Exim informa de sus propias características de compilación, p. ej. Support for: GnuTLS)lddstrings (respaldo)Si se detecta OpenSSL → el veredicto cambia a no vulnerable independientemente de la versión. Si se detecta GnuTLS → se confirma que la superficie de ataque está presente. Si no se puede determinar ninguno → el resultado es inconcluyente.
Comprobación 4 — Configuración de CHUNKING/BDAT (comprobación de solución alternativa)
Solo se ejecuta si el sistema sigue marcado como vulnerable en este punto.
Comprueba si chunking_advertise_hosts se ha establecido explícitamente a un
valor vacío en la configuración de Exim, lo que desactiva el anuncio de BDAT y
bloquea el vector de ataque. Gestiona tanto configuraciones de un solo archivo
como el diseño de configuración dividida de Debian (fragmentos de
/etc/exim4/conf.d/).
Nota: si
chunking_advertise_hostsestá ausente de la configuración (por defecto), Exim anuncia CHUNKING a todos los hosts (*). La opción debe establecerse explícitamente a un valor vacío para desactivarla.
Comprobación 5 — Mitigaciones informativas del sistema No cambia el veredicto, pero informa sobre factores que afectan a la explotabilidad:
/proc/sys/kernel/randomize_va_space) — debería ser 2checksec para el binario de Exim (PIE, RELRO, canarios de pila) si checksec está instaladoMemoryDenyWriteExecute, NoNewPrivileges, SystemCallFilter/proc (para la comprobación de ASLR)grep, awk, ldd, headchecksec (opcional — para el análisis de endurecimiento del binario)systemctl (opcional — para la inspección de unidades systemd)Debian-exim en Debian/Ubuntu)No se requieren dependencias externas para las comprobaciones básicas de vulnerabilidad.
chmod +x check_cve_2026_45185.sh
./check_cve_2026_45185.sh
| Opción | Descripción |
|---|
| Código | Significado |
|---|---|
0 | No vulnerable (o se encontró una condición segura definitiva) |
1 |
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'
# Check if a specific mitigation was found
./check_cve_2026_45185.sh --json | jq '.mitigations | contains(["aslr=full"])'
# Run across multiple hosts and collect results
for host in mail1 mail2 mail3; do
ssh "$host" 'bash -s' < check_cve_2026_45185.sh --json
done | jq -s '.'
# Debian / Ubuntu
apt-get update && apt-get install --only-upgrade exim4
# RHEL / CentOS / Fedora
dnf upgrade exim
# From source
# Download 4.99.3 from https://ftp.exim.org/pub/exim/exim4/
# and rebuild with your existing Local/Makefile settings
Verificar después de la actualización:
exim -bV | head -1
# Expected: Exim version 4.99.3 ...
Si no puede actualizar de inmediato, añadir la siguiente línea a la sección de configuración principal de su configuración de Exim desactiva por completo el anuncio de BDAT, bloqueando el vector de ataque:
chunking_advertise_hosts =
El valor vacío significa «ningún host»: Exim ya no anunciará la extensión
CHUNKING en las respuestas EHLO. Reinicie Exim después de realizar este
cambio:
# Debian / Ubuntu
systemctl restart exim4
# Other systemd systems
systemctl restart exim
Verificar que CHUNKING ya no se anuncia:
# Connect and check the EHLO response — CHUNKING should not appear
echo QUIT | openssl s_client -connect localhost:25 -starttls smtp 2>/dev/null \
| grep -i chunking
# No output = CHUNKING is disabled
Esto es una solución alternativa, no una corrección. Algunos servidores de correo remitentes usan BDAT para la entrega de mensajes grandes. Desactivarlo puede causar problemas de compatibilidad con esos remitentes. Actualice a 4.99.3 lo antes posible.
Incluso en un sistema parcheado, añadir estas directivas a la unidad systemd de Exim reduce el impacto de cualquier futura vulnerabilidad de corrupción de memoria:
# /etc/systemd/system/exim4.service.d/hardening.conf
[Service]
NoNewPrivileges=yes
MemoryDenyWriteExecute=yes
ProtectSystem=strict
PrivateTmp=yes
RestrictAddressFamilies=AF_INET AF_INET6
SystemCallFilter=@system-service
systemctl daemon-reload && systemctl restart exim4
ldd y strings, que pueden ser menos fiables.--json | Muestra los resultados como un objeto JSON (ver más abajo) |
--quiet | Suprime toda la salida; solo se establece el código de salida |
--no-color | Desactiva los códigos de color ANSI (útil para archivos de registro) |
--help / -h | Muestra información de uso |
| Vulnerable |
2 | Inconcluyente — no se pudieron determinar uno o más hechos necesarios; trátese como potencialmente vulnerable |
3 | Error de script o entorno no compatible |