Skip to content

Commit 0fbec65

Browse files
committed
smtp: recover from invalid BDAT command syntax
A BDAT command that failed to parse, such as "BDAT 5 X", returned -1, disabling SMTP parsing for the rest of the flow. A server may reject the command and continue the session, leaving following messages uninspected. Instead raise a decoder event and queue the command as an ordinary command. Ticket: OISF#8741
1 parent e03cb0f commit 0fbec65

3 files changed

Lines changed: 18 additions & 9 deletions

File tree

rules/smtp-events.rules

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ alert smtp any any -> any any (msg:"SURICATA SMTP duplicate fields"; flow:establ
3131
alert smtp any any -> any any (msg:"SURICATA SMTP unparsable content"; flow:established,to_server; app-layer-event:smtp.unparsable_content; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220019; rev:1;)
3232
alert smtp any any -> any any (msg:"SURICATA SMTP filename truncated"; flow:established,to_server; app-layer-event:smtp.mime_long_filename; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220020; rev:1;)
3333
alert smtp any any -> any any (msg:"SURICATA SMTP failed protocol change"; flow:established,to_client; app-layer-event:smtp.failed_protocol_change; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220021; rev:2;)
34-
# next sid 2220022
34+
alert smtp any any -> any any (msg:"SURICATA SMTP invalid BDAT command"; flow:established,to_server; app-layer-event:smtp.invalid_bdat; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220022; rev:1;)
35+
36+
# next sid 2220023

src/app-layer-smtp.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ SCEnumCharMap smtp_decoder_event_table[] = {
132132
{ "MAX_REPLY_LINE_LEN_EXCEEDED", SMTP_DECODER_EVENT_MAX_REPLY_LINE_LEN_EXCEEDED },
133133
{ "INVALID_PIPELINED_SEQUENCE", SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE },
134134
{ "BDAT_CHUNK_LEN_EXCEEDED", SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED },
135+
{ "INVALID_BDAT", SMTP_DECODER_EVENT_INVALID_BDAT },
135136
{ "NO_SERVER_WELCOME_MESSAGE", SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE },
136137
{ "TLS_REJECTED", SMTP_DECODER_EVENT_TLS_REJECTED },
137138
{ "DATA_COMMAND_REJECTED", SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED },
@@ -1393,14 +1394,19 @@ static int SMTPProcessRequest(
13931394
bool last = false;
13941395
r = SMTPParseCommandBDAT(state, line, &last);
13951396
if (r == -1) {
1396-
SCReturnInt(-1);
1397-
}
1398-
state->current_command = last ? SMTP_COMMAND_BDAT_LAST : SMTP_COMMAND_BDAT;
1399-
SMTPSetProgressTS(tx, SMTP_REQUEST_DATA);
1400-
if (state->bdat_chunk_len > 0) {
1401-
state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE;
1402-
} else if (last) {
1403-
SMTPTransactionCompleteTS(tx);
1397+
/* Invalid BDAT syntax is recoverable: the server rejects the
1398+
* command and the session continues. */
1399+
SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_BDAT);
1400+
state->current_command = SMTP_COMMAND_OTHER_CMD;
1401+
r = 0;
1402+
} else {
1403+
state->current_command = last ? SMTP_COMMAND_BDAT_LAST : SMTP_COMMAND_BDAT;
1404+
SMTPSetProgressTS(tx, SMTP_REQUEST_DATA);
1405+
if (state->bdat_chunk_len > 0) {
1406+
state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE;
1407+
} else if (last) {
1408+
SMTPTransactionCompleteTS(tx);
1409+
}
14041410
}
14051411
} else if (line->len >= 4 && ((SCMemcmpLowercase("helo", line->buf, 4) == 0) ||
14061412
SCMemcmpLowercase("ehlo", line->buf, 4) == 0)) {

src/app-layer-smtp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum {
3939
SMTP_DECODER_EVENT_MAX_REPLY_LINE_LEN_EXCEEDED,
4040
SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE,
4141
SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED,
42+
SMTP_DECODER_EVENT_INVALID_BDAT,
4243
SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE,
4344
SMTP_DECODER_EVENT_TLS_REJECTED,
4445
SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED,

0 commit comments

Comments
 (0)