]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3130: ssl: disable inspection on alert only at fatal level
authorTom Peters (thopeter) <thopeter@cisco.com>
Tue, 2 Nov 2021 17:21:33 +0000 (17:21 +0000)
committerTom Peters (thopeter) <thopeter@cisco.com>
Tue, 2 Nov 2021 17:21:33 +0000 (17:21 +0000)
Merge in SNORT/snort3 from ~SBAIGAL/snort3:ssl_alert_fix to master

Squashed commit of the following:

commit fc567298456a798da12318c18c78c35f69cf868e
Author: Steven Baigal (sbaigal) <sbaigal@cisco.com>
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

src/protocols/ssl.cc
src/protocols/ssl.h
src/service_inspectors/ssl/ssl_inspector.cc

index b1c01c864de114736f1d65ec6bd15f5b7bc8df9f..aff3a3717058ea6d87a7577073a31deb623ea07e 100644 (file)
@@ -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))
index 9efb34c53567179b5acff421c561ae3fdb8697dc..03ca5c956fa0934122d74cefcb9ea366834925f4 100644 (file)
@@ -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);
index 44fc7ba8ecb20ac8efeead4b92e6261658a80399..fcdf2e9c8c59b06f7cc4fd95bdd740c31b1362e1 100644 (file)
@@ -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))
     {