This is a loaded mail dock with one bad forklift model, not every warehouse on the block
CVE-2026-45185 is a remotely reachable use-after-free in Exim's BDAT/CHUNKING body parsing path when TLS is handled by GnuTLS. The published advisory says Exim 4.97 through 4.99.2 are affected, fixed in 4.99.3, and the trigger requires a client to negotiate TLS, start a BDAT transfer, send close_notify before the body completes, then push a final cleartext byte on the same TCP connection. Builds using OpenSSL or other TLS libraries are not affected.
The vendor's 9.8/CRITICAL is technically understandable in a lab because this is pre-auth remote memory corruption on a public-facing mail daemon. In enterprise reality, though, it deserves a downgrade to HIGH because the reachable population is materially narrower: the host must be Exim, internet-reachable, advertising STARTTLS and CHUNKING, and specifically built with GnuTLS. That is still bad enough to prioritize quickly, but it is not the same thing as 'every Exim server on TCP/25 falls over on demand.'
4 steps from start to impact.
Find an exposed Exim listener that advertises the right SMTP features
openssl s_client, swaks, or a custom SMTP client to confirm the service is Exim and that EHLO exposes STARTTLS and CHUNKING. Public exposure is common for MX hosts, but the bug is only reachable where that feature set is live. Openwall and the Exim advisory both make those prerequisites explicit.- Internet-reachable SMTP service on 25/465/587
- Exim in use
- STARTTLS and CHUNKING advertised
- Many enterprises do not expose every mail node directly to the internet
- Some Exim deployments disable or do not advertise CHUNKING
- Banner scans can see SMTP exposure but not the TLS backend
Hit the GnuTLS-only bug path with a crafted BDAT/TLS teardown sequence
close_notify mid-stream, and then follows with a final cleartext byte. Per the vendor advisory, this stale-state transition causes Exim to reuse freed memory in the BDAT receive path. XBOW's write-up shows this is not theoretical; they reached a working exploit path in their research environment.- Exim built with
USE_GNUTLS=yes - TLS session establishment succeeds
- BDAT path remains enabled
- OpenSSL-backed Exim is out of scope
- Some commercial Exim packaging, including cPanel's cited OpenSSL builds, is not affected
- A malformed SMTP/TLS sequence may crash or reset the session before reliable exploitation
exim -bV, package metadata, ldd/library linkage, and SMTP transcript testing for STARTTLS+CHUNKING.Convert the one-byte UAF into stable heap corruption
- Allocator behavior favorable enough for grooming
- Process memory protections do not fully derail reliability
- Attacker can keep interacting with the same SMTP worker/session
- ASLR, PIE, RELRO, and newer glibc integrity checks reduce reliability
- Service restarts, crashes, and worker recycling make exploit development noisy
- A public full RCE exploit was not confirmed in the primary sources reviewed
Land code execution in the Exim context and pivot
- Successful exploit reliability
- Writable or useful local post-exploitation paths
- No strong sandboxing that blocks follow-on actions
- Exim often runs as a non-root service user for much of its work
- Systemd hardening or MAC controls can limit child process execution and file writes
- A single edge MTA compromise is bad, but not automatically domain-wide compromise
exim spawning shells, curl/wget/nc, abnormal writes under spool paths, and outbound connections from the mail service account.The supporting signals.
| In-the-wild status | No confirmed active exploitation found in the reviewed primary sources as of 2026-05-30. Not in CISA KEV. |
|---|---|
| Proof-of-concept availability | XBOW published deep technical exploit analysis and states they reached a working exploit path in research conditions; a public GitHub repo exists for detection, not a confirmed full weaponized RCE release: XBOW, GitHub scanner. |
| EPSS | 0.00087 per the user-supplied intel. That is a very low predicted short-term exploitation probability, which is downward pressure on urgency but not a free pass for exposed MX hosts. |
| KEV status | Not listed in the CISA Known Exploited Vulnerabilities Catalog. No KEV add date because there is no listing. |
| CVSS vector reality check | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H is fair inside the affected slice. The overstatement is population reach: CVSS does not price in the GnuTLS-only and BDAT/CHUNKING reachable constraints. |
| Affected versions | Upstream says Exim 4.97 through 4.99.2 are affected only when compiled with USE_GNUTLS=yes; OpenSSL builds are not affected. |
| Fixed versions and backports | Upstream fix is 4.99.3. Debian tracker shows backported fixes in bullseye 4.94.2-7+deb11u5, bookworm 4.96-15+deb12u9 / +deb12u10 (security), and trixie 4.98.2-1+deb13u2 / +deb13u3 (security). |
| Exposure and scanning reality | runZero notes Exim is broadly exposed on the internet and recommends inventory queries such as product:=exim AND banner:"STARTTLS". The same source also cites a historical Shodan view of ~3.5 million exposed Exim servers, which is useful context but not a count of vulnerable GnuTLS builds. |
| Disclosure timeline | Reporter submission 2026-05-01, distro pre-notification 2026-05-07, public coordinated release 2026-05-12 per the official Exim advisory. |
| Researcher / reporting org | Federico Kirschbaum, XBOW Security received credit in the vendor advisory. |
noisgate verdict.
The decisive factor is population narrowing: exploitation is pre-auth remote, but only against the subset of Exim deployments that are internet-reachable, advertise STARTTLS+CHUNKING, and are specifically built with GnuTLS. That keeps this firmly above MEDIUM, yet below CRITICAL because the vendor score assumes universal reachability that the real deployment base does not have.
Why this verdict
- Pre-auth edge exposure is the main amplifier: if you run affected Exim on an internet-facing MX, the attacker does not need credentials, phishing, or local foothold.
- First downgrade: requires the right TLS backend. OpenSSL builds are not affected, which cuts out a meaningful chunk of real deployments and makes version-only severity inflation misleading.
- Second downgrade: requires the BDAT/CHUNKING path to be reachable. STARTTLS plus CHUNKING advertisement is a specific protocol state, not 'any TCP/25 connection.'
- Third downgrade: no active exploitation signal. No KEV listing and a very low EPSS mean there is no evidence this is already commodity mass exploitation.
- Still not lower because blast radius is real. A compromised mail edge node is a high-value foothold with mail-flow access, credential adjacency, and broad network trust.
Why not higher?
I am not keeping this at CRITICAL because the vendor's 9.8 describes the bug mechanics, not the deployment reality. The attack requires a narrower-than-CVSS population slice, and the reviewed sources do not show KEV status, broad live exploitation, or a confirmed public turnkey RCE exploit that would justify 'drop everything' treatment across every Exim asset.
Why not lower?
I am not pushing this to MEDIUM because the prerequisites are still operationally common on exposed MX infrastructure, especially Debian-family GnuTLS builds. This is unauthenticated remote memory corruption on a perimeter mail service; if your fleet matches the affected slice, the consequence of being wrong is a hostile foothold on a crown-jewel edge role.
What to do — in priority order.
- Disable CHUNKING advertisement where you can — If business testing allows it, set
chunking_advertise_hosts =to an empty value so BDAT is not advertised, removing the published trigger path. Treat this as a temporary control and deploy it within 30 days for systems that cannot be patched immediately. - Prioritize internet-facing GnuTLS-backed Exim first — Use
exim -bV, package metadata, and library linkage to separate GnuTLS from OpenSSL builds, then focus on public MX/submission servers before internal relays. This sharply cuts false positives and should be completed within 30 days. - Restrict SMTP exposure to known peers where operationally feasible — For relay-only nodes, limit inbound SMTP at the firewall/load balancer to approved upstreams so unauthenticated internet traffic cannot reach the vulnerable service. This is a practical temporary barrier and belongs in place within 30 days if patching lags.
- Harden the Exim service sandbox — Enable or tighten
NoNewPrivileges,MemoryDenyWriteExecute, file-system restrictions, and MAC policy around Exim so a successful memory-corruption exploit has a worse day after landing. This does not fix the bug, but it can reduce post-exploitation freedom; apply within 30 days. - Instrument for Exim child-process and crash telemetry — Alert on
eximspawning shells, downloaders, or unexpected outbound connections, and on crash loops during malformed SMTP sessions. This is containment-focused visibility and should be live within 30 days on exposed nodes.
- MFA or stronger SMTP auth does not help; the bug is reachable before authentication.
- A WAF is irrelevant; this is SMTP/TLS traffic, not HTTP.
- Version-only scanning is not enough; it will overcall OpenSSL-backed or backported distro builds unless you verify TLS linkage and package fix state.
- TLS inspection boxes do not reliably save you here; the vulnerable parser is on the Exim side after the protocol state machine enters the affected path.
Crowdsourced verification payload.
Run this on the target Linux mail host as root or a user who can execute exim -bV, read the Exim config, and inspect package metadata. Example: sudo bash check_cve_2026_45185.sh; it checks upstream version, Debian backport package versions when present, TLS backend, and whether CHUNKING is explicitly disabled.
#!/usr/bin/env bash
# check_cve_2026_45185.sh
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
say() { printf '%s\n' "$1"; }
find_exim() {
for p in /usr/sbin/exim4 /usr/sbin/exim /usr/local/sbin/exim; do
[ -x "$p" ] && { echo "$p"; return 0; }
done
command -v exim4 2>/dev/null && return 0
command -v exim 2>/dev/null && return 0
return 1
}
ver_ge() {
if command -v dpkg >/dev/null 2>&1; then
dpkg --compare-versions "$1" ge "$2"
else
[ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]
fi
}
ver_le() {
if command -v dpkg >/dev/null 2>&1; then
dpkg --compare-versions "$1" le "$2"
else
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
fi
}
in_range() {
ver_ge "$1" "$2" && ver_le "$1" "$3"
}
EXIM_BIN="$(find_exim || true)"
if [ -z "${EXIM_BIN:-}" ]; then
say "UNKNOWN: Exim binary not found"
exit 2
fi
BV="$($EXIM_BIN -bV 2>/dev/null || true)"
if [ -z "$BV" ]; then
say "UNKNOWN: failed to run '$EXIM_BIN -bV'"
exit 2
fi
UPSTREAM_VER="$(printf '%s\n' "$BV" | awk '/^Exim version / {print $3; exit}')"
if [ -z "$UPSTREAM_VER" ]; then
say "UNKNOWN: could not parse Exim version"
exit 2
fi
# Determine TLS backend.
TLS_BACKEND="unknown"
if printf '%s\n' "$BV" | grep -qi 'gnutls'; then
TLS_BACKEND="gnutls"
elif printf '%s\n' "$BV" | grep -qi 'openssl'; then
TLS_BACKEND="openssl"
else
if command -v ldd >/dev/null 2>&1; then
LDD_OUT="$(ldd "$EXIM_BIN" 2>/dev/null || true)"
if printf '%s\n' "$LDD_OUT" | grep -qi 'gnutls'; then
TLS_BACKEND="gnutls"
elif printf '%s\n' "$LDD_OUT" | grep -qi 'ssl\.so\|libssl'; then
TLS_BACKEND="openssl"
fi
fi
fi
# Debian package backport checks from the Debian tracker.
if command -v dpkg-query >/dev/null 2>&1; then
PKG=""
for c in exim4 exim4-daemon-light exim4-daemon-heavy; do
if dpkg-query -W -f='${Status} ${Version}\n' "$c" 2>/dev/null | grep -q 'install ok installed'; then
PKG="$c"
PKG_VER="$(dpkg-query -W -f='${Version}' "$c" 2>/dev/null)"
break
fi
done
if [ -n "$PKG" ] && [ "$TLS_BACKEND" = "gnutls" ]; then
if [[ "$PKG_VER" == *deb11u* ]] && ver_ge "$PKG_VER" "4.94.2-7+deb11u5"; then
say "PATCHED: $PKG $PKG_VER includes Debian bullseye fix for CVE-2026-45185"
exit 0
fi
if [[ "$PKG_VER" == *deb12u* ]] && ver_ge "$PKG_VER" "4.96-15+deb12u9"; then
say "PATCHED: $PKG $PKG_VER includes Debian bookworm fix for CVE-2026-45185"
exit 0
fi
if [[ "$PKG_VER" == *deb13u* ]] && ver_ge "$PKG_VER" "4.98.2-1+deb13u2"; then
say "PATCHED: $PKG $PKG_VER includes Debian trixie fix for CVE-2026-45185"
exit 0
fi
fi
fi
# If not using GnuTLS, this CVE does not apply.
if [ "$TLS_BACKEND" = "openssl" ]; then
say "PATCHED: Exim uses OpenSSL, and CVE-2026-45185 is GnuTLS-only"
exit 0
elif [ "$TLS_BACKEND" != "gnutls" ]; then
say "UNKNOWN: could not determine whether Exim uses GnuTLS or OpenSSL"
exit 2
fi
# Upstream fixed version.
if ver_ge "$UPSTREAM_VER" "4.99.3"; then
say "PATCHED: upstream Exim version $UPSTREAM_VER is >= 4.99.3"
exit 0
fi
# Advisory scope check.
if ! in_range "$UPSTREAM_VER" "4.97" "4.99.2"; then
say "PATCHED: upstream Exim version $UPSTREAM_VER is outside the published affected range 4.97-4.99.2"
exit 0
fi
# Check whether CHUNKING is explicitly disabled.
CFG_CANDIDATES="/etc/exim4/exim4.conf /etc/exim/exim.conf"
CHUNKING_DISABLED="no"
for cfg in $CFG_CANDIDATES; do
if [ -r "$cfg" ]; then
if grep -Eiq '^[[:space:]]*chunking_advertise_hosts[[:space:]]*=[[:space:]]*$' "$cfg"; then
CHUNKING_DISABLED="yes"
break
fi
fi
done
if [ "$CHUNKING_DISABLED" = "no" ] && [ -d /etc/exim4/conf.d ]; then
if grep -REiq '^[[:space:]]*chunking_advertise_hosts[[:space:]]*=[[:space:]]*$' /etc/exim4/conf.d 2>/dev/null; then
CHUNKING_DISABLED="yes"
fi
fi
if [ "$CHUNKING_DISABLED" = "yes" ]; then
say "PATCHED: affected GnuTLS build and version, but CHUNKING appears explicitly disabled, blocking the published attack path"
exit 0
fi
say "VULNERABLE: Exim $UPSTREAM_VER in affected range, GnuTLS-backed, and CHUNKING not explicitly disabled"
exit 1
If you remember one thing.
Sources
- Exim security advisory EXIM-Security-2026-05-01.1
- Openwall oss-security announcement
- NVD CVE-2026-45185
- Debian security tracker CVE-2026-45185
- XBOW technical research on Dead.Letter
- runZero Exim exposure and asset-finding guidance
- CISA Known Exploited Vulnerabilities Catalog
- Public GitHub detection script for CVE-2026-45185
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.