diff --git a/rules/smtp-events.rules b/rules/smtp-events.rules index e641e98037..ade39d81ab 100644 --- a/rules/smtp-events.rules +++ b/rules/smtp-events.rules @@ -31,4 +31,6 @@ alert smtp any any -> any any (msg:"SURICATA SMTP duplicate fields"; flow:establ 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;) 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;) 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;) -# next sid 2220022 +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;) + +# next sid 2220023 diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index c234523f53..937d477442 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -132,6 +132,7 @@ SCEnumCharMap smtp_decoder_event_table[] = { { "MAX_REPLY_LINE_LEN_EXCEEDED", SMTP_DECODER_EVENT_MAX_REPLY_LINE_LEN_EXCEEDED }, { "INVALID_PIPELINED_SEQUENCE", SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE }, { "BDAT_CHUNK_LEN_EXCEEDED", SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED }, + { "INVALID_BDAT", SMTP_DECODER_EVENT_INVALID_BDAT }, { "NO_SERVER_WELCOME_MESSAGE", SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE }, { "TLS_REJECTED", SMTP_DECODER_EVENT_TLS_REJECTED }, { "DATA_COMMAND_REJECTED", SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED }, @@ -1393,14 +1394,19 @@ static int SMTPProcessRequest( bool last = false; r = SMTPParseCommandBDAT(state, line, &last); if (r == -1) { - SCReturnInt(-1); - } - state->current_command = last ? SMTP_COMMAND_BDAT_LAST : SMTP_COMMAND_BDAT; - SMTPSetProgressTS(tx, SMTP_REQUEST_DATA); - if (state->bdat_chunk_len > 0) { - state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE; - } else if (last) { - SMTPTransactionCompleteTS(tx); + /* Invalid BDAT syntax is recoverable: the server rejects the + * command and the session continues. */ + SMTPSetEvent(state, SMTP_DECODER_EVENT_INVALID_BDAT); + state->current_command = SMTP_COMMAND_OTHER_CMD; + r = 0; + } else { + state->current_command = last ? SMTP_COMMAND_BDAT_LAST : SMTP_COMMAND_BDAT; + SMTPSetProgressTS(tx, SMTP_REQUEST_DATA); + if (state->bdat_chunk_len > 0) { + state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE; + } else if (last) { + SMTPTransactionCompleteTS(tx); + } } } else if (line->len >= 4 && ((SCMemcmpLowercase("helo", line->buf, 4) == 0) || SCMemcmpLowercase("ehlo", line->buf, 4) == 0)) { diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index e45dd66c87..d6e8a7fd1a 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -39,6 +39,7 @@ enum { SMTP_DECODER_EVENT_MAX_REPLY_LINE_LEN_EXCEEDED, SMTP_DECODER_EVENT_INVALID_PIPELINED_SEQUENCE, SMTP_DECODER_EVENT_BDAT_CHUNK_LEN_EXCEEDED, + SMTP_DECODER_EVENT_INVALID_BDAT, SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE, SMTP_DECODER_EVENT_TLS_REJECTED, SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED,