From: Juweria Ali Imran (jaliimra) Date: Thu, 5 Oct 2023 20:28:31 +0000 (+0000) Subject: Pull request #4034: stream_tcp: accept 1 byte of trimmed probe data after zero window X-Git-Tag: 3.1.72.0~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5217dff062668c7c546920b47156c84470a1badc;p=thirdparty%2Fsnort3.git Pull request #4034: stream_tcp: accept 1 byte of trimmed probe data after zero window Merge in SNORT/snort3 from ~JALIIMRA/snort3:sfcn_zw_trim to master Squashed commit of the following: commit 86635a90a120ba963cee350075bc8f50545f219d Author: Juweria Ali Imran Date: Thu Sep 28 06:11:46 2023 -0400 stream_tcp: accept 1 byte of trimmed probe data after zero window --- diff --git a/src/stream/tcp/segment_overlap_editor.cc b/src/stream/tcp/segment_overlap_editor.cc index c3cb1da87..b95017bf3 100644 --- a/src/stream/tcp/segment_overlap_editor.cc +++ b/src/stream/tcp/segment_overlap_editor.cc @@ -465,7 +465,7 @@ void SegmentOverlapEditor::full_right_overlap_os5(TcpReassemblerState& trs) bool SegmentOverlapEditor::zwp_data_mismatch( TcpReassemblerState& trs, TcpSegmentDescriptor& tsd, uint32_t overlap) { - if ( overlap == ZERO_WIN_PROBE_LEN + if ( overlap == MAX_ZERO_WIN_PROBE_LEN and trs.sos.right->i_seq == trs.tracker->normalizer.get_zwp_seq() and (trs.sos.right->data[0] != tsd.get_pkt()->data[0]) ) { diff --git a/src/stream/tcp/tcp_defs.h b/src/stream/tcp/tcp_defs.h index 8b768c64c..7b140e7f5 100644 --- a/src/stream/tcp/tcp_defs.h +++ b/src/stream/tcp/tcp_defs.h @@ -61,7 +61,7 @@ struct Packet; #define SLAM_MAX 4 -#define ZERO_WIN_PROBE_LEN 1 +#define MAX_ZERO_WIN_PROBE_LEN 1 // target-based policy types - changes to this enum require changes to stream.h::TCP_POLICIES enum StreamPolicy : uint8_t diff --git a/src/stream/tcp/tcp_normalizer.cc b/src/stream/tcp/tcp_normalizer.cc index f83d7ebcf..275fdb195 100644 --- a/src/stream/tcp/tcp_normalizer.cc +++ b/src/stream/tcp/tcp_normalizer.cc @@ -170,8 +170,6 @@ uint32_t TcpNormalizer::get_zwp_seq( uint32_t TcpNormalizer::get_stream_window( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd) { - int32_t window; - if ( tns.tracker->get_snd_wnd() ) { if ( !(tns.session->flow->session_state & STREAM_STATE_MIDSTREAM ) ) @@ -181,11 +179,17 @@ uint32_t TcpNormalizer::get_stream_window( return tns.tracker->get_snd_wnd(); // ensure the data is in the window - window = tsd.get_end_seq() - tns.tracker->r_win_base; + return data_inside_window(tns, tsd); +} + +uint32_t TcpNormalizer::data_inside_window( + TcpNormalizerState& tns, TcpSegmentDescriptor& tsd) +{ + int32_t window = tsd.get_end_seq() - tns.tracker->r_win_base; if ( window < 0 ) - window = 0; + return 0; - return (uint32_t)window; + return (uint32_t) window; } uint32_t TcpNormalizer::get_tcp_timestamp( diff --git a/src/stream/tcp/tcp_normalizer.h b/src/stream/tcp/tcp_normalizer.h index d7ccfd7e8..9a0897018 100644 --- a/src/stream/tcp/tcp_normalizer.h +++ b/src/stream/tcp/tcp_normalizer.h @@ -76,6 +76,7 @@ public: virtual void ecn_stripper(State&, TcpSegmentDescriptor&); virtual uint32_t get_zwp_seq(State&); virtual uint32_t get_stream_window(State&, TcpSegmentDescriptor&); + virtual uint32_t data_inside_window(State&, TcpSegmentDescriptor&); virtual uint32_t get_tcp_timestamp(State&, TcpSegmentDescriptor&, bool strip); virtual int handle_paws(State&, TcpSegmentDescriptor&); virtual bool validate_rst(State&, TcpSegmentDescriptor&); diff --git a/src/stream/tcp/tcp_normalizers.h b/src/stream/tcp/tcp_normalizers.h index 0a24ce693..67befb242 100644 --- a/src/stream/tcp/tcp_normalizers.h +++ b/src/stream/tcp/tcp_normalizers.h @@ -80,6 +80,9 @@ public: uint32_t get_stream_window(TcpSegmentDescriptor& tsd) { return norm->get_stream_window(tns, tsd); } + uint32_t data_inside_window(TcpSegmentDescriptor& tsd) + { return norm->data_inside_window(tns, tsd); } + uint32_t get_tcp_timestamp(TcpSegmentDescriptor& tsd, bool strip) { return norm->get_tcp_timestamp(tns, tsd, strip); } diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index a021c5c6e..5df70791c 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -475,16 +475,16 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) if ( tcp_config->policy != StreamPolicy::OS_PROXY and listener->normalizer.get_stream_window(tsd) == 0 ) { - if (tsd.get_len() == ZERO_WIN_PROBE_LEN) + if ( !listener->normalizer.data_inside_window(tsd) or !listener->get_iss() ) { - tcpStats.zero_win_probes++; - listener->normalizer.set_zwp_seq(seq); + listener->normalizer.trim_win_payload(tsd); + return STREAM_UNALIGNED; } else { - bool force = (tsd.is_nap_policy_inline() && listener->get_iss()); - listener->normalizer.trim_win_payload(tsd, 0, force); - return STREAM_UNALIGNED; + tcpStats.zero_win_probes++; + listener->normalizer.set_zwp_seq(seq); + listener->normalizer.trim_win_payload(tsd, MAX_ZERO_WIN_PROBE_LEN, tsd.is_nap_policy_inline()); } } @@ -511,11 +511,14 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) if ( tcp_config->policy != StreamPolicy::OS_PROXY and listener->normalizer.get_stream_window(tsd) == 0 ) { - if (tsd.get_len() == ZERO_WIN_PROBE_LEN) + if ( SEQ_EQ(seq, listener->normalizer.get_zwp_seq()) ) + { tcpStats.zero_win_probes++; + listener->normalizer.trim_win_payload(tsd, MAX_ZERO_WIN_PROBE_LEN, tsd.is_nap_policy_inline()); + return STREAM_UNALIGNED; + } - bool force = (tsd.is_nap_policy_inline() && listener->get_iss()); - listener->normalizer.trim_win_payload(tsd, 0, force); + listener->normalizer.trim_win_payload(tsd); return STREAM_UNALIGNED; } if ( tsd.is_data_segment() )