]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: support SYN/ACK with TFO only ack'ing ISN 8568/head
authorVictor Julien <vjulien@oisf.net>
Sat, 25 Feb 2023 09:10:29 +0000 (10:10 +0100)
committerVictor Julien <vjulien@oisf.net>
Thu, 2 Mar 2023 08:01:28 +0000 (09:01 +0100)
Not ack'ing the data.

(cherry picked from commit 7ef57cc7cbbfe6ca0aff3c3526614c7ab6d14d40)

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

index 39435819f534c7ab5005f06be57fd4853f342315..205a137df4b1baaad6cc686864692898e963afe8 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 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 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;)
 alert tcp any any -> any any (msg:"SURICATA STREAM 3way handshake wrong seq wrong ack"; stream-event:3whs_wrong_seq_wrong_ack; classtype:protocol-command-decode; sid:2210010; rev:2;)
@@ -94,5 +97,5 @@ alert tcp any any -> any any (msg:"SURICATA STREAM pkt seen on wrong thread"; st
 # Packet with FIN+SYN set
 alert tcp any any -> any any (msg:"SURICATA STREAM FIN SYN reuse"; stream-event:fin_syn; classtype:protocol-command-decode; sid:2210060; rev:1;)
 
-# next sid 2210061
+# next sid 2210065
 
index aae2e464aafda6304e165b11b0bb460c055cc7b0..79659e866a35869aeee28bfcb57f56f571040422 100644 (file)
@@ -595,6 +595,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 8d0ee4a55ed15902b32abb415e4b205a0a8262f8..e5f0ae968549fff0b83f2ee5ccedb6365c835f3d 100644 (file)
@@ -222,6 +222,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_WRONG_SEQ_WRONG_ACK,
index f050e9f0be56e9504b72f7d8b985df0fe7a1e710..859e9d408f9278d16a7c24645aef5081026f7c69 100644 (file)
@@ -1619,17 +1619,24 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p,
                 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);
         }