SMTP Smuggling
References
- Article SMTP Smuggling - Spoofing E-Mails Worldwide by Timo Longin
- Presentation SMTP Smuggling – Spoofing E-Mails Worldwide by Timo Longin
- smtpsmuggling.com by Timo Longin
- SMTP-Smuggling-Tools by Timo Longin
- smtpsmug by Hanno Böck
- SMTP Smuggling by Postfix
- Bare LFs in SMTP by djb
- smtpd smuggling on openbsd-tech
- Postfix CVE-2023-51764 nvd ubuntu
- Sendmail CVE-2023-51765 nvd ubuntu debian
- Exim CVE-2023-51766 nvd ubuntu
- [oss-security] New SMTP smuggling attack
- Sendmail Configuration Files by Eric Allman and Sendmail
- Configuring a Sendmail Client from Oracle Linux 6 Administrator’s Guide
- Email agent (infrastructure) wiki jargon descriptions
Inbound Testing
Postfix, Sendmail, and Exim are all affected by the inbound direction (i.e., mail that a server is receiving and parsing).
Testing Sendmail
Install sendmail on a test machine with a FQDN:
$ cat /etc/hosts
127.0.0.1 victim.lan victim
127.0.1.1 victim
$ cat /etc/hostname
victim.lan
Verify that emails can be sent to a local user (eslerm):
$ telnet localhost smtp
helo victim.lan
mail from: root@victim.lan
rcpt to: eslerm@victim.lan
data
Subject: local test
foo
.
Check mail of the local user.
Now run SMTP-Smuggling-Tools.
git clone https://github.com/The-Login/SMTP-Smuggling-Tools.git
cd SMTP-Smuggling-Tools/
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
python3 smtp_smuggling_scanner.py --setup-check --inbound-smtp-server victim.lan eslerm@victim.lan
python3 smtp_smuggling_scanner.py --inbound-smtp-server victim.lan eslerm@victim.lan
If sendmail is vulnerable you will see:
(.venv) eslerm@victim:~/SMTP-Smuggling-Tools$ mail
"/var/mail/eslerm": 11 messages 1 new 10 unread
>U 1 mark@markesler.com Thu Feb 29 23:21 13/411 local test
N 2 setup_check@check. Thu Feb 29 23:22 11/523 SETUP CHECK
N 3 test@check.smtpsmu Thu Feb 29 23:22 13/505 CHECK EMAIL ('\n.\n')
N 4 smuggled@check.smt Thu Feb 29 23:22 13/529 SMUGGLED EMAIL ('\n.\n')
N 5 test@check.smtpsmu Thu Feb 29 23:22 25/856 CHECK EMAIL ('\n.\r')
N 6 test@check.smtpsmu Thu Feb 29 23:22 25/858 CHECK EMAIL ('\r.\n')
N 7 test@check.smtpsmu Thu Feb 29 23:22 24/858 CHECK EMAIL ('\r.\r')
N 8 test@check.smtpsmu Thu Feb 29 23:22 13/509 CHECK EMAIL ('\n.\r\n')
N 9 smuggled@check.smt Thu Feb 29 23:22 13/532 SMUGGLED EMAIL ('\n.\r\n')
N 10 test@check.smtpsmu Thu Feb 29 23:23 25/866 CHECK EMAIL ('\r.\r\n')
N 11 test@check.smtpsmu Thu Feb 29 23:23 26/892 CHECK EMAIL ('\r\n\x00.\r\n')
Postfix < 3.9 is affected by default
Postfix is vulnerable unless the following non-default configs are set:
smtpd_forbid_bare_newline = normalize
smtpd_forbid_bare_newline_exclusions = $mynetworks
(for local testing, you must explicitly set smtpd_forbid_bare_newline_exclusions = )
NUL and other Control Characters
As per RFC 5321 section 4.1.1.4, MTAs need to strip control characters other than <SP>, <HT>, <CR>, and <LF> to be RFC compliant.
e.g., \r\n\x00.\r\n SHOULD become \r\n.\r\n and then (as per RFC 5321 section 4.5.2) dot-stuff the “forbidden” sequences.
As per RFC 2119 section 3, SHOULD implies MUST unless you have a valid reason not to–which is never the case for these “forbidden” sequences. This is why RFC 5321 4.1.1.4’s “SHOULD avoid” implies “needs to strip”.
Also note that RFC 5321 section 3.6.3 and 6.4 is about adding missing information.
Cheers to Pete Resnick for this clarification and explanation.
Other
Likely worth more fuzzing per RFC 5321 warnings and history.
Overly restrictive filters in a patch can cause emails to be dropped: a major regressions.