]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
tcp: rejects FIN+SYN packets as invalid
authorPhilippe Antoine <contact@catenacyber.fr>
Thu, 16 Sep 2021 14:54:37 +0000 (16:54 +0200)
committerVictor Julien <vjulien@oisf.net>
Mon, 15 Nov 2021 13:33:16 +0000 (14:33 +0100)
Ticket: #4569

If a FIN+SYN packet is sent, the destination may keep the
connection alive instead of starting to close it.
In this case, a later SYN packet will be ignored by the
destination.

Previously, Suricata considered this a session reuse, and thus
used the sequence number of the last SYN packet, instead of
using the one of the live connection, leading to evasion.

This commit errors on FIN+SYN so that they do not get
processed as regular FIN packets.

(cherry picked from commit 6cb6225b28c5d8e616a420b7d05b129ba2845dc0)

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

index 7ea3261862b7e12fab27c59dc065bd7c30449bef..39435819f534c7ab5005f06be57fd4853f342315 100644 (file)
@@ -91,5 +91,8 @@ alert tcp any any -> any any (msg:"SURICATA STREAM excessive retransmissions"; f
 # Packet on wrong thread. Fires at most once per flow.
 alert tcp any any -> any any (msg:"SURICATA STREAM pkt seen on wrong thread"; stream-event:wrong_thread; sid:2210059; rev:1;)
 
-# next sid 2210060
+# 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
 
index 0a9cfab9627b53a02c440e975b2ae1e117524595..99eeae19edf02b60192975ec801f1beb629dd03f 100644 (file)
@@ -254,6 +254,10 @@ const struct DecodeEvents_ DEvents[] = {
     { "stream.fin2_invalid_ack", STREAM_FIN2_INVALID_ACK, },
     { "stream.fin_but_no_session", STREAM_FIN_BUT_NO_SESSION, },
     { "stream.fin_out_of_window", STREAM_FIN_OUT_OF_WINDOW, },
+    {
+            "stream.fin_syn",
+            STREAM_FIN_SYN,
+    },
     { "stream.lastack_ack_wrong_seq", STREAM_LASTACK_ACK_WRONG_SEQ, },
     { "stream.lastack_invalid_ack", STREAM_LASTACK_INVALID_ACK, },
     { "stream.rst_but_no_session", STREAM_RST_BUT_NO_SESSION, },
index 329860ffcea79d90bcb201aed2d6373f9f12e7ae..c3bb9bf27e71489e335f60bdd0b8533b86e12440 100644 (file)
@@ -244,6 +244,7 @@ enum {
     STREAM_FIN2_INVALID_ACK,
     STREAM_FIN_BUT_NO_SESSION,
     STREAM_FIN_OUT_OF_WINDOW,
+    STREAM_FIN_SYN,
     STREAM_LASTACK_ACK_WRONG_SEQ,
     STREAM_LASTACK_INVALID_ACK,
     STREAM_RST_BUT_NO_SESSION,
index 49a82585bb44cfd9c2b18f3b17b954e803e19a3e..98ae70ee5c899a8c7eb3a6996d7146013d18417c 100644 (file)
@@ -2754,6 +2754,11 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt,
             return -1;
         }
 
+        if (p->tcph->th_flags & TH_SYN) {
+            SCLogDebug("ssn %p: FIN+SYN", ssn);
+            StreamTcpSetEvent(p, STREAM_FIN_SYN);
+            return -1;
+        }
         StreamTcpPacketSetState(p, ssn, TCP_CLOSE_WAIT);
         SCLogDebug("ssn %p: state changed to TCP_CLOSE_WAIT", ssn);