From: Tom Peters (thopeter) Date: Tue, 2 Nov 2021 17:21:33 +0000 (+0000) Subject: Pull request #3130: ssl: disable inspection on alert only at fatal level X-Git-Tag: 3.1.16.0~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e74250a85ba98dd98e29d530f97c114fc6ece808;p=thirdparty%2Fsnort3.git Pull request #3130: ssl: disable inspection on alert only at fatal level Merge in SNORT/snort3 from ~SBAIGAL/snort3:ssl_alert_fix to master Squashed commit of the following: commit fc567298456a798da12318c18c78c35f69cf868e Author: Steven Baigal (sbaigal) Date: Mon Oct 25 09:44:11 2021 -0400 ssl: disable inspection on alert only at fatal level remove SO_PUBLIC from SSL_decode, since it is only called from inside snort --- diff --git a/src/protocols/ssl.cc b/src/protocols/ssl.cc index b1c01c864..aff3a3717 100644 --- a/src/protocols/ssl.cc +++ b/src/protocols/ssl.cc @@ -190,7 +190,7 @@ static uint32_t SSL_decode_handshake_v3(const uint8_t* pkt, int size, } static uint32_t SSL_decode_v3(const uint8_t* pkt, int size, uint32_t pkt_flags, - uint8_t* alert_flags, uint16_t* partial_rec_len, int max_hb_len) + uint8_t* alert_flags, uint16_t* partial_rec_len, int max_hb_len, uint32_t* info_flags) { uint32_t retval = 0; uint16_t hblen; @@ -245,6 +245,12 @@ static uint32_t SSL_decode_v3(const uint8_t* pkt, int size, uint32_t pkt_flags, break; case SSL_ALERT_REC: + if (reclen == sizeof(SSL_alert_t)) + { + const SSL_alert_t* ssl_alert = (const SSL_alert_t*)pkt; + if (ssl_alert->level == SSL_ALERT_LEVEL_FATAL && info_flags) + *info_flags |= SSL_ALERT_LVL_FATAL_FLAG; + } retval |= SSL_ALERT_FLAG; ccs = 0; break; @@ -421,7 +427,7 @@ namespace snort { uint32_t SSL_decode( const uint8_t* pkt, int size, uint32_t pkt_flags, uint32_t prev_flags, - uint8_t* alert_flags, uint16_t* partial_rec_len, int max_hb_len) + uint8_t* alert_flags, uint16_t* partial_rec_len, int max_hb_len, uint32_t* info_flags) { if (!pkt || !size) return SSL_ARG_ERROR_FLAG; @@ -442,7 +448,7 @@ uint32_t SSL_decode( * SSLv2 as TLS,the decoder will either catch a bad type, bad version, or * indicate that it is truncated. */ if (size == 5) - return SSL_decode_v3(pkt, size, pkt_flags, alert_flags, partial_rec_len, max_hb_len); + return SSL_decode_v3(pkt, size, pkt_flags, alert_flags, partial_rec_len, max_hb_len, info_flags); /* At this point, 'size' has to be > 5 */ @@ -489,7 +495,7 @@ uint32_t SSL_decode( } } - return SSL_decode_v3(pkt, size, pkt_flags, alert_flags, partial_rec_len, max_hb_len); + return SSL_decode_v3(pkt, size, pkt_flags, alert_flags, partial_rec_len, max_hb_len, info_flags); } /* very simplistic - just enough to say this is binary data - the rules will make a final @@ -540,7 +546,7 @@ bool IsTlsServerHello(const uint8_t* ptr, const uint8_t* end) bool IsSSL(const uint8_t* ptr, int len, int pkt_flags) { - uint32_t ssl_flags = SSL_decode(ptr, len, pkt_flags, 0, nullptr, nullptr, 0); + uint32_t ssl_flags = SSL_decode(ptr, len, pkt_flags, 0, nullptr, nullptr, 0, nullptr); if ((ssl_flags != SSL_ARG_ERROR_FLAG) && !(ssl_flags & SSL_ERROR_FLAGS)) diff --git a/src/protocols/ssl.h b/src/protocols/ssl.h index 9efb34c53..03ca5c956 100644 --- a/src/protocols/ssl.h +++ b/src/protocols/ssl.h @@ -94,6 +94,9 @@ * #define SSL_HS_FINISHED_FLAG Ignored for our purposes */ +/* Flags for additional info */ +#define SSL_ALERT_LVL_FATAL_FLAG 0x00000001 + /* The constants used below are from RFC 2246 */ /* SSLv3 & TLS Record types */ @@ -138,6 +141,15 @@ struct SSL_record_t #define SSL_REC_PAYLOAD_OFFSET (sizeof(uint8_t) * 5) +#define SSL_ALERT_LEVEL_WARNING 1 +#define SSL_ALERT_LEVEL_FATAL 2 + +struct SSL_alert_t +{ + uint8_t level; + uint8_t description; +}; + struct SSL_heartbeat { uint8_t type; @@ -215,9 +227,9 @@ struct SSLv2_shello_t namespace snort { -SO_PUBLIC uint32_t SSL_decode( +uint32_t SSL_decode( const uint8_t* pkt, int size, uint32_t pktflags, uint32_t prevflags, - uint8_t* alert_flags, uint16_t* partial_rec_len, int hblen); + uint8_t* alert_flags, uint16_t* partial_rec_len, int hblen, uint32_t* info_flags = nullptr); SO_PUBLIC bool IsTlsClientHello(const uint8_t* ptr, const uint8_t* end); SO_PUBLIC bool IsTlsServerHello(const uint8_t* ptr, const uint8_t* end); diff --git a/src/service_inspectors/ssl/ssl_inspector.cc b/src/service_inspectors/ssl/ssl_inspector.cc index 44fc7ba8e..fcdf2e9c8 100644 --- a/src/service_inspectors/ssl/ssl_inspector.cc +++ b/src/service_inspectors/ssl/ssl_inspector.cc @@ -169,7 +169,7 @@ static inline bool SSLPP_is_encrypted(SSL_PROTO_CONF* config, uint32_t ssl_flags } static inline uint32_t SSLPP_process_alert( - SSL_PROTO_CONF*, uint32_t ssn_flags, uint32_t new_flags, Packet* packet) + SSL_PROTO_CONF*, uint32_t ssn_flags, uint32_t new_flags, Packet* packet, uint32_t info_flags) { ssn_flags |= new_flags; @@ -178,7 +178,8 @@ static inline uint32_t SSLPP_process_alert( if (SSL_IS_HANDSHAKE(ssn_flags) && !SSL_IS_HANDSHAKE(new_flags) && !(new_flags & SSL_CHANGE_CIPHER_FLAG) && - !(new_flags & SSL_HEARTBEAT_SEEN)) + !(new_flags & SSL_HEARTBEAT_SEEN) && + info_flags & SSL_ALERT_LVL_FATAL_FLAG) { DetectionEngine::disable_content(packet); sslstats.disabled++; @@ -298,8 +299,9 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) uint8_t index = (p->packet_flags & PKT_REBUILT_STREAM) ? 2 : 0; uint8_t heartbleed_type = 0; + uint32_t info_flags = 0; uint32_t new_flags = SSL_decode(p->data, (int)p->dsize, p->packet_flags, sd->ssn_flags, - &heartbleed_type, &(sd->partial_rec_len[dir+index]), config->max_heartbeat_len); + &heartbleed_type, &(sd->partial_rec_len[dir+index]), config->max_heartbeat_len, &info_flags); if (heartbleed_type & SSL_HEARTBLEED_REQUEST) { @@ -369,7 +371,7 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p) if (SSL_IS_ALERT(new_flags)) { - sd->ssn_flags = SSLPP_process_alert(config, sd->ssn_flags, new_flags, p); + sd->ssn_flags = SSLPP_process_alert(config, sd->ssn_flags, new_flags, p, info_flags); } else if (SSL_IS_HANDSHAKE(new_flags)) {