]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
fix so rule parsing
authorRuss Combs <rucombs@cisco.com>
Mon, 11 Aug 2014 00:33:14 +0000 (20:33 -0400)
committerRuss Combs <rucombs@cisco.com>
Mon, 11 Aug 2014 00:33:14 +0000 (20:33 -0400)
ChangeLog
extra/src/so_rules/sid_18758.h
extra/src/so_rules/sid_18758.txt
src/managers/so_manager.cc
src/parser/parse_rule.cc
src/parser/parse_rule.h
src/parser/parse_stream.cc

index 97ee92e70c9a0e7e62f4dd9c40a1654c12a479b6..f9913e833be5523eb31221d75dc671f021e37108 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 111
 -- fix up luajit ips rule option
 -- fix up rule loading
+-- fixed so rule parsing
 
 110
 -- converted rule meta options to ips options (w/o eval)
index 1a6551006bdb1c912f950e4aea7636cd8a8274a2..772743643a3e580ed448a4a44aba511c76d15b00 100644 (file)
@@ -1,29 +1,34 @@
 unsigned char sid_18758_gz[] = {
-  0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x2d, 0x8e,
-  0x5f, 0x6b, 0xc2, 0x40, 0x10, 0xc4, 0xdf, 0xfb, 0x29, 0x96, 0x90, 0x07,
-  0x05, 0x35, 0xb4, 0x45, 0x2a, 0x17, 0x68, 0x69, 0x69, 0x44, 0xc1, 0x7f,
-  0xd8, 0x60, 0x5b, 0x6a, 0x09, 0xe7, 0x65, 0xa3, 0x4b, 0x2f, 0xb9, 0xf4,
-  0xf6, 0x12, 0x15, 0xfc, 0xf0, 0x4d, 0xa4, 0x4f, 0xcb, 0xfc, 0x66, 0x99,
-  0x19, 0xa9, 0xd1, 0x3a, 0x70, 0xaa, 0x04, 0x7f, 0xb2, 0x9c, 0x47, 0xc9,
-  0x22, 0x8a, 0x41, 0x16, 0x67, 0xe8, 0x3f, 0x82, 0x1f, 0x7d, 0xc4, 0xd1,
-  0x7a, 0xf1, 0x3c, 0xbb, 0x42, 0x7f, 0x12, 0xc7, 0xab, 0x64, 0xb5, 0x5c,
-  0xc7, 0x6f, 0xd0, 0xc9, 0x79, 0x2f, 0xbc, 0xf1, 0x74, 0x16, 0xf5, 0xa7,
-  0xaf, 0xd1, 0x22, 0x9e, 0x8e, 0x3f, 0x61, 0x4e, 0xca, 0x1a, 0x36, 0x99,
-  0x83, 0x77, 0x2a, 0x52, 0x73, 0x64, 0xd8, 0x10, 0x57, 0x52, 0xc3, 0x8b,
-  0x64, 0x52, 0xc0, 0xca, 0x52, 0xe9, 0x20, 0x23, 0x8d, 0xd0, 0xb8, 0x85,
-  0x36, 0x32, 0x05, 0x8b, 0xbf, 0x15, 0xb2, 0xf3, 0x42, 0xc8, 0xd1, 0xc9,
-  0x54, 0x3a, 0x29, 0x18, 0x6d, 0x4d, 0x0a, 0xe1, 0xe0, 0x5c, 0x19, 0x36,
-  0x0f, 0x19, 0x5a, 0x2c, 0x14, 0x8a, 0xca, 0xea, 0x1e, 0x16, 0x83, 0x23,
-  0xfd, 0x50, 0x89, 0x29, 0xc9, 0x81, 0xb1, 0xfb, 0xa0, 0x55, 0xc1, 0x66,
-  0xc7, 0x21, 0x28, 0x2d, 0x99, 0xdd, 0xb9, 0x44, 0x91, 0x13, 0xab, 0xbe,
-  0x54, 0x8e, 0x6a, 0x72, 0xe7, 0x10, 0x98, 0x52, 0x71, 0x3b, 0x7a, 0x18,
-  0x8e, 0xda, 0xb0, 0x5a, 0x34, 0x87, 0x4d, 0x83, 0xee, 0x2f, 0xff, 0x30,
-  0xd3, 0xe6, 0x28, 0x9c, 0x49, 0xda, 0x5e, 0xb4, 0xbd, 0x66, 0x8d, 0xdc,
-  0x69, 0xe2, 0x03, 0xa6, 0xe1, 0x75, 0x43, 0x52, 0x59, 0x6a, 0xe2, 0x4d,
-  0xe1, 0xb0, 0x70, 0xc2, 0x1b, 0xd4, 0x3b, 0xf6, 0x7a, 0x50, 0x18, 0x25,
-  0x19, 0x43, 0x28, 0x95, 0x45, 0xe1, 0x05, 0xdb, 0xd3, 0x1d, 0x36, 0x46,
-  0xe7, 0x6b, 0xfb, 0xb4, 0x3d, 0x0d, 0x55, 0x23, 0xb3, 0xef, 0x8b, 0xdf,
-  0x0d, 0x38, 0x27, 0xaf, 0x2d, 0x14, 0x58, 0x4b, 0x1d, 0x42, 0xf7, 0xe6,
-  0x0f, 0x45, 0xc2, 0xce, 0x14, 0x6e, 0x01, 0x00, 0x00
+  0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x3d, 0x8f,
+  0x6f, 0x6b, 0xdb, 0x30, 0x10, 0xc6, 0xdf, 0xe7, 0x53, 0x1c, 0x5e, 0x5e,
+  0xb4, 0x90, 0x3f, 0x6c, 0xa3, 0xb4, 0xa8, 0xb0, 0xb1, 0x31, 0x97, 0x06,
+  0xda, 0xb4, 0x74, 0xa6, 0xdb, 0x58, 0x46, 0x38, 0xcb, 0xe7, 0xe4, 0x98,
+  0x22, 0x79, 0xba, 0xb3, 0xd3, 0x40, 0x3f, 0xfc, 0xe4, 0x3a, 0xad, 0xde,
+  0x9c, 0xee, 0x7e, 0x8f, 0x9e, 0xd3, 0x83, 0x8e, 0xa2, 0x82, 0xda, 0x06,
+  0xc6, 0xd7, 0x77, 0xb7, 0xf9, 0x7a, 0x99, 0x17, 0x80, 0xfe, 0x00, 0xd3,
+  0x4f, 0x30, 0xce, 0x7f, 0x16, 0xf9, 0xc3, 0xf2, 0xcb, 0xcd, 0xcb, 0x70,
+  0x7c, 0x5d, 0x14, 0xf7, 0xeb, 0xfb, 0xbb, 0x87, 0xe2, 0xfb, 0xe8, 0x64,
+  0x04, 0xe9, 0xec, 0x64, 0x63, 0xb2, 0xab, 0xc5, 0x4d, 0x3e, 0x5d, 0x7c,
+  0xcb, 0x97, 0xc5, 0xe2, 0xea, 0x17, 0xdc, 0xb2, 0x8d, 0x41, 0x42, 0xad,
+  0xf0, 0x83, 0x7d, 0x15, 0xf6, 0x02, 0x8f, 0x2c, 0x2d, 0x3a, 0xf8, 0x8a,
+  0xc2, 0x16, 0xc4, 0x46, 0x6e, 0x14, 0x6a, 0x76, 0x04, 0x89, 0x7a, 0x17,
+  0xb0, 0x82, 0x48, 0xff, 0x5a, 0x12, 0xcd, 0x2e, 0x07, 0x53, 0x52, 0xac,
+  0x50, 0xd1, 0x08, 0xc5, 0x8e, 0x2d, 0xc1, 0x56, 0xb5, 0x19, 0x50, 0xa4,
+  0x9a, 0x22, 0x79, 0x4b, 0xa6, 0x8d, 0x6e, 0x42, 0x7e, 0xb6, 0xe7, 0xbf,
+  0xdc, 0x50, 0xc5, 0x38, 0x0b, 0x71, 0x33, 0xef, 0xbb, 0xf9, 0x63, 0x29,
+  0x83, 0xd8, 0x3a, 0x14, 0xd1, 0x43, 0x43, 0x66, 0xc7, 0x62, 0xa7, 0x68,
+  0x95, 0x3b, 0xd6, 0xc3, 0x00, 0x85, 0x2b, 0xf3, 0xfe, 0xe2, 0xfc, 0xec,
+  0xe2, 0xd5, 0xb8, 0x33, 0xc7, 0xab, 0x84, 0x84, 0x3e, 0x3e, 0x1f, 0xe1,
+  0x3b, 0xa0, 0x8e, 0xe2, 0x41, 0xb7, 0xec, 0x37, 0x80, 0x65, 0xe8, 0x08,
+  0xb0, 0x69, 0x08, 0xa3, 0x00, 0x7b, 0x10, 0x6d, 0xcb, 0x24, 0xd1, 0x2d,
+  0x41, 0x1d, 0x9c, 0x0b, 0xfb, 0x5e, 0x55, 0x91, 0x52, 0xda, 0x15, 0x3c,
+  0x84, 0xa6, 0x2f, 0x02, 0x18, 0x09, 0x7c, 0xd0, 0xb7, 0x17, 0xfd, 0x9a,
+  0x3a, 0xa9, 0x8d, 0x86, 0x75, 0x1f, 0x92, 0xe2, 0x24, 0xc5, 0xc7, 0xd2,
+  0xb1, 0x6c, 0xa9, 0x1a, 0xbe, 0xd1, 0x87, 0x5e, 0xb7, 0x91, 0x8f, 0x59,
+  0x82, 0x57, 0xf2, 0x6a, 0xb2, 0x59, 0x57, 0x4a, 0x36, 0x49, 0x6e, 0x16,
+  0x85, 0x06, 0xd6, 0xd8, 0x48, 0x26, 0x9b, 0xaf, 0x9e, 0x3e, 0x50, 0x82,
+  0x27, 0xbf, 0x57, 0x9f, 0x57, 0x4f, 0x67, 0x36, 0xb5, 0xf5, 0x9f, 0xe7,
+  0xf1, 0xe9, 0x5c, 0x76, 0x9c, 0xbd, 0x26, 0x33, 0xd4, 0xa1, 0xbb, 0x1c,
+  0x9d, 0x8e, 0xfe, 0x03, 0x51, 0xaa, 0xf2, 0x71, 0xf4, 0x01, 0x00, 0x00
 };
-unsigned int sid_18758_gz_len = 309;
+unsigned int sid_18758_gz_len = 372;
index b6399f393313d2404de8d00721000cdb45914fae..4487d08507ad68958056e47812ea9076945acf49 100644 (file)
@@ -1 +1,17 @@
-alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"FILE-IDENTIFY Microsoft Windows Visual Basic script file download request"; metadata:service http; reference:url,en.wikipedia.org/wiki/Vbs; classtype:misc-activity; sid:18758; rev:8; soid:3|18758; flow:to_server,established; http_uri; content:".vbs", nocase; pcre:"/\x2evbs([\?\x5c\x2f]|$)/smi"; so:eval; )
+alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS
+(
+    msg:"FILE-IDENTIFY Microsoft Windows Visual Basic script file download request";
+    metadata:service http;
+    reference:url,en.wikipedia.org/wiki/Vbs;
+    classtype:misc-activity;
+    sid:18758;
+    rev:8;
+    soid:3|18758;
+# everything above appears in stub
+# the following detection options are not in stub
+    flow:to_server,established;
+    http_uri;
+    content:".vbs", nocase;
+    pcre:"/\x2evbs([\?\x5c\x2f]|$)/smi";
+    so:eval;
+)
index 8d7ea8d4836ec4bde614322d68abf252a41eb4d4..15dcb8188f042f5e2cbdd07b17f8ae73557bbd8f 100644 (file)
@@ -136,10 +136,10 @@ const char* SoManager::get_so_options(const char* soid)
     // FIXIT this approach won't tolerate spaces and might get
     // fooled by matching content (should it precede this)
     char opt[32];
-    snprintf(opt, sizeof(opt), "; soid:%s", soid);
+    snprintf(opt, sizeof(opt), "soid:%s;", soid);
     const char* s = strstr(rule, opt);
 
-    return s ? s + strlen(opt) + 1 : nullptr;
+    return s ? s + strlen(opt) : nullptr;
 }
 
 SoEvalFunc SoManager::get_so_eval(const char* soid, const char* so, void** data)
index bcb856674c23074a573cd2a1769f02bbe88fe223..e9ce0a26d6809045e4b5544b8f1a36a97ba17d3b 100644 (file)
@@ -1427,26 +1427,28 @@ OptTreeNode* parse_rule_open(SnortConfig*, RuleTreeNode& rtn)
     return otn;
 }
 
-void parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* otn)
+const char* parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* otn)
 {
+    static bool entered = false;
     const char* so_opts = nullptr;
 
-    if ( otn->soid )
+    if ( entered )
+        entered = false;
+
+    else if ( otn->soid )
     {
         so_opts = SoManager::get_so_options(otn->soid);
 
         if ( !so_opts )
             ParseError("SO rule %s not loaded.", otn->soid);
-
-        otn->sigInfo.generator = 3;  // FIXIT why isn't this set already? (don't hardcode)
+        else
+        {
+            otn->sigInfo.generator = 3;  // FIXIT why isn't this set already? (don't hardcode)
+            entered = true;
+            return so_opts;
+        }
     }
     
-    // FIXIT must parse so_opts (to right of soid)
-    if ( so_opts )
-    {
-        printf("so_opts = %s\n", so_opts);
-    }
-
     /* The IPs in the test node get free'd in ProcessHeadNode if there is
      * already a matching RTN.  The portobjects will get free'd when the
      * port var table is free'd */
@@ -1465,7 +1467,7 @@ void parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* otn)
         {
             /* We are keeping the old/dup OTN and trashing the new one
              * we just created - it's free'd in the remove dup function */
-            return;
+            return nullptr;
         }
     }
     //otn->num_detection_opts += num_detection_opts; FIXIT tbd
@@ -1533,5 +1535,7 @@ void parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* otn)
      */
     if (FinishPortListRule(sc->port_tables, new_rtn, otn, rtn.proto, &pe, sc->fast_pattern_config))
         ParseError("Failed to finish a port list rule.");
+
+    return nullptr;
 }
 
index 8c801898f77782ee389d56be36a1fba749501db8..036ff47211d2bf630e5604e774d8627a36746b3e 100644 (file)
@@ -45,7 +45,7 @@ void parse_rule_opt_set(
     SnortConfig*, const char* key, const char* opt, const char* val);
 void parse_rule_opt_end(SnortConfig*, const char* key, OptTreeNode*);
 OptTreeNode* parse_rule_open(SnortConfig*, RuleTreeNode&);
-void parse_rule_close(SnortConfig*, RuleTreeNode&, OptTreeNode*);
+const char* parse_rule_close(SnortConfig*, RuleTreeNode&, OptTreeNode*);
 
 int get_rule_count();
 
index b121b4a3319756369c7aa87032ebf25faf66f3ba..eddbcbe39554fb465324624afbd5305e9a919879 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include <istream>
+#include <sstream>
 #include <string>
 using namespace std;
 
@@ -297,8 +298,13 @@ struct RuleParseState
     string key;
     string opt;
     string val;
+
+    RuleParseState()
+    { otn = nullptr; };
 };
 
+static void parse_body(const char*, RuleParseState&, struct SnortConfig*);
+
 static void exec(
     FsmAction act, string& tok,
     RuleParseState& rps, SnortConfig* sc)
@@ -337,10 +343,17 @@ static void exec(
         rps.otn = parse_rule_open(sc, rps.rtn);
         break;
     case FSM_EOB:
-        parse_rule_close(sc, rps.rtn, rps.otn);
-        rps.otn = nullptr;
-        rules++;
+    {
+        const char* extra = parse_rule_close(sc, rps.rtn, rps.otn);
+        if ( extra )
+            parse_body(extra, rps, sc);
+        else
+        {
+            rps.otn = nullptr;
+            rules++;
+        }
         break;
+    }
     case FSM_KEY:
         parse_rule_opt_begin(sc, tok.c_str());
         rps.key = tok;
@@ -392,11 +405,40 @@ static void exec(
     }
 }
 
-int parse_stream(istream& is, struct SnortConfig* sc)
+// parse_body() is called at the end of a stub rule to parse the detection
+// options in an so rule.  similar to parse_stream() except we start in a
+// different state.
+static void parse_body(const char* extra, RuleParseState& rps, struct SnortConfig* sc)
 {
+    stringstream is(extra);
+
     string tok;
     TokenType type;
     bool esc = false;
+
+    int num = 8;
+    const char* punct = "(:,;)";
+
+    while ( (type = get_token(is, tok, punct, esc)) )
+    {
+        ++tokens;
+        const State* s = get_state(num, type, tok);
+
+        exec(s->action, tok, rps, sc);
+        num = s->next;
+        esc = (rps.key == "pcre");
+
+        if ( s->punct )
+            punct = s->punct;
+    }
+}
+
+void parse_stream(istream& is, struct SnortConfig* sc)
+{
+    string tok;
+    TokenType type;
+    bool esc = false;
+
     int num = 0;
     const char* punct = fsm[0].punct;
     RuleParseState rps;
@@ -420,6 +462,5 @@ int parse_stream(istream& is, struct SnortConfig* sc)
     //printf("lines = %d, comments = %d\n", lines, comments);
     //printf("rules = %d, keys = %d\n", rules, keys);
     //printf("lists = %d, strings = %d\n", lists, strings);
-
-    return 0;
 }
+