[prev in list] [next in list] [prev in thread] [next in thread]
List: oss-security
Subject: Re: [oss-security] Re: New SMTP smuggling attack
From: kai <kai () hostland ! ru>
Date: 2023-12-25 18:27:37
Message-ID: 32345105-4692-465c-9a1d-e668c23df18d () hostland ! ru
[Download RAW message or body]
Happy christmas list!
If anyone needs patch for postfix's 3.3.0-1ubuntu0.4
smtpd_forbid_bare_newline feature it has been attached to this message
On 24/12/2023 12.33, Marcus Meissner wrote:
> On Sat, Dec 23, 2023 at 02:29:34PM +0200, Valtteri Vuorikoski wrote:
>> On Fri, Dec 22, 2023 at 11:46:48AM +0100, Marcus Meissner wrote:
>>> Hi,
>>>
>>> FWIW as no CVEs were to be found yet, I filed a CVE request for Postfix now.
>>>
>>> Not sure if we need it for others like sendmail too, as that is also
>>> referenced by the security researchers.
>> Looks like exim opened a bug on this yesterday too, no sign of CVE yet:
>> <https://bugs.exim.org/show_bug.cgi?id=3063>
> CVEs are assigned now for:
>
> - CVE-2023-51764 postfix
> - CVE-2023-51765 sendmail
> - CVE-2023-51766 exim
>
> Ciao, Marcus
["smtp-smuggling33.patch" (text/x-patch)]
Description: Security
smtpd_forbid_bare_newline
Author: genie <mail@postfix.org>
Origin: https://www.postfix.org/smtp-smuggling.html
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: postfix-3.3.0/src/global/mail_params.h
===================================================================
--- postfix-3.3.0.orig/src/global/mail_params.h
+++ postfix-3.3.0/src/global/mail_params.h
@@ -4009,6 +4009,15 @@ extern char *var_smtp_dns_re_filter;
extern char *var_smtpd_dns_re_filter;
/*
+ * Backwards compatibility.
+ */
+#define VAR_SMTPD_FORBID_BARE_LF "smtpd_forbid_bare_newline"
+#define DEF_SMTPD_FORBID_BARE_LF 0
+
+#define VAR_SMTPD_FORBID_BARE_LF_EXCL "smtpd_forbid_bare_newline_exclusions"
+#define DEF_SMTPD_FORBID_BARE_LF_EXCL "$" VAR_MYNETWORKS
+
+ /*
* Location of shared-library files.
*
* If the files will be installed into a known directory, such as a directory
Index: postfix-3.3.0/src/global/smtp_stream.c
===================================================================
--- postfix-3.3.0.orig/src/global/smtp_stream.c
+++ postfix-3.3.0/src/global/smtp_stream.c
@@ -169,6 +169,8 @@
#include "smtp_stream.h"
+int smtp_forbid_bare_lf;
+
/* smtp_timeout_reset - reset per-stream error flags, restart deadline timer */
static void smtp_timeout_reset(VSTREAM *stream)
@@ -345,6 +347,9 @@ int smtp_get(VSTRING *vp, VSTREAM *s
*/
case '\n':
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
+ if (smtp_forbid_bare_lf
+ && (VSTRING_LEN(vp) == 0 || vstring_end(vp)[-1] != '\r'))
+ vstream_longjmp(stream, SMTP_ERR_LF);
while (VSTRING_LEN(vp) > 0 && vstring_end(vp)[-1] == '\r')
vstring_truncate(vp, VSTRING_LEN(vp) - 1);
VSTRING_TERMINATE(vp);
Index: postfix-3.3.0/src/global/smtp_stream.h
===================================================================
--- postfix-3.3.0.orig/src/global/smtp_stream.h
+++ postfix-3.3.0/src/global/smtp_stream.h
@@ -32,6 +32,7 @@
#define SMTP_ERR_QUIET 3 /* silent cleanup (application) */
#define SMTP_ERR_NONE 4 /* non-error case */
#define SMTP_ERR_DATA 5 /* application data error */
+#define SMTP_ERR_LF 6 /* bare <LF> protocol error */
extern void smtp_stream_setup(VSTREAM *, int, int);
extern void PRINTFLIKE(2, 3) smtp_printf(VSTREAM *, const char *,...);
@@ -41,6 +42,7 @@ extern int smtp_get(VSTRING *, VSTREAM *
extern void smtp_fputs(const char *, ssize_t len, VSTREAM *);
extern void smtp_fwrite(const char *, ssize_t len, VSTREAM *);
extern void smtp_fputc(int, VSTREAM *);
+extern int smtp_forbid_bare_lf;
extern void smtp_vprintf(VSTREAM *, const char *, va_list);
Index: postfix-3.3.0/src/smtpd/smtpd.c
===================================================================
--- postfix-3.3.0.orig/src/smtpd/smtpd.c
+++ postfix-3.3.0/src/smtpd/smtpd.c
@@ -1416,6 +1416,10 @@ char *var_tlsproxy_service;
char *var_smtpd_uproxy_proto;
int var_smtpd_uproxy_tmout;
+bool var_smtpd_forbid_bare_lf;
+char *var_smtpd_forbid_bare_lf_excl;
+static NAMADR_LIST *bare_lf_excl;
+
/*
* Silly little macros.
*/
@@ -1490,6 +1494,7 @@ static void tls_reset(SMTPD_STATE *);
#define REASON_TIMEOUT "timeout"
#define REASON_LOST_CONNECTION "lost connection"
#define REASON_ERROR_LIMIT "too many errors"
+#define REASON_BARE_LF "bare <LF> received"
#ifdef USE_TLS
@@ -4156,6 +4161,9 @@ static int xclient_cmd(SMTPD_STATE *stat
*/
xclient_allowed =
namadr_list_match(xclient_hosts, state->name, state->addr);
+ smtp_forbid_bare_lf = SMTPD_STAND_ALONE((state)) == 0
+ && var_smtpd_forbid_bare_lf
+ && !namadr_list_match(bare_lf_excl, state->name, state->addr);
/* NOT: tls_reset() */
if (got_helo == 0)
helo_reset(state);
@@ -4936,6 +4944,13 @@ static void smtpd_proto(SMTPD_STATE *sta
var_myhostname);
break;
+ case SMTP_ERR_LF:
+ state->reason = REASON_BARE_LF;
+ if (vstream_setjmp(state->client) == 0)
+ smtpd_chat_reply(state, "521 5.5.2 %s Error: bare <LF> received",
+ var_myhostname);
+ break;
+
case 0:
/*
@@ -5461,6 +5476,13 @@ static void smtpd_service(VSTREAM *strea
namadr_list_match(xforward_hosts, state.name, state.addr);
/*
+ * Enforce strict SMTP line endings, with compatibility exclusions.
+ */
+ smtp_forbid_bare_lf = SMTPD_STAND_ALONE((&state)) == 0
+ && var_smtpd_forbid_bare_lf
+ && !namadr_list_match(bare_lf_excl, state.name, state.addr);
+
+ /*
* See if we need to turn on verbose logging for this client.
*/
debug_peer_check(state.name, state.addr);
@@ -5522,10 +5544,14 @@ static void pre_jail_init(char *unused_n
hogger_list = namadr_list_init(VAR_SMTPD_HOGGERS, MATCH_FLAG_RETURN
| match_parent_style(VAR_SMTPD_HOGGERS),
var_smtpd_hoggers);
+ bare_lf_excl = namadr_list_init(VAR_SMTPD_FORBID_BARE_LF_EXCL,
+ MATCH_FLAG_RETURN
+ | match_parent_style(VAR_MYNETWORKS),
+ var_smtpd_forbid_bare_lf_excl);
/*
* Open maps before dropping privileges so we can read passwords etc.
- *
+ *
* XXX We should not do this in stand-alone (sendmail -bs) mode, but we
* can't use SMTPD_STAND_ALONE(state) here. This means "sendmail -bs"
* will try to connect to proxymap when invoked by root for mail
@@ -5850,6 +5876,7 @@ int main(int argc, char **argv)
VAR_SMTPD_PEERNAME_LOOKUP, DEF_SMTPD_PEERNAME_LOOKUP, &var_smtpd_peername_lookup,
VAR_SMTPD_DELAY_OPEN, DEF_SMTPD_DELAY_OPEN, &var_smtpd_delay_open,
VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log,
+ VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &var_smtpd_forbid_bare_lf,
0,
};
static const CONFIG_NBOOL_TABLE nbool_table[] = {
@@ -5960,6 +5987,7 @@ int main(int argc, char **argv)
VAR_SMTPD_POLICY_DEF_ACTION, DEF_SMTPD_POLICY_DEF_ACTION, &var_smtpd_policy_def_action, 1, 0,
VAR_SMTPD_POLICY_CONTEXT, DEF_SMTPD_POLICY_CONTEXT, &var_smtpd_policy_context, 0, 0,
VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 0,
+ VAR_SMTPD_FORBID_BARE_LF_EXCL, DEF_SMTPD_FORBID_BARE_LF_EXCL, &var_smtpd_forbid_bare_lf_excl, 0, 0,
0,
};
static const CONFIG_RAW_TABLE raw_table[] = {
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic