From 6cb6225b28c5d8e616a420b7d05b129ba2845dc0 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 16 Sep 2021 16:54:37 +0200 Subject: [PATCH] tcp: rejects FIN+SYN packets as invalid 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. --- rules/stream-events.rules | 5 ++++- src/decode-events.c | 4 ++++ src/decode-events.h | 1 + src/stream-tcp.c | 5 +++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/rules/stream-events.rules b/rules/stream-events.rules index 7ea326186..39435819f 100644 --- a/rules/stream-events.rules +++ b/rules/stream-events.rules @@ -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 diff --git a/src/decode-events.c b/src/decode-events.c index 8023d1075..cd93e3105 100644 --- a/src/decode-events.c +++ b/src/decode-events.c @@ -754,6 +754,10 @@ const struct DecodeEvents_ DEvents[] = { "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, diff --git a/src/decode-events.h b/src/decode-events.h index 6fad62e27..715b46e8d 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -265,6 +265,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, diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 311ce1ed6..1cff19fa5 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -2813,6 +2813,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); -- 2.47.3