]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tls: implement alert parser
authorVictor Julien <vjulien@oisf.net>
Fri, 18 Oct 2024 09:55:40 +0000 (11:55 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 21 Mar 2025 06:08:57 +0000 (07:08 +0100)
Fatal alerts set the tx state to 'finished'.

Add event for malformed alerts.

rules/tls-events.rules
src/app-layer-ssl.c
src/app-layer-ssl.h

index ab7963d1a18cdb340da4c5686484ddb8a66ad3d1..ab45ba5a19e92a1008e4dcd8ef4b3bae804a8952 100644 (file)
@@ -34,5 +34,6 @@ alert tls any any -> any any (msg:"SURICATA TLS certificate invalid der"; flow:e
 alert tls any any -> any any (msg:"SURICATA TLS certificate invalid subject"; flow:established; app-layer-event:tls.certificate_invalid_subject; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230028; rev:1;)
 alert tls any any -> any any (msg:"SURICATA TLS certificate invalid issuer"; flow:established; app-layer-event:tls.certificate_invalid_issuer; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230029; rev:1;)
 alert tls any any -> any any (msg:"SURICATA TLS certificate invalid validity"; flow:established; app-layer-event:tls.certificate_invalid_validity; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230030; rev:1;)
+alert tls any any -> any any (msg:"SURICATA TLS invalid alert message"; flow:established; app-layer-event:tls.invalid_alert_message; flowint:tls.anomaly.count,+,1; classtype:protocol-command-decode; sid:2230031; rev:1;)
 
-#next sid is 2230031
+#next sid is 2230032
index bce099fd59147bcdbe7c97953de23055f7e76fa8..2f24dae140e24d40ea79716ccd988fb060a9b0e3 100644 (file)
@@ -92,6 +92,7 @@ SCEnumCharMap tls_decoder_event_table[] = {
     { "INVALID_SNI_TYPE", TLS_DECODER_EVENT_INVALID_SNI_TYPE },
     { "INVALID_SNI_LENGTH", TLS_DECODER_EVENT_INVALID_SNI_LENGTH },
     { "TOO_MANY_RECORDS_IN_PACKET", TLS_DECODER_EVENT_TOO_MANY_RECORDS_IN_PACKET },
+    { "INVALID_ALERT_MESSAGE", TLS_DECODER_EVENT_INVALID_ALERT },
     /* certificate decoding messages */
     { "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE },
     { "CERTIFICATE_INVALID_LENGTH", TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH },
@@ -1913,6 +1914,38 @@ static int SSLv3ParseHandshakeProtocol(SSLState *ssl_state, const uint8_t *input
     return (int)(input - initial_input);
 }
 
+/**
+ * \internal
+ * \brief TLS Alert parser
+ *
+ * \param sslstate  Pointer to the SSL state.
+ * \param input     Pointer to the received input data.
+ * \param input_len Length in bytes of the received data.
+ * \param direction 1 toclient, 0 toserver
+ *
+ * \retval The number of bytes parsed on success, 0 if nothing parsed, -1 on failure.
+ */
+static int SSLv3ParseAlertProtocol(
+        SSLState *ssl_state, const uint8_t *input, uint32_t input_len, uint8_t direction)
+{
+    if (input_len < 2) {
+        SSLSetEvent(ssl_state, TLS_DECODER_EVENT_INVALID_ALERT);
+        return -1;
+    }
+
+    /* assume a record > 2 to be an encrypted alert record */
+    if (input_len == 2) {
+        uint8_t level = input[0];
+        // uint8_t desc = input[1];
+
+        /* if level Fatal, we consider the tx finished */
+        if (level == 2) {
+            ssl_state->flags |= SSL_AL_FLAG_STATE_FINISHED;
+        }
+    }
+    return 0;
+}
+
 /**
  * \internal
  * \brief TLS Heartbeat parser (see RFC 6520)
@@ -2540,11 +2573,17 @@ static struct SSLDecoderResult SSLv3Decode(uint8_t direction, SSLState *ssl_stat
             }
             break;
 
-        case SSLV3_ALERT_PROTOCOL:
+        case SSLV3_ALERT_PROTOCOL: {
             AppLayerFrameNewByPointer(ssl_state->f, &stream_slice, input + parsed,
                     ssl_state->curr_connp->record_length, direction, TLS_FRAME_ALERT_DATA);
-            break;
 
+            int retval = SSLv3ParseAlertProtocol(ssl_state, input + parsed, record_len, direction);
+            if (retval < 0) {
+                SCLogDebug("SSLv3ParseAlertProtocol returned %d", retval);
+                return SSL_DECODER_ERROR(-1);
+            }
+            break;
+        }
         case SSLV3_APPLICATION_PROTOCOL:
             /* In TLSv1.3 early data (0-RTT) could be sent before the
                handshake is complete (rfc8446, section 2.3). We should
index 479ccf51921d9f9561ee08b4e18fd916413d6dd9..8ad65f886f9093154e5e47a0e1b9a4c072c2205a 100644 (file)
@@ -56,6 +56,7 @@ enum {
     TLS_DECODER_EVENT_INVALID_SNI_TYPE,
     TLS_DECODER_EVENT_INVALID_SNI_LENGTH,
     TLS_DECODER_EVENT_TOO_MANY_RECORDS_IN_PACKET,
+    TLS_DECODER_EVENT_INVALID_ALERT,
     /* Certificates decoding messages */
     TLS_DECODER_EVENT_INVALID_CERTIFICATE,
     TLS_DECODER_EVENT_CERTIFICATE_INVALID_LENGTH,