snort: Updated to 2.9.8.0 with Quantum Insert patch included Updated: rootfile Updated: patch file
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org --- config/rootfiles/common/snort | 2 +- lfs/snort | 5 +- .../stream_quantuminsert-snort-2.9.8.0.patch | 417 +++++++++++++++++++++ 3 files changed, 421 insertions(+), 3 deletions(-) create mode 100644 src/patches/stream_quantuminsert-snort-2.9.8.0.patch
diff --git a/config/rootfiles/common/snort b/config/rootfiles/common/snort index 6dfcdfc..77208e8 100644 --- a/config/rootfiles/common/snort +++ b/config/rootfiles/common/snort @@ -27,7 +27,6 @@ usr/bin/u2spewfoo #usr/include/snort/dynamic_output/snort_debug.h #usr/include/snort/dynamic_output/stream_api.h #usr/include/snort/dynamic_preproc -#usr/include/snort/dynamic_preproc/appId.h #usr/include/snort/dynamic_preproc/bitop.h #usr/include/snort/dynamic_preproc/cpuclock.h #usr/include/snort/dynamic_preproc/file_api.h @@ -38,6 +37,7 @@ usr/bin/u2spewfoo #usr/include/snort/dynamic_preproc/mpse_methods.h #usr/include/snort/dynamic_preproc/obfuscation.h #usr/include/snort/dynamic_preproc/packet_time.h +#usr/include/snort/dynamic_preproc/perf_indicators.h #usr/include/snort/dynamic_preproc/preprocids.h #usr/include/snort/dynamic_preproc/profiler.h #usr/include/snort/dynamic_preproc/segment_mem.h diff --git a/lfs/snort b/lfs/snort index 148f539..9b1d34d 100644 --- a/lfs/snort +++ b/lfs/snort @@ -24,7 +24,7 @@
include Config
-VER = 2.9.7.6 +VER = 2.9.8.0
THISAPP = snort-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 65349f3272c4de5b3210f77f1f7ab0e6 +$(DL_FILE)_MD5 = 33a2ffd0daf3f60b81ab685848f95947
install : $(TARGET)
@@ -70,6 +70,7 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) $(DIR_SRC)/snort* && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/stream_quantuminsert-snort-2.9.8.0.patch cd $(DIR_APP) && ./configure \ --prefix=/usr \ --sysconfdir=/etc/snort \ diff --git a/src/patches/stream_quantuminsert-snort-2.9.8.0.patch b/src/patches/stream_quantuminsert-snort-2.9.8.0.patch new file mode 100644 index 0000000..f482de4 --- /dev/null +++ b/src/patches/stream_quantuminsert-snort-2.9.8.0.patch @@ -0,0 +1,417 @@ +--- src/preprocessors/Stream6/snort_stream_tcp.c Wed Nov 18 19:59:15 2015 ++++ src/preprocessors/Stream6/snort_stream_tcp.c Fri Dec 11 13:39:41 2015 +@@ -48,6 +48,7 @@ + + #include <errno.h> + #include <assert.h> ++#include "Unified2_common.h" + + #ifdef HAVE_CONFIG_H + #include "config.h" +@@ -202,6 +203,7 @@ + #define EVENT_BAD_ACK 0x00008000 + #define EVENT_DATA_AFTER_RST_RCVD 0x00010000 + #define EVENT_WINDOW_SLAM 0x00020000 ++#define EVENT_QUANTUM_INSERT 0x00040000 + + #define TF_NONE 0x0000 + #define TF_WSCALE 0x0001 +@@ -386,6 +388,12 @@ + // TBD move out of here since only used per packet? + StreamSegment* seglist_next; /* next queued segment to flush */ + ++ // Keep track of acked/purged segments, configurable with `max_track_old_segs` ++ StreamSegment *qi_seglist; /* first queued segment */ ++ StreamSegment *qi_seglist_tail; /* last queued segment */ ++ StreamSegment *qi_inserted_seg; /* the inconsistent segment, used for extra_data */ ++ uint32_t qi_seg_count; /* number of current queued segments */ ++ + #ifdef DEBUG + int segment_ordinal; + #endif +@@ -1402,6 +1410,7 @@ + clone->max_consec_small_segs = master->max_consec_small_segs; + clone->max_consec_small_seg_size = master->max_consec_small_seg_size; + memcpy(clone->small_seg_ignore, master->small_seg_ignore, sizeof(master->small_seg_ignore)); ++ clone->max_track_old_segs = master->max_track_old_segs; + + config = (StreamConfig *) sfPolicyUserDataGet(stream_online_config, getParserPolicy( snort_conf )); + addStreamTcpPolicyToList( config->tcp_config, clone ); +@@ -1544,6 +1553,38 @@ + + #define STATIC_FP ((s5TcpPolicy->flags & STREAM_CONFIG_STATIC_FLUSHPOINTS)?1:0) + ++static int GetQuantumPacket(void *ssn_ptr, uint8_t **buf, uint32_t *len, uint32_t *type) ++{ ++ SessionControlBlock* scb = NULL; ++ TcpSession *tcpssn = NULL; ++ StreamTracker *listener = NULL; ++ StreamSegment *seg = NULL; ++ ++ if (ssn_ptr == NULL) ++ return 0; ++ ++ scb = (SessionControlBlock*) ssn_ptr; ++ if (scb->proto_specific_data) ++ tcpssn = (TcpSession *)scb->proto_specific_data->data; ++ ++ if (tcpssn == NULL) ++ return 0; ++ ++ listener = &tcpssn->client; ++ seg = listener->qi_inserted_seg; ++ ++ if (seg == NULL) ++ return 0; ++ ++ *buf = (uint8_t *)seg->data; ++ *len = seg->size; ++ *type = EVENT_INFO_GENERIC_DATA; ++ ++ listener->qi_inserted_seg = NULL; ++ ++ return 1; ++} ++ + static void StreamParseTcpArgs(struct _SnortConfig *sc, StreamTcpConfig *config, char *args, StreamTcpPolicy *s5TcpPolicy) + { + char **toks; +@@ -1571,6 +1612,10 @@ + s5TcpPolicy->max_consec_small_seg_size = STREAM_DEFAULT_MAX_SMALL_SEG_SIZE; + s5TcpPolicy->log_asymmetric_traffic = false; + ++ s5TcpPolicy->max_track_old_segs = STREAM_DEFAULT_TRACK_OLD_SEGS; ++ if (stream_api) ++ s5TcpPolicy->xtra_quantum_id = stream_api->reg_xtra_data_cb(GetQuantumPacket); ++ + if(args != NULL && strlen(args) != 0) + { + toks = mSplit(args, ",", 0, &num_toks, 0); +@@ -1859,6 +1904,39 @@ + } + max_s_toks = 2; + } ++ ++ else if(!strcasecmp(stoks[0], "max_track_old_segs")) ++ { ++ if(stoks[1]) ++ { ++ long_val = SnortStrtol(stoks[1], &endPtr, 10); ++ if (errno == ERANGE) ++ { ++ errno = 0; ++ FatalError("%s(%d) => Invalid Max Track Old Segments. Integer parameter required.\n", ++ file_name, file_line); ++ } ++ s5TcpPolicy->max_track_old_segs = (uint32_t)long_val; ++ } ++ ++ if (!stoks[1] || (endPtr == &stoks[1][0])) ++ { ++ FatalError("%s(%d) => Invalid Max Track Old Segments. Integer parameter required.\n", ++ file_name, file_line); ++ } ++ ++ if (((long_val > STREAM_MAX_MAX_TRACK_OLD_SEGS) || ++ (long_val < STREAM_MIN_MAX_TRACK_OLD_SEGS)) && ++ (long_val != 0)) ++ { ++ FatalError("%s(%d) => Invalid Max Track Old Segments." ++ " Must be 0 (disabled) or between %d and %d\n", ++ file_name, file_line, ++ STREAM_MAX_MAX_TRACK_OLD_SEGS, STREAM_MIN_MAX_TRACK_OLD_SEGS); ++ } ++ max_s_toks = 2; ++ } ++ + else if (!strcasecmp(stoks[0], "small_segments")) + { + char **ptoks; +@@ -2338,6 +2416,11 @@ + LogMessage(" Maximum number of segs to queue per session: %d\n", + s5TcpPolicy->max_queued_segs); + } ++ if (s5TcpPolicy->max_track_old_segs != 0) ++ { ++ LogMessage(" Maximum number of old segs to track per session: %d\n", ++ s5TcpPolicy->max_track_old_segs); ++ } + if (s5TcpPolicy->flags) + { + LogMessage(" Options:\n"); +@@ -3055,6 +3138,22 @@ + NULL); /* rule info ptr */ + } + ++static inline void EventQuantumInsert (StreamTcpPolicy *s5TcpPolicy) ++{ ++ // if(!(s5TcpPolicy->flags & STREAM_CONFIG_ENABLE_ALERTS)) ++ // return; ++ ++ s5stats.events++; ++ ++ SnortEventqAdd(GENERATOR_SPP_STREAM, /* GID */ ++ STREAM_QUANTUM_INSERT, /* SID */ ++ 1, /* rev */ ++ 0, /* class */ ++ 3, /* priority */ ++ STREAM_QUANTUM_INSERT_STR, /* event msg */ ++ NULL); /* rule info ptr */ ++} ++ + /* + * Utility functions for TCP stuff + */ +@@ -4133,6 +4232,10 @@ + st->seglist = st->seglist_tail = st->seglist_next = NULL; + st->seg_count = st->flush_count = 0; + st->seg_bytes_total = st->seg_bytes_logical = 0; ++ ++ st->qi_seg_count = 0; ++ DeleteSeglist(st->qi_seglist); ++ st->qi_seglist = st->qi_seglist_tail = st->qi_inserted_seg = NULL; + } + + // purge_flushed_ackd(): +@@ -6113,6 +6216,69 @@ + return NULL; + } + ++static inline StreamSegment *FindOldSegment(StreamTracker *st, uint32_t pkt_seq) ++{ ++ int32_t dist_head; ++ int32_t dist_tail; ++ StreamSegment *ss; ++ ++ if (!st->qi_seglist) ++ return NULL; ++ ++ dist_head = pkt_seq - st->qi_seglist->seq; ++ dist_tail = pkt_seq - st->qi_seglist_tail->seq; ++ ++ if (dist_head <= dist_tail) ++ { ++ /* Start iterating at the head (left) */ ++ for (ss = st->qi_seglist; ss; ss = ss->next) ++ { ++ if (SEQ_EQ(ss->seq, pkt_seq)) ++ return ss; ++ ++ if (SEQ_GEQ(ss->seq, pkt_seq)) ++ break; ++ } ++ } ++ else ++ { ++ /* Start iterating at the tail (right) */ ++ for (ss = st->qi_seglist_tail; ss; ss = ss->prev) ++ { ++ if (SEQ_EQ(ss->seq, pkt_seq)) ++ return ss; ++ ++ if (SEQ_LT(ss->seq, pkt_seq)) ++ break; ++ } ++ } ++ return NULL; ++} ++ ++static inline int CheckQuantumInsert(StreamTracker *listener, ++ TcpDataBlock *tdb, ++ Packet *p) ++{ ++ int ret = 0; ++ StreamSegment* seg = NULL; ++ ++ if (listener->seglist_tail && tdb->seq <= listener->seglist_tail->seq) { ++ seg = FindSegment(listener, tdb->seq); ++ } ++ if (seg == NULL && listener->qi_seglist_tail && tdb->seq <= listener->qi_seglist_tail->seq) { ++ seg = FindOldSegment(listener, tdb->seq); ++ } ++ if (seg) { ++ // compare smallest segment size ++ if (memcmp(p->data, seg->data, MIN(p->dsize, seg->size)) != 0) { ++ listener->qi_inserted_seg = seg; ++ SetExtraData(p, listener->tcp_policy->xtra_quantum_id); ++ ret |= EVENT_QUANTUM_INSERT; ++ } ++ } ++ return ret; ++} ++ + void StreamTcpSessionClear(Packet *p) + { + SessionControlBlock *scb; +@@ -7476,8 +7642,10 @@ + { + if ( !(tcpssn->scb->ha_state.session_flags & SSNFLAG_STREAM_ORDER_BAD) ) + { +- if ( !SEQ_LEQ((tdb->seq + p->dsize), listener->r_nxt_ack) ) ++ if ( !SEQ_LEQ((tdb->seq + p->dsize), listener->r_nxt_ack) ) { + tcpssn->scb->ha_state.session_flags |= SSNFLAG_STREAM_ORDER_BAD; ++ CheckQuantumInsert(listener, tdb, p); ++ } + } + ProcessTcpStream(listener, tcpssn, p, tdb, s5TcpPolicy); + } +@@ -8162,6 +8330,9 @@ + + if (eventcode & EVENT_WINDOW_SLAM) + EventWindowSlam(s5TcpPolicy); ++ ++ if (eventcode & EVENT_QUANTUM_INSERT) ++ EventQuantumInsert(s5TcpPolicy); + } + + static inline void DisableInspection (SessionControlBlock *scb, Packet* p, char ignore) +@@ -9195,6 +9366,10 @@ + if ((p->tcph->th_flags != 0) || (s5TcpPolicy->policy == STREAM_POLICY_LINUX) || (s5TcpPolicy->policy == STREAM_POLICY_NOACK)) + { + ProcessTcpData(p, listener, tcpssn, tdb, s5TcpPolicy); ++ ++ if (listener->qi_inserted_seg) ++ eventcode |= EVENT_QUANTUM_INSERT; ++ + //Check if all segments are received. Process FIN transition + if(checkFINTransitionStatus(p, listener)) + process_fin = true; +@@ -10144,8 +10319,46 @@ + if ( st->seglist_next == seg ) + st->seglist_next = NULL; + +- SegmentFree(seg); +- st->seg_count--; ++ // Keep track of `max_track_old_segs` segments ++ if (st->tcp_policy->max_track_old_segs) { ++ StreamSegment* prev = st->qi_seglist_tail; ++ StreamSegment* new = seg; ++ if(prev) ++ { ++ new->next = prev->next; ++ new->prev = prev; ++ prev->next = new; ++ if (new->next) ++ new->next->prev = new; ++ else ++ st->qi_seglist_tail = new; ++ } ++ else ++ { ++ new->next = st->qi_seglist; ++ if(new->next) ++ new->next->prev = new; ++ else ++ st->qi_seglist_tail = new; ++ st->qi_seglist = new; ++ } ++ ++ st->qi_seg_count++; ++ while (st->qi_seg_count > st->tcp_policy->max_track_old_segs) { ++ StreamSegment* old = st->qi_seglist; ++ st->qi_seglist = st->qi_seglist->next; ++ if (st->qi_seglist) ++ st->qi_seglist->prev = NULL; ++ if (st->qi_seglist == NULL) ++ st->qi_seglist_tail = NULL; ++ SegmentFree(old); ++ st->qi_seg_count--; ++ st->seg_count--; ++ } ++ } else { ++ SegmentFree(seg); ++ st->seg_count--; ++ } + + return ret; + } +--- src/preprocessors/Stream6/stream_common.h Wed Nov 18 19:59:15 2015 ++++ src/preprocessors/Stream6/stream_common.h Fri Dec 11 13:41:15 2015 +@@ -69,6 +69,9 @@ + #define STREAM_DEFAULT_CONSEC_SMALL_SEGS 0 /* disabled */ + #define STREAM_MAX_CONSEC_SMALL_SEGS 2048 /* 2048 single byte packets without acks is alot */ + #define STREAM_MIN_CONSEC_SMALL_SEGS 0 /* 0 means disabled */ ++#define STREAM_DEFAULT_TRACK_OLD_SEGS 10 /* keep track of 10 old TCP segments */ ++#define STREAM_MIN_MAX_TRACK_OLD_SEGS 0 /* 0 means disabled */ ++#define STREAM_MAX_MAX_TRACK_OLD_SEGS 2048 /* history of 2048 segments should be enough */ + + #if defined(FEAT_OPEN_APPID) + #define MAX_APP_PROTOCOL_ID 4 +@@ -203,6 +206,10 @@ + + uint32_t max_consec_small_segs; + uint32_t max_consec_small_seg_size; ++ ++ uint32_t max_track_old_segs; ++ uint32_t xtra_quantum_id; ++ + char small_seg_ignore[MAX_PORTS/8]; + bool log_asymmetric_traffic; + +--- src/sfutil/Unified2_common.h Wed Nov 18 19:59:15 2015 ++++ src/sfutil/Unified2_common.h Fri Dec 11 13:42:17 2015 +@@ -193,7 +193,8 @@ + EVENT_INFO_HTTP_HOSTNAME, + EVENT_INFO_IPV6_SRC, + EVENT_INFO_IPV6_DST, +- EVENT_INFO_JSNORM_DATA ++ EVENT_INFO_JSNORM_DATA, ++ EVENT_INFO_GENERIC_DATA + }EventInfoEnum; + + typedef enum _EventDataType +--- src/generators.h Wed Nov 18 19:59:14 2015 ++++ src/generators.h Fri Dec 11 13:12:12 2015 +@@ -438,6 +438,7 @@ + #define DNS_EVENT_OBSOLETE_TYPES 1 + #define DNS_EVENT_EXPERIMENTAL_TYPES 2 + #define DNS_EVENT_RDATA_OVERFLOW 3 ++#define STREAM_QUANTUM_INSERT 21 + + #define GENERATOR_SKYPE 132 + +@@ -592,6 +593,7 @@ + #define STREAM_DATA_AFTER_RST_RCVD_STR "Data sent on stream after TCP Reset received" + #define STREAM_WINDOW_SLAM_STR "TCP window closed before receiving data" + #define STREAM_NO_3WHS_STR "TCP session without 3-way handshake" ++#define STREAM_QUANTUM_INSERT_STR "Possible Quantum Insert" + + #define STREAM_INTERNAL_EVENT_STR "" + +--- tools/u2openappid/u2openappid.c Thu Apr 23 19:28:11 2015 ++++ tools/u2openappid/u2openappid.c Fri Dec 11 13:43:55 2015 +@@ -296,6 +296,11 @@ + len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData)); + break; + ++ case EVENT_INFO_GENERIC_DATA: ++ printf("Generic Data:\n"); ++ LogBuffer(record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), len); ++ break; ++ + case EVENT_INFO_SMTP_FILENAME: + printf("SMTP Attachment Filename: %.*s\n", + len,record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData)); +--- tools/u2spewfoo/u2spewfoo.c Thu Apr 23 19:28:11 2015 ++++ tools/u2spewfoo/u2spewfoo.c Fri Dec 11 13:45:27 2015 +@@ -43,6 +43,8 @@ + + #include "Unified2_common.h" + ++static void LogBuffer (const uint8_t* p, unsigned n); ++ + #define SUCCESS 314159265 + #define STEVE -1 + #define FAILURE STEVE +@@ -294,6 +296,11 @@ + case EVENT_INFO_JSNORM_DATA: + printf("Normalized JavaScript Data: %.*s\n", + len, record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData)); ++ break; ++ ++ case EVENT_INFO_GENERIC_DATA: ++ printf("Generic Data:\n"); ++ LogBuffer(record->data + sizeof(Unified2ExtraDataHdr) + sizeof(SerialUnified2ExtraData), len); + break; + + case EVENT_INFO_SMTP_FILENAME: