From ff46cd66b754fda8c98af75b4860b9aac46874d1 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. (cherry picked from commit 6cb6225b28c5d8e616a420b7d05b129ba2845dc0) --- 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 7ea3261862b7..39435819f534 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 f96c574fa84b..a4ec4e697b77 100644 --- a/src/decode-events.c +++ b/src/decode-events.c @@ -723,6 +723,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 886cedf3a69e..b82fa235d880 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -254,6 +254,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 a170f9026674..e6ab8b2bd284 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -2750,6 +2750,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);