smtp-smuggling.md (9454B)
1 --- 2 title: "SMTP Smuggling" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-smtp/smtp-smuggling.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-smtp/smtp-smuggling.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # SMTP Smuggling 14 15 ## Basic Information 16 17 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.<sup>[[1]](#references)[[7]](#references)</sup> 18 19 ### Why 20 21 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:<sup>[[1]](#references)</sup> 22 23 <figure><img src="https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%288%29%20%281%29%20%281%29%20%281%29%20%281%29.png" alt=""><figcaption><p><a href="https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png">https://sec-consult.com/fileadmin/user_upload/sec-consult/Dynamisch/Blogartikel/2023_12/SMTP_Smuggling-Overview__09_.png</a></p></figcaption></figure> 24 25 ### How 26 27 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**. 28 29 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.<sup>[[1]](#references)[[7]](#references)</sup> 30 31 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.<sup>[[1]](#references)</sup> 32 33 Potential desynchronization data: 34 35 - `\n.` 36 - `\n.\r` 37 38 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.<sup>[[1]](#references)</sup> 39 40 --- 41 42 ## Attacker’s checklist (what conditions must hold?) 43 44 To successfully smuggle a second email, you typically need:<sup>[[1]](#references)</sup> 45 46 - 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`. 47 - 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...). 48 - 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. 49 - PIPELINING isn’t required but helps hiding the injected commands in a single TCP write so intermediate devices don’t resynchronize. 50 51 Common end‑of‑DATA variants worth testing (receiver-dependent): 52 53 - `\n.\n` 54 - `\n.\r\n` 55 - `\r.\r\n` 56 - `\r\n.\r` (bare CR at end) 57 58 Note: What works is the intersection of “what A forwards” ∩ “what B accepts”. 59 60 --- 61 62 ## Schematic Single-Session Example 63 64 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.<sup>[[1]](#references)</sup> 65 66 <details> 67 <summary>Manual smuggling session (STARTTLS)</summary> 68 69 ```text 70 $ openssl s_client -starttls smtp -quiet -connect smtp.example.com:587 < payload.bin 71 EHLO a.example 72 AUTH PLAIN <base64(\0user@example.com\0password)> 73 MAIL FROM:<user@example.com> 74 RCPT TO:<victim@target.com> 75 DATA 76 From: User <user@example.com> 77 To: victim <victim@target.com> 78 Subject: legit 79 80 hello A 81 \n.\r\nMAIL FROM:<admin@target.com> 82 RCPT TO:<victim@target.com> 83 DATA 84 From: Admin <admin@target.com> 85 To: victim <victim@target.com> 86 Subject: smuggled 87 88 hello B 89 \r\n.\r\n 90 ``` 91 92 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). 93 </details> 94 95 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. 96 97 --- 98 99 ## Automation and scanners 100 101 - hannob/smtpsmug: send a message ending with multiple malformed end‑of‑DATA sequences to see what a receiver accepts.<sup>[[3]](#references)</sup> 102 - Example: `./smtpsmug -s mail.target.com -p 25 -t victim@target.com` 103 - 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.<sup>[[4]](#references)</sup> 104 - Inbound quick check: `python3 smtp_smuggling_scanner.py victim@target.com` 105 - 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 '...' 106 ` 107 108 These tools help you map the A→B pairs where smuggling actually works. 109 110 --- 111 112 ## CHUNKING/BDAT vs DATA 113 114 - DATA uses a sentinel terminator `<CR><LF>.<CR><LF>`; any ambiguity in how CR/LF are normalized or dot‑stuffed leads to desync. 115 - 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.<sup>[[1]](#references)</sup> 116 117 --- 118 119 ## Notes on affected software and fixes (for targeting) 120 121 - 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.<sup>[[2]](#references)</sup> 122 - 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.<sup>[[5]](#references)</sup> 123 - 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.<sup>[[6]](#references)[[8]](#references)</sup> 124 - 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>`. 125 126 Use the scanners above to verify current behavior; many vendors changed defaults in early 2024–2025. 127 128 --- 129 130 ## Tips for red team ops 131 132 - 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. 133 - 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. 134 - 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). 135 136 --- 137 138 ## References 139 140 - [1] [SMTP Smuggling - Spoofing E-Mails Worldwide](https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/) 141 - [2] [Postfix - SMTP smuggling](https://www.postfix.org/smtp-smuggling.html) 142 - [3] [hannob/smtpsmug - SMTP smuggling test tool](https://github.com/hannob/smtpsmug) 143 - [4] [The-Login/SMTP-Smuggling-Tools](https://github.com/The-Login/SMTP-Smuggling-Tools) 144 - [5] [Exim CVE-2023-51766 advisory](https://www.openwall.com/lists/oss-security/2023/12/29/2) 145 - [6] [Sendmail 8.18.1 release announcement and notes](https://groups.google.com/g/comp.mail.sendmail/c/4x_vDXdJABE) 146 - [7] [RFC 5321 - Simple Mail Transfer Protocol](https://www.rfc-editor.org/rfc/rfc5321.html) 147 - [8] [NVD - CVE-2023-51765](https://nvd.nist.gov/vuln/detail/CVE-2023-51765)