From: Victor Julien Date: Sat, 25 Feb 2023 09:10:29 +0000 (+0100) Subject: stream: support SYN/ACK with TFO only ack'ing ISN X-Git-Tag: suricata-6.0.11~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F8568%2Fhead;p=thirdparty%2Fsuricata.git stream: support SYN/ACK with TFO only ack'ing ISN Not ack'ing the data. (cherry picked from commit 7ef57cc7cbbfe6ca0aff3c3526614c7ab6d14d40) --- diff --git a/rules/stream-events.rules b/rules/stream-events.rules index 39435819f5..205a137df4 100644 --- a/rules/stream-events.rules +++ b/rules/stream-events.rules @@ -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 diff --git a/src/decode-events.c b/src/decode-events.c index aae2e464aa..79659e866a 100644 --- a/src/decode-events.c +++ b/src/decode-events.c @@ -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, diff --git a/src/decode-events.h b/src/decode-events.h index 8d0ee4a55e..e5f0ae9685 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -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, diff --git a/src/stream-tcp.c b/src/stream-tcp.c index f050e9f0be..859e9d408f 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -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); }