]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: support SYN/ACK with TFO only ack'ing ISN
authorVictor Julien <vjulien@oisf.net>
Sat, 25 Feb 2023 09:10:29 +0000 (10:10 +0100)
committerVictor Julien <vjulien@oisf.net>
Mon, 27 Feb 2023 06:34:21 +0000 (07:34 +0100)
Not ack'ing the data.

rules/stream-events.rules
src/decode-events.c
src/decode-events.h
src/stream-tcp.c

index 5cc6169d1190abf7a46c6f89d691d04cdf2e7a59..661e3d2b518b909dbf477b47713da607378a6604 100644 (file)
@@ -12,6 +12,9 @@ alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK to serv
 alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYNACK with wrong ack"; stream-event:3whs_synack_with_wrong_ack; classtype:protocol-command-decode; sid:2210007; rev:2;)
 # Excessive SYNs or SYN/ACKs within a session. Limit is set in stream engine, "stream.max-synack-queued".
 alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake excessive different SYN/ACKs"; stream-event:3whs_synack_flood; classtype:protocol-command-decode; sid:2210055; rev:2;)
+# Client sent an SYN packet with TCP fast open and data, but the server only ACK'd
+# the SYN, not the data, while still supporting TFO.
+alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN/ACK ignored TFO data"; stream-event:3whs_synack_tfo_data_ignored; classtype:protocol-command-decode; sid:2210064; rev:1;)
 alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake excessive different SYNs"; stream-event:3whs_syn_flood; classtype:protocol-command-decode; sid:2210063; rev:1;)
 alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN resend different seq on SYN recv"; stream-event:3whs_syn_resend_diff_seq_on_syn_recv; classtype:protocol-command-decode; sid:2210008; rev:2;)
 alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake SYN to client on SYN recv"; stream-event:3whs_syn_toclient_on_syn_recv; classtype:protocol-command-decode; sid:2210009; rev:2;)
@@ -102,5 +105,5 @@ alert tcp any any -> any any (msg:"SURICATA STREAM FIN SYN reuse"; stream-event:
 # Depth setting reached for a stream. Very common in normal traffic, so disable by default.
 #alert tcp any any -> any any (msg:"SURICATA STREAM reassembly depth reached"; stream-event:reassembly_depth_reached; classtype:protocol-command-decode; sid:2210062; rev:1;)
 
-# next sid 2210064
+# next sid 2210065
 
index 0a2626beca999d93f3873f3b1afe1eac52eb0710..21c8eaba2831dedca009029698bd2610f5c4f558 100644 (file)
@@ -626,6 +626,10 @@ const struct DecodeEvents_ DEvents[] = {
             "stream.3whs_synack_flood",
             STREAM_3WHS_SYNACK_FLOOD,
     },
+    {
+            "stream.3whs_synack_tfo_data_ignored",
+            STREAM_3WHS_SYNACK_TFO_DATA_IGNORED,
+    },
     {
             "stream.3whs_syn_resend_diff_seq_on_syn_recv",
             STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV,
index 150ec9f75cca2be5f6d033e5962fbc00924f90fb..2555ed28b6f423b6feb71510a729c098da91e279 100644 (file)
@@ -233,6 +233,7 @@ enum {
     STREAM_3WHS_SYNACK_TOSERVER_ON_SYN_RECV,
     STREAM_3WHS_SYNACK_WITH_WRONG_ACK,
     STREAM_3WHS_SYNACK_FLOOD,
+    STREAM_3WHS_SYNACK_TFO_DATA_IGNORED,
     STREAM_3WHS_SYN_RESEND_DIFF_SEQ_ON_SYN_RECV,
     STREAM_3WHS_SYN_TOCLIENT_ON_SYN_RECV,
     STREAM_3WHS_SYN_FLOOD,
index cb6c815f4a6755e2012173118b2da3ace3df0feb..b80e71a19a4b2679576d82e3e12b570d06a914b9 100644 (file)
@@ -1760,17 +1760,24 @@ static int StreamTcpPacketStateSynSent(
                 return -1;
             }
         } else {
-            if (!(SEQ_EQ(TCP_GET_ACK(p), ssn->client.next_seq))) {
+            if (SEQ_EQ(TCP_GET_ACK(p), ssn->client.next_seq)) {
+                SCLogDebug("ssn %p: (TFO) ACK matches next_seq, packet ACK %" PRIu32 " == "
+                           "%" PRIu32 " from stream",
+                        ssn, TCP_GET_ACK(p), ssn->client.next_seq);
+            } else if (SEQ_EQ(TCP_GET_ACK(p), ssn->client.isn + 1)) {
+                SCLogDebug("ssn %p: (TFO) ACK matches ISN+1, packet ACK %" PRIu32 " == "
+                           "%" PRIu32 " from stream",
+                        ssn, TCP_GET_ACK(p), ssn->client.isn + 1);
+                ssn->client.next_seq = ssn->client.isn;
+                SCLogDebug("ssn %p: (TFO) next_seq reset to isn (%u)", ssn, ssn->client.next_seq);
+                StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_TFO_DATA_IGNORED);
+            } else {
                 StreamTcpSetEvent(p, STREAM_3WHS_SYNACK_WITH_WRONG_ACK);
                 SCLogDebug("ssn %p: (TFO) ACK mismatch, packet ACK %" PRIu32 " != "
                         "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p),
                         ssn->client.next_seq);
                 return -1;
             }
-            SCLogDebug("ssn %p: (TFO) ACK match, packet ACK %" PRIu32 " == "
-                    "%" PRIu32 " from stream", ssn, TCP_GET_ACK(p),
-                    ssn->client.next_seq);
-
             ssn->flags |= STREAMTCP_FLAG_TCP_FAST_OPEN;
             StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED);
         }