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-7.0.0-rc2~550 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ef57cc7cbbfe6ca0aff3c3526614c7ab6d14d40;p=thirdparty%2Fsuricata.git stream: support SYN/ACK with TFO only ack'ing ISN Not ack'ing the data. --- diff --git a/rules/stream-events.rules b/rules/stream-events.rules index 5cc6169d11..661e3d2b51 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 SYNs or 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 excessive different SYNs"; stream-event:3whs_syn_flood; classtype:protocol-command-decode; sid:2210063; 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;) @@ -102,5 +105,5 @@ alert tcp any any -> any any (msg:"SURICATA STREAM FIN SYN reuse"; stream-event: # Depth setting reached for a stream. Very common in normal traffic, so disable by default. #alert tcp any any -> any any (msg:"SURICATA STREAM reassembly depth reached"; stream-event:reassembly_depth_reached; classtype:protocol-command-decode; sid:2210062; rev:1;) -# next sid 2210064 +# next sid 2210065 diff --git a/src/decode-events.c b/src/decode-events.c index 0a2626beca..21c8eaba28 100644 --- a/src/decode-events.c +++ b/src/decode-events.c @@ -626,6 +626,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 150ec9f75c..2555ed28b6 100644 --- a/src/decode-events.h +++ b/src/decode-events.h @@ -233,6 +233,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_SYN_FLOOD, diff --git a/src/stream-tcp.c b/src/stream-tcp.c index cb6c815f4a..b80e71a19a 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -1760,17 +1760,24 @@ static int StreamTcpPacketStateSynSent( 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); }