From: Russ Combs (rucombs) Date: Wed, 23 Nov 2016 12:46:31 +0000 (-0500) Subject: Merge pull request #719 in SNORT/snort3 from ecb_alt_fast_pattern to master X-Git-Tag: 3.0.0-233~174 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=570c41b29daf9bcd7a34d180d63d79283a3d3a8d;p=thirdparty%2Fsnort3.git Merge pull request #719 in SNORT/snort3 from ecb_alt_fast_pattern to master Squashed commit of the following: commit b89eb774fcc4a5ac076304db6dab6dd31f5ddf99 Author: mdagon Date: Fri Nov 18 13:28:03 2016 -0500 alternate pattern for dce_udp iface rule option Code review fixes Remove an extra 'using namespace std' Refactoring --- diff --git a/src/detection/fp_create.cc b/src/detection/fp_create.cc index 0e1d4c5b9..d9b1bbaf6 100644 --- a/src/detection/fp_create.cc +++ b/src/detection/fp_create.cc @@ -458,10 +458,25 @@ static int fpFinishPortGroup( return 0; } +static void fpAddAlternatePatterns(SnortConfig* sc, PortGroup* pg, + OptTreeNode* otn, PatternMatchData* pmd, FastPatternConfig* fp) +{ + if ( fp->get_debug_print_fast_patterns() ) + print_fp_info(s_group, otn, pmd, pmd->pattern_buf, pmd->pattern_size); + + PMX* pmx = (PMX*)snort_calloc(sizeof(PMX)); + pmx->rule_node.rnRuleData = otn; + pmx->pmd = pmd; + + Mpse::PatternDescriptor desc(pmd->no_case, pmd->negated, pmd->literal, pmd->flags); + pg->mpse[pmd->pm_type]->add_pattern(sc, (uint8_t*)pmd->pattern_buf, pmd->pattern_size, desc, + pmx); +} + static int fpAddPortGroupRule( SnortConfig* sc, PortGroup* pg, OptTreeNode* otn, FastPatternConfig* fp, bool srvc) { - PatternMatchData* pmd = NULL; + PatternMatchVector pmv; // skip builtin rules, continue for text and so rules if ( !otn->sigInfo.text_rule ) @@ -472,23 +487,27 @@ static int fpAddPortGroupRule( return -1; OptFpList* next = nullptr; - pmd = get_fp_content(otn, next, srvc); + pmv = get_fp_content(otn, next, srvc); - if ( pmd ) + if ( !pmv.empty() ) { - if ( - !pmd->relative && !pmd->negated && pmd->fp_only >= 0 && + PatternMatchData* main_pmd = pmv.back(); + pmv.pop_back(); + + if ( !main_pmd->relative && !main_pmd->negated && main_pmd->fp_only >= 0 && // FIXIT-L no_case consideration is mpse specific, delegate - !pmd->offset && !pmd->depth && pmd->no_case ) + !main_pmd->offset && !main_pmd->depth && main_pmd->no_case ) { if ( !next || !next->ips_opt || !next->ips_opt->is_relative() ) - pmd->fp_only = 1; + main_pmd->fp_only = 1; } - if (fpFinishPortGroupRule(sc, pg, otn, pmd, fp) == 0) + if (fpFinishPortGroupRule(sc, pg, otn, main_pmd, fp) == 0) { - if (pmd->pattern_size > otn->longestPatternLen) - otn->longestPatternLen = pmd->pattern_size; + if (main_pmd->pattern_size > otn->longestPatternLen) + otn->longestPatternLen = main_pmd->pattern_size; + for (auto p : pmv) + fpAddAlternatePatterns(sc, pg, otn, p, fp); return 0; } @@ -1617,4 +1636,3 @@ static void print_fp_info( pm_type_strings[pmd->pm_type], pattern_length, txt.c_str(), hex.c_str(), opts.c_str()); } - diff --git a/src/detection/fp_utils.cc b/src/detection/fp_utils.cc index efb53c821..b5841758b 100644 --- a/src/detection/fp_utils.cc +++ b/src/detection/fp_utils.cc @@ -290,12 +290,13 @@ bool FpSelector::is_better_than(FpSelector& rhs, bool srvc, RuleDirection dir) // public methods //-------------------------------------------------------------------------- -PatternMatchData* get_fp_content(OptTreeNode* otn, OptFpList*& next, bool srvc) +PatternMatchVector get_fp_content(OptTreeNode* otn, OptFpList*& next, bool srvc) { CursorActionType curr_cat = CAT_SET_RAW; FpSelector best; bool content = false; bool fp_only = true; + PatternMatchVector pmds; for (OptFpList* ofl = otn->opt_func; ofl; ofl = ofl->next) { @@ -329,6 +330,13 @@ PatternMatchData* get_fp_content(OptTreeNode* otn, OptFpList*& next, bool srvc) { best = curr; next = ofl->next; + pmds.clear(); + // Add alternate pattern + PatternMatchData* alt_pmd = ofl->ips_opt->get_alternate_pattern(); + if (alt_pmd) + pmds.push_back(alt_pmd); + // Add main pattern last + pmds.push_back(best.pmd); } } @@ -336,17 +344,14 @@ PatternMatchData* get_fp_content(OptTreeNode* otn, OptFpList*& next, bool srvc) { ParseWarning(WARN_RULES, "file rule %u:%u does not have file_data fast pattern", otn->sigInfo.generator, otn->sigInfo.id); - return nullptr; + pmds.clear(); } - if ( best.pmd ) - return best.pmd; - - if ( content ) + if ( content && !best.pmd) ParseWarning(WARN_RULES, "content based rule %u:%u has no eligible fast pattern", otn->sigInfo.generator, otn->sigInfo.id); - return nullptr; + return pmds; } //-------------------------------------------------------------------------- diff --git a/src/detection/fp_utils.h b/src/detection/fp_utils.h index 1f4d07c4d..7c7465ec5 100644 --- a/src/detection/fp_utils.h +++ b/src/detection/fp_utils.h @@ -22,7 +22,7 @@ #define FP_UTILS_H // fast pattern utilities - +#include #include "framework/ips_option.h" struct OptFpList; @@ -35,7 +35,7 @@ void validate_fast_pattern(OptTreeNode*); int flp_trim(const char* p, int plen, const char** buff); bool set_fp_content(OptTreeNode*); -PatternMatchData* get_fp_content(OptTreeNode*, OptFpList*&, bool srvc); +std::vector get_fp_content(OptTreeNode*, OptFpList*&, bool srvc); #endif diff --git a/src/detection/pattern_match_data.h b/src/detection/pattern_match_data.h index 4cad2b418..bb784b9c1 100644 --- a/src/detection/pattern_match_data.h +++ b/src/detection/pattern_match_data.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "detection/treenodes.h" #include "framework/ips_option.h" // FIXIT-L not a good dependency @@ -80,6 +81,8 @@ struct PatternMatchData bool can_be_fp() const; }; +typedef std::vector PatternMatchVector; + inline bool PatternMatchData::can_be_fp() const { if ( !pattern_buf || !pattern_size ) diff --git a/src/framework/ips_option.h b/src/framework/ips_option.h index f2ad4600a..ed51f1cba 100644 --- a/src/framework/ips_option.h +++ b/src/framework/ips_option.h @@ -88,6 +88,9 @@ public: virtual struct PatternMatchData* get_pattern(int /*proto*/, RuleDirection = RULE_WO_DIR) { return nullptr; } + virtual struct PatternMatchData* get_alternate_pattern() + { return nullptr; } + static int eval(void* v, Cursor& c, Packet* p) { IpsOption* opt = (IpsOption*)v; diff --git a/src/service_inspectors/dce_rpc/ips_dce_iface.cc b/src/service_inspectors/dce_rpc/ips_dce_iface.cc index c947531d8..dfe082047 100644 --- a/src/service_inspectors/dce_rpc/ips_dce_iface.cc +++ b/src/service_inspectors/dce_rpc/ips_dce_iface.cc @@ -202,12 +202,14 @@ public: IpsOption(s_name), version(iface_version), any_frag(iface_any_frag), uuid(iface_uuid) { memset(&pmd, 0, sizeof(pmd)); + memset(&alt_pmd, 0, sizeof(alt_pmd)); } uint32_t hash() const override; bool operator==(const IpsOption&) const override; int eval(Cursor&, Packet*) override; PatternMatchData* get_pattern(int proto, RuleDirection direction) override; + PatternMatchData* get_alternate_pattern() override; ~Dce2IfaceOption(); private: @@ -215,6 +217,7 @@ private: const bool any_frag; const Uuid uuid; PatternMatchData pmd; + PatternMatchData alt_pmd; }; Dce2IfaceOption::~Dce2IfaceOption() @@ -223,6 +226,38 @@ Dce2IfaceOption::~Dce2IfaceOption() { snort_free((char*)pmd.pattern_buf); } + if ( alt_pmd.pattern_buf) + { + snort_free((char*)alt_pmd.pattern_buf); + } +} + +static char* make_pattern_buffer( const Uuid &uuid, DceRpcBoFlag type ) +{ + int index = 0; + char* pattern_buf = (char*)snort_alloc(sizeof(Uuid)); + + uint32_t time32 = DceRpcNtohl(&uuid.time_low, type); + memcpy(&pattern_buf[index], &time32, sizeof(uint32_t)); + index += sizeof(uint32_t); + + uint16_t time16 = DceRpcNtohs(&uuid.time_mid, type); + memcpy(&pattern_buf[index], &time16, sizeof(uint16_t)); + index += sizeof(uint16_t); + + time16 = DceRpcNtohs(&uuid.time_high_and_version, type); + memcpy(&pattern_buf[index], &time16, sizeof(uint16_t)); + index += sizeof(uint16_t); + + pattern_buf[index] = uuid.clock_seq_and_reserved; + index += sizeof(uint8_t); + + pattern_buf[index] = uuid.clock_seq_low; + index += sizeof(uint8_t); + + memcpy(&pattern_buf[index], uuid.node, 6); + + return pattern_buf; } PatternMatchData* Dce2IfaceOption::get_pattern(int proto, RuleDirection direction) @@ -260,7 +295,25 @@ PatternMatchData* Dce2IfaceOption::get_pattern(int proto, RuleDirection directio } return &pmd; } - // FIXIT-L add udp fast pattern + else if (proto == SNORT_PROTO_UDP) + { + pmd.pattern_buf = make_pattern_buffer( uuid, DCERPC_BO_FLAG__LITTLE_ENDIAN ); + pmd.pattern_size = sizeof(Uuid); + alt_pmd.pattern_buf = make_pattern_buffer( uuid, DCERPC_BO_FLAG__BIG_ENDIAN ); + alt_pmd.pattern_size = sizeof(Uuid); + + return &pmd; + } + + return nullptr; +} + +PatternMatchData* Dce2IfaceOption::get_alternate_pattern() +{ + if (alt_pmd.pattern_buf) + { + return &alt_pmd; + } return nullptr; }