## https://sploitus.com/exploit?id=E06430E8-210A-510A-A01B-011688E27E2F
# CVE-2026-45185 โ "Dead.Letter" Exim Vulnerability Scanner
A shell script for detecting whether a Linux system is vulnerable to
CVE-2026-45185, a use-after-free in the Exim mail transfer agent that can
lead to remote code execution.
Designed for use in CI/CD pipelines, configuration management tooling, and
ad-hoc system audits. Produces both human-readable and machine-readable
(JSON) output.
---
## The Vulnerability
**CVE-2026-45185** (alias: *Dead.Letter*) is a use-after-free bug in Exim's
BDAT (binary data) message body parsing, triggered when TLS is handled by
GnuTLS.
During TLS shutdown, Exim frees its TLS transfer buffer โ but a nested BDAT
receive wrapper can still process incoming bytes and call `ungetc()`, writing
a single `\n` byte into the freed region. That one-byte write corrupts heap
allocator metadata, from which an attacker can gain further memory primitives
and achieve remote code execution.
| Property | Detail |
|---|---|
| **CVE** | CVE-2026-45185 |
| **Alias** | Dead.Letter |
| **Type** | Use-After-Free (CWE-416) |
| **Component** | Exim BDAT/CHUNKING handler (GnuTLS builds only) |
| **Attack vector** | Network โ unauthenticated, requires only a TLS connection and CHUNKING extension |
| **Affected versions** | Exim 4.97 โ 4.99.2, GnuTLS builds only |
| **Fixed in** | Exim 4.99.3 |
| **Discovered by** | Federico Kirschbaum, XBOW Security Lab (reported 1 May 2026) |
> **OpenSSL builds are not affected.** The vulnerability is specific to Exim
> compiled with `USE_GNUTLS=yes`. If your Exim links against OpenSSL, you are
> not vulnerable regardless of version.
---
## What the Script Checks
The script works through a decision tree, stopping and marking the system
**not vulnerable** as soon as a definitive safe condition is confirmed:
**Check 1 โ Exim presence**
Searches `$PATH` and common install locations (`/usr/sbin/exim`,
`/usr/sbin/exim4`, `/usr/local/sbin/exim`). If Exim is not found, the system
is not vulnerable and the script exits immediately.
**Check 2 โ Exim version**
Parses `exim -bV` output and compares against the affected range
(4.97 โ 4.99.2). Versions โฅ 4.99.3 are treated as patched. Versions outside
the known range are marked not vulnerable (with a note if they are
unrecognised).
**Check 3 โ TLS library (the critical gate)**
Uses three detection methods in sequence:
1. `exim -bV` build information (most reliable โ Exim reports its own compile-time features, e.g. `Support for: GnuTLS`)
2. `ldd` shared library linkage
3. `strings` binary scan (fallback)
If OpenSSL is detected โ verdict flips to **not vulnerable** regardless of
version. If GnuTLS is detected โ the attack surface is confirmed present. If
neither can be determined โ result is **inconclusive**.
**Check 4 โ CHUNKING/BDAT config (workaround check)**
Only runs if the system is still marked vulnerable at this point. Checks
whether `chunking_advertise_hosts` has been explicitly set to an empty value
in the Exim config, which disables BDAT advertisement and blocks the attack
vector. Handles both single-file configs and Debian's split-config layout
(`/etc/exim4/conf.d/` fragments).
> Note: if `chunking_advertise_hosts` is *absent* from the config (the
> default), Exim advertises CHUNKING to all hosts (`*`). The option must be
> explicitly set to an empty value to disable it.
**Check 5 โ Informational system mitigations**
Does not change the verdict, but reports on factors that affect
exploitability:
- ASLR level (`/proc/sys/kernel/randomize_va_space`) โ should be `2`
- glibc version โ 2.32+ has stronger heap metadata integrity checks
- `checksec` output for the Exim binary (PIE, RELRO, stack canaries) if `checksec` is installed
- systemd unit sandboxing: `MemoryDenyWriteExecute`, `NoNewPrivileges`, `SystemCallFilter`
---
## Requirements
- **Bash** 4.0 or later
- **Linux** with `/proc` filesystem (for ASLR check)
- Standard coreutils: `grep`, `awk`, `ldd`, `head`
- `checksec` (optional โ for binary hardening analysis)
- `systemctl` (optional โ for systemd unit inspection)
- Must be run with sufficient privilege to read the Exim config file (typically root, or a user in the `Debian-exim` group on Debian/Ubuntu)
No external dependencies are required for the core vulnerability checks.
---
## Usage
```bash
chmod +x check_cve_2026_45185.sh
./check_cve_2026_45185.sh
```
### Options
| Flag | Description |
|---|---|
| `--json` | Output results as a JSON object (see below) |
| `--quiet` | Suppress all output; only the exit code is set |
| `--no-color` | Disable ANSI colour codes (useful for log files) |
| `--help` / `-h` | Print usage information |
### Exit Codes
| Code | Meaning |
|---|---|
| `0` | Not vulnerable (or a definitive safe condition was found) |
| `1` | Vulnerable |
| `2` | Inconclusive โ could not determine one or more required facts; treat as potentially vulnerable |
| `3` | Script error or unsupported environment |
---
## Example Output
### Human-readable (default)
```
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 output (`--json`)
```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"
]
}
```
---
## CI/CD Integration
### GitHub Actions
```yaml
- 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
```
### GitLab CI
```yaml
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
```
### Ansible
```yaml
- 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 }}"
```
### Parsing JSON output with jq
```bash
# 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' /dev/null \
| grep -i chunking
# No output = CHUNKING is disabled
```
> **This is a workaround, not a fix.** Some sending mail servers use BDAT for
> large message delivery. Disabling it may cause compatibility issues with
> those senders. Upgrade to 4.99.3 as soon as possible.
### Hardening the systemd unit (defence in depth)
Even on a patched system, adding these directives to the Exim systemd unit
reduces the impact of any future memory corruption vulnerability:
```ini
# /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
```
```bash
systemctl daemon-reload && systemctl restart exim4
```
---
## Limitations
- The script performs **static detection** only. It does not attempt to
exploit the vulnerability or confirm exploitability under the specific
runtime conditions of the target system.
- On systems where the Exim binary cannot be executed (e.g. permission
constraints in a container), TLS library detection falls back to `ldd` and
`strings`, which may be less reliable.
- Exim versions **below 4.97** are outside the known affected range for this
specific CVE, but are unmaintained and likely vulnerable to other
unpatched issues. Upgrading is recommended regardless.
- The script requires read access to the Exim configuration file to check
the CHUNKING workaround. If run without sufficient privilege, the config
check step will report inconclusive rather than failing.
---
## References
- [The Hacker News โ New Exim BDAT Vulnerability Exposes GnuTLS Builds to Potential Code Execution](https://thehackernews.com/2026/05/new-exim-bdat-vulnerability-exposes.html)
- [Exim project โ Security documentation](https://www.exim.org/static/doc/security/)
- [Exim specification โ CHUNKING (`chunking_advertise_hosts`)](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-main_configuration.html)
- [Exim specification โ TLS configuration](https://www.exim.org/exim-html-current/doc/html/spec_html/ch-encrypted_smtp_connections_using_tlsssl.html)
- [XBOW Security Lab](https://xbow.com)