🦊

SMTP Smuggling

References

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: [email protected]
rcpt to: [email protected]
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 [email protected]
python3 smtp_smuggling_scanner.py --inbound-smtp-server victim.lan [email protected]

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 [email protected] 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 [email protected] Thu Feb  29 23:22  13/505   CHECK EMAIL ('\n.\n')
 N   4 [email protected] Thu Feb  29 23:22  13/529   SMUGGLED EMAIL ('\n.\n')
 N   5 [email protected] Thu Feb  29 23:22  25/856   CHECK EMAIL ('\n.\r')
 N   6 [email protected] Thu Feb  29 23:22  25/858   CHECK EMAIL ('\r.\n')
 N   7 [email protected] Thu Feb  29 23:22  24/858   CHECK EMAIL ('\r.\r')
 N   8 [email protected] Thu Feb  29 23:22  13/509   CHECK EMAIL ('\n.\r\n')
 N   9 [email protected] Thu Feb  29 23:22  13/532   SMUGGLED EMAIL ('\n.\r\n')
 N  10 [email protected] Thu Feb  29 23:23  25/866   CHECK EMAIL ('\r.\r\n')
 N  11 [email protected] 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.