]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #719 in SNORT/snort3 from ecb_alt_fast_pattern to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 23 Nov 2016 12:46:31 +0000 (07:46 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 23 Nov 2016 12:46:31 +0000 (07:46 -0500)
Squashed commit of the following:

commit b89eb774fcc4a5ac076304db6dab6dd31f5ddf99
Author: mdagon <mdagon@cisco.com>
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

src/detection/fp_create.cc
src/detection/fp_utils.cc
src/detection/fp_utils.h
src/detection/pattern_match_data.h
src/framework/ips_option.h
src/service_inspectors/dce_rpc/ips_dce_iface.cc

index 0e1d4c5b99a8ec3b9b16090e17c598d741e08549..d9b1bbaf608ca60f7056b150b028934bfdf9ec72 100644 (file)
@@ -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());
 }
-
index efb53c8217d6692787237ea8e4d320867a3e2c72..b5841758b0cee1a02b90166d4105c9273ef6b5ae 100644 (file)
@@ -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;
 }
 
 //--------------------------------------------------------------------------
index 1f4d07c4d3e07c2d624c461efb00ec812f73bdfa..7c7465ec52f31b2474816036fd31d56b70093cc9 100644 (file)
@@ -22,7 +22,7 @@
 #define FP_UTILS_H
 
 // fast pattern utilities
-
+#include <vector>
 #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 <PatternMatchData*> get_fp_content(OptTreeNode*, OptFpList*&, bool srvc);
 
 #endif
 
index 4cad2b418c1cbeb5eed55a284f403ea40e1a64ed..bb784b9c1c4c0ebfc7f7a68d59be431007afbdf7 100644 (file)
@@ -24,6 +24,7 @@
 #include <assert.h>
 #include <ctype.h>
 #include <sys/time.h>
+#include <vector>
 
 #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<PatternMatchData*> PatternMatchVector;
+
 inline bool PatternMatchData::can_be_fp() const
 {
     if ( !pattern_buf || !pattern_size )
index f2ad4600ab67a12bc9a5c5b64a4c33af77c28166..ed51f1cba2f638b64da5a463dfed518842ad4dba 100644 (file)
@@ -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;
index c947531d8f9cd28bbb5cd6cde077d5dd7f555c71..dfe0820476cfdc8739ebe752336bcd57aa7cdf66 100644 (file)
@@ -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;
 }