From: Philippe Antoine Date: Mon, 25 Apr 2022 06:23:53 +0000 (+0200) Subject: protocol-change: sets event in case of failure X-Git-Tag: suricata-7.0.0-beta1~283 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=11f849c3ee7ef9c02c36a0fcf9ed26f7fc32bc70;p=thirdparty%2Fsuricata.git protocol-change: sets event in case of failure Protocol change can fail if one protocol change is already occuring. Ticket: #5509 --- diff --git a/rules/http-events.rules b/rules/http-events.rules index dbdf523f52..6376c807fc 100644 --- a/rules/http-events.rules +++ b/rules/http-events.rules @@ -87,4 +87,6 @@ alert http any any -> any any (msg:"SURICATA HTTP invalid Range header value"; f alert http any any -> any any (msg:"SURICATA HTTP file name too long"; flow:established; app-layer-event:http.file_name_too_long; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2221052; rev:1;) -# next sid 2221053 +alert http any any -> any any (msg:"SURICATA HTTP failed protocol change"; flow:established; app-layer-event:http.failed_protocol_change; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2221053; rev:1;) + +# next sid 2221054 diff --git a/rules/smtp-events.rules b/rules/smtp-events.rules index cc7eedcbbf..135b84c629 100644 --- a/rules/smtp-events.rules +++ b/rules/smtp-events.rules @@ -30,4 +30,5 @@ alert smtp any any -> any any (msg:"SURICATA SMTP Mime boundary length exceeded" alert smtp any any -> any any (msg:"SURICATA SMTP duplicate fields"; flow:established,to_server; app-layer-event:smtp.duplicate_fields; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220018; rev:1;) 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;) -# next sid 2220021 +alert smtp any any -> any any (msg:"SURICATA SMTP failed protocol change"; flow:established; app-layer-event:smtp.failed_protocol_change; flowint:smtp.anomaly.count,+,1; classtype:protocol-command-decode; sid:2220021; rev:1;) +# next sid 2220022 diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 642172a518..a08741b02b 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -388,7 +388,7 @@ extern { pp_min_depth: u16, pp_max_depth: u16) -> c_int; pub fn AppLayerProtoDetectConfProtoDetectionEnabled(ipproto: *const c_char, proto: *const c_char) -> c_int; pub fn AppLayerProtoDetectConfProtoDetectionEnabledDefault(ipproto: *const c_char, proto: *const c_char, default: bool) -> c_int; - pub fn AppLayerRequestProtocolTLSUpgrade(flow: *const Flow); + pub fn AppLayerRequestProtocolTLSUpgrade(flow: *const Flow) -> bool; } // Defined in app-layer-parser.h diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 3971291245..638bd1b983 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -1958,13 +1958,13 @@ void AppLayerProtoDetectRegisterAlias(const char *proto_name, const char *proto_ * \param expect_proto expected protocol. AppLayer event will be set if * detected protocol differs from this. */ -void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto) +bool AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto) { if (FlowChangeProto(f)) { // If we are already changing protocols, from SMTP to TLS for instance, // and that we do not get TLS but HTTP1, which is requesting whange to HTTP2, // we do not proceed the new protocol change - return; + return false; } FlowSetChangeProtoFlag(f); f->protodetect_dp = dp; @@ -1978,6 +1978,7 @@ void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto) if (f->alproto_tc == ALPROTO_UNKNOWN) { f->alproto_tc = f->alproto; } + return true; } /** \brief request applayer to wrap up this protocol and rerun protocol @@ -1988,9 +1989,9 @@ void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto) * * \param f flow to act on */ -void AppLayerRequestProtocolTLSUpgrade(Flow *f) +bool AppLayerRequestProtocolTLSUpgrade(Flow *f) { - AppLayerRequestProtocolChange(f, 443, ALPROTO_TLS); + return AppLayerRequestProtocolChange(f, 443, ALPROTO_TLS); } void AppLayerProtoDetectReset(Flow *f) diff --git a/src/app-layer-detect-proto.h b/src/app-layer-detect-proto.h index cf9b5e2506..7d1430d541 100644 --- a/src/app-layer-detect-proto.h +++ b/src/app-layer-detect-proto.h @@ -115,8 +115,8 @@ int AppLayerProtoDetectSetup(void); */ void AppLayerProtoDetectReset(Flow *); -void AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto); -void AppLayerRequestProtocolTLSUpgrade(Flow *f); +bool AppLayerRequestProtocolChange(Flow *f, uint16_t dp, AppProto expect_proto); +bool AppLayerRequestProtocolTLSUpgrade(Flow *f); /** * \brief Cleans up the app layer protocol detection phase. diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index cfe1302bb8..c46d8c7fbc 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -172,6 +172,7 @@ SCEnumCharMap http_decoder_event_table[] = { { "MULTIPART_INVALID_HEADER", HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER }, { "TOO_MANY_WARNINGS", HTTP_DECODER_EVENT_TOO_MANY_WARNINGS }, + { "FAILED_PROTOCOL_CHANGE", HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE }, { NULL, -1 }, }; @@ -968,7 +969,10 @@ static AppLayerResult HTPHandleResponseData(Flow *f, void *htp_state, AppLayerPa } consumed = htp_connp_res_data_consumed(hstate->connp); hstate->slice = NULL; - AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_HTTP2); + if (!AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_HTTP2)) { + HTPSetEvent(hstate, NULL, STREAM_TOCLIENT, + HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE); + } // During HTTP2 upgrade, we may consume the HTTP1 part of the data // and we need to parser the remaining part with HTTP2 if (consumed > 0 && consumed < input_len) { @@ -2282,7 +2286,10 @@ static int HTPCallbackResponseComplete(htp_tx_t *tx) dp = (uint16_t)tx->request_port_number; } // both ALPROTO_HTTP1 and ALPROTO_TLS are normal options - AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_UNKNOWN); + if (!AppLayerRequestProtocolChange(hstate->f, dp, ALPROTO_UNKNOWN)) { + HTPSetEvent( + hstate, htud, STREAM_TOCLIENT, HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE); + } tx->request_progress = HTP_REQUEST_COMPLETE; tx->response_progress = HTP_RESPONSE_COMPLETE; } diff --git a/src/app-layer-htp.h b/src/app-layer-htp.h index 7f2389213c..c8ad371765 100644 --- a/src/app-layer-htp.h +++ b/src/app-layer-htp.h @@ -139,6 +139,8 @@ enum { HTTP_DECODER_EVENT_MULTIPART_INVALID_HEADER, HTTP_DECODER_EVENT_TOO_MANY_WARNINGS, + + HTTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE, }; typedef enum HtpSwfCompressType_ { diff --git a/src/app-layer-smtp.c b/src/app-layer-smtp.c index 449dd30298..787a6a76f1 100644 --- a/src/app-layer-smtp.c +++ b/src/app-layer-smtp.c @@ -145,6 +145,7 @@ SCEnumCharMap smtp_decoder_event_table[] = { { "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 }, + { "FAILED_PROTOCOL_CHANGE", SMTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE }, /* MIME Events */ { "MIME_PARSE_FAILED", SMTP_DECODER_EVENT_MIME_PARSE_FAILED }, @@ -944,7 +945,9 @@ static int SMTPProcessReply(SMTPState *state, Flow *f, AppLayerParserState *psta if (reply_code == SMTP_REPLY_220) { /* we are entering STARRTTLS data mode */ state->parser_state |= SMTP_PARSER_STATE_COMMAND_DATA_MODE; - AppLayerRequestProtocolTLSUpgrade(f); + if (!AppLayerRequestProtocolTLSUpgrade(f)) { + SMTPSetEvent(state, SMTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE); + } if (state->curr_tx) { SMTPTransactionComplete(state); } diff --git a/src/app-layer-smtp.h b/src/app-layer-smtp.h index af6550b560..f7f983b7ee 100644 --- a/src/app-layer-smtp.h +++ b/src/app-layer-smtp.h @@ -38,6 +38,7 @@ enum { SMTP_DECODER_EVENT_NO_SERVER_WELCOME_MESSAGE, SMTP_DECODER_EVENT_TLS_REJECTED, SMTP_DECODER_EVENT_DATA_COMMAND_REJECTED, + SMTP_DECODER_EVENT_FAILED_PROTOCOL_CHANGE, /* MIME Events */ SMTP_DECODER_EVENT_MIME_PARSE_FAILED,