]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1951 in SNORT/snort3 from ~RUCOMBS/snort3:ports_and_services...
authorRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 24 Jan 2020 21:30:39 +0000 (21:30 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 24 Jan 2020 21:30:39 +0000 (21:30 +0000)
Squashed commit of the following:

commit bd7626b4fdfcd27e2502859ea742c89a8460b6db
Author: russ <rucombs@cisco.com>
Date:   Mon Jan 20 07:35:50 2020 -0500

    ips: alert service rules check ports

commit 1df737255567925932f6c68db0d557edab560688
Author: russ <rucombs@cisco.com>
Date:   Sat Jan 18 15:28:01 2020 -0500

    ips: refactor rule parsing

commit 257406547538e5ba728240047f617e494e7f1256
Author: russ <rucombs@cisco.com>
Date:   Sat Jan 18 11:35:57 2020 -0500

    ips: remove dead code from rule parser

commit d1a4bf86979b7379ca00ce3265e710d38163cf9b
Author: russ <rucombs@cisco.com>
Date:   Sat Jan 18 07:53:25 2020 -0500

    bufferlen: match on total length unless remaining is specified

commit 202b4a29e00148ed79143f0a1b80fb79447be71e
Author: russ <rucombs@cisco.com>
Date:   Fri Jan 17 16:16:22 2020 -0500

    ips: use service "file" instead of "user"

src/detection/rtn_checks.cc
src/detection/treenodes.h
src/ips_options/ips_bufferlen.cc
src/parser/parse_conf.cc
src/parser/parse_rule.cc
src/stream/file/file_session.cc
src/target_based/snort_protocols.cc
src/target_based/snort_protocols.h
src/target_based/test/proto_ref_test.cc

index 75745c5a233bd779222c937b04410602028146b8..29bdb1fe5dd101355571b596c56bdc0282b7556f 100644 (file)
@@ -248,7 +248,7 @@ int CheckProto(Packet* p, RuleTreeNode* rtn_idx, RuleFpList*, int)
         /* icmp */ PROTO_BIT__ICMP,
         /* tcp */  PROTO_BIT__TCP | PROTO_BIT__PDU,
         /* udp */  PROTO_BIT__UDP,
-        /* user */ PROTO_BIT__PDU
+        /* file */ PROTO_BIT__FILE | PROTO_BIT__PDU
     };
     return proto_bits[rtn_idx->snort_protocol_id] & p->proto_bits;
 }
index f99d9338a40220d0c522c06609a4318f91238e29..b4f4fa26898bb880470864309cb1bc3d5cbaa2f4 100644 (file)
@@ -131,8 +131,17 @@ struct RuleTreeNode
     bool enabled() const
     { return (flags & ENABLED) != 0; }
 
-    bool user_mode()
+    bool user_mode() const
     { return (flags & USER_MODE) != 0; }
+
+    bool any_src_port() const
+    { return (flags & ANY_SRC_PORT) != 0; }
+
+    bool any_dst_port() const
+    { return (flags & ANY_DST_PORT) != 0; }
+
+    bool any_any_port() const
+    { return any_src_port() and any_dst_port(); }
 };
 
 // one of these for each rule
index 4d22cbc722fbff8f13bbd712863dffa41455e87e..a058c5bd4b952d7c56eac5473a2d2f615fe1fcf5 100644 (file)
@@ -40,9 +40,9 @@ static THREAD_LOCAL ProfileStats lenCheckPerfStats;
 class LenOption : public IpsOption
 {
 public:
-    LenOption(const RangeCheck& c) :
+    LenOption(const RangeCheck& c, bool r) :
         IpsOption(s_name, RULE_OPTION_TYPE_BUFFER_USE)
-    { config = c; }
+    { config = c; relative = r; }
 
     uint32_t hash() const override;
     bool operator==(const IpsOption&) const override;
@@ -51,6 +51,7 @@ public:
 
 private:
     RangeCheck config;
+    bool relative;
 };
 
 //-------------------------------------------------------------------------
@@ -77,14 +78,15 @@ bool LenOption::operator==(const IpsOption& ips) const
         return false;
 
     const LenOption& rhs = (const LenOption&)ips;
-    return ( config == rhs.config );
+    return ( config == rhs.config and relative == rhs.relative );
 }
 
 IpsOption::EvalStatus LenOption::eval(Cursor& c, Packet*)
 {
     RuleProfile profile(lenCheckPerfStats);
+    unsigned n = relative ? c.length() : c.size();
 
-    if ( config.eval(c.length()) )
+    if ( config.eval(n) )
         return MATCH;
 
     return NO_MATCH;
@@ -99,7 +101,10 @@ IpsOption::EvalStatus LenOption::eval(Cursor& c, Packet*)
 static const Parameter s_params[] =
 {
     { "~range", Parameter::PT_INTERVAL, RANGE, nullptr,
-      "check that length of current buffer is in given range" },
+      "check that total length of current buffer is in given range" },
+
+    { "relative", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "use remaining length (from current position) instead of total length" },
 
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
@@ -120,6 +125,7 @@ public:
 
 public:
     RangeCheck data;
+    bool relative = false;
 };
 
 bool LenModule::begin(const char*, int, SnortConfig*)
@@ -130,10 +136,16 @@ bool LenModule::begin(const char*, int, SnortConfig*)
 
 bool LenModule::set(const char*, Value& v, SnortConfig*)
 {
-    if ( !v.is("~range") )
+    if ( v.is("~range") )
+        return data.validate(v.get_string(), RANGE);
+
+    if ( v.is("relative") )
+        relative = true;
+
+    else
         return false;
 
-    return data.validate(v.get_string(), RANGE);
+    return true;
 }
 
 //-------------------------------------------------------------------------
@@ -153,7 +165,7 @@ static void mod_dtor(Module* m)
 static IpsOption* len_ctor(Module* p, OptTreeNode*)
 {
     LenModule* m = (LenModule*)p;
-    return new LenOption(m->data);
+    return new LenOption(m->data, m->relative);
 }
 
 static void len_dtor(IpsOption* p)
index 9c54f609ed360529cd982ab81b2013ce170f8f3a..9d18d604c03a6072d7a62f56bb5492d46f68edf5 100644 (file)
@@ -248,7 +248,7 @@ void add_service_to_otn(SnortConfig* sc, OptTreeNode* otn, const char* svc_name)
         add_service_to_otn(sc, otn, "pop3");
         add_service_to_otn(sc, otn, "imap");
         add_service_to_otn(sc, otn, "smtp");
-        add_service_to_otn(sc, otn, "user");
+        add_service_to_otn(sc, otn, "file");
         return;
     }
 
index c154ad5b387a187f6997e9d319603cbe38ea141a..9ae690d9cc3b2e6acce233bd85c872f2cd24f47e 100644 (file)
@@ -148,28 +148,24 @@ static int FinishPortListRule(
         prc = &svcCnt;
     }
 
-    /* Count rules with both src and dst specific ports */
-    if (!(rtn->flags & RuleTreeNode::ANY_DST_PORT) && !(rtn->flags & RuleTreeNode::ANY_SRC_PORT))
-    {
+    if ( !rtn->any_src_port() and !rtn->any_dst_port() )
         prc->both++;
-    }
 
     /* If not an any-any rule test for port bleedover, if we are using a
      * single rule group, don't bother */
-    if (!fp->get_single_rule_group() &&
-        (rtn->flags & (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT)) != (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT))
+    if ( !fp->get_single_rule_group() and !rtn->any_any_port() )
     {
         int dst_cnt = 0;
         int src_cnt = 0;
 
-        if (!(rtn->flags & RuleTreeNode::ANY_SRC_PORT))
+        if ( !rtn->any_src_port() )
         {
             src_cnt = PortObjectPortCount(rtn->src_portobject);
             if (src_cnt >= fp->get_bleed_over_port_limit())
                 large_port_group = 1;
         }
 
-        if (!(rtn->flags & RuleTreeNode::ANY_DST_PORT))
+        if ( !rtn->any_dst_port() )
         {
             dst_cnt = PortObjectPortCount(rtn->dst_portobject);
             if (dst_cnt >= fp->get_bleed_over_port_limit())
@@ -198,46 +194,18 @@ static int FinishPortListRule(
      * any-any port rules...
      * If we have an any-any rule or a large port group or
      * were using a single rule group we make it an any-any rule. */
-    if (((rtn->flags & (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT)) == (RuleTreeNode::ANY_DST_PORT|RuleTreeNode::ANY_SRC_PORT)) ||
-        large_port_group || fp->get_single_rule_group())
+    if ( rtn->any_any_port() or large_port_group or fp->get_single_rule_group() )
     {
         if (snort_protocol_id == SNORT_PROTO_IP)
         {
-            /* Add the IP rules to the higher level app protocol groups, if they apply
-             * to those protocols.  All IP rules should have any-any port descriptors
-             * and fall into this test.  IP rules that are not tcp/udp/icmp go only into the
-             * IP table */
-            switch ( otn->snort_protocol_id )
-            {
-            case SNORT_PROTO_IP:    /* Add to all ip proto any port tables */
-                PortObjectAddRule(port_tables->icmp.any, otn->ruleIndex);
-                icmpCnt.any++;
-
-                PortObjectAddRule(port_tables->tcp.any, otn->ruleIndex);
-                tcpCnt.any++;
-
-                PortObjectAddRule(port_tables->udp.any, otn->ruleIndex);
-                udpCnt.any++;
-                break;
-
-            case SNORT_PROTO_ICMP:
-                PortObjectAddRule(port_tables->icmp.any, otn->ruleIndex);
-                icmpCnt.any++;
-                break;
-
-            case SNORT_PROTO_TCP:
-                PortObjectAddRule(port_tables->tcp.any, otn->ruleIndex);
-                tcpCnt.any++;
-                break;
-
-            case SNORT_PROTO_UDP:
-                PortObjectAddRule(port_tables->udp.any, otn->ruleIndex);
-                udpCnt.any++;
-                break;
-
-            default:
-                break;
-            }
+            PortObjectAddRule(port_tables->icmp.any, otn->ruleIndex);
+            icmpCnt.any++;
+
+            PortObjectAddRule(port_tables->tcp.any, otn->ruleIndex);
+            tcpCnt.any++;
+
+            PortObjectAddRule(port_tables->udp.any, otn->ruleIndex);
+            udpCnt.any++;
         }
         /* For all protocols-add to the any any group */
         PortObjectAddRule(aaObject, otn->ruleIndex);
@@ -247,7 +215,7 @@ static int FinishPortListRule(
     }
 
     /* add rule index to dst table if we have a specific dst port or port list */
-    if (!(rtn->flags & RuleTreeNode::ANY_DST_PORT))
+    if ( !rtn->any_dst_port() )
     {
         prc->dst++;
 
@@ -290,7 +258,7 @@ static int FinishPortListRule(
     }
 
     /* add rule index to src table if we have a specific src port or port list */
-    if (!(rtn->flags & RuleTreeNode::ANY_SRC_PORT))
+    if ( !rtn->any_src_port() )
     {
         prc->src++;
         PortObject* pox = PortTableFindInputPortObjectPorts(srcTable, rtn->src_portobject);
@@ -793,15 +761,17 @@ static void SetupRTNFuncList(RuleTreeNode* rtn)
 
     else
     {
-        PortToFunc(rtn, (rtn->flags & RuleTreeNode::ANY_DST_PORT) ? 1 : 0, 0, DST);
-        PortToFunc(rtn, (rtn->flags & RuleTreeNode::ANY_SRC_PORT) ? 1 : 0, 0, SRC);
+        PortToFunc(rtn, (rtn->any_dst_port() ? 1 : 0), 0, DST);
+        PortToFunc(rtn, (rtn->any_src_port() ? 1 : 0), 0, SRC);
 
         AddrToFunc(rtn, SRC);
         AddrToFunc(rtn, DST);
     }
 
-    if ( rtn->snort_protocol_id < SNORT_PROTO_MAX )
+    if ( rtn->snort_protocol_id < SNORT_PROTO_FILE )
         AddRuleFuncToList(CheckProto, rtn);
+    else
+        rtn->flags |= RuleTreeNode::USER_MODE;
 
     AddRuleFuncToList(RuleListEnd, rtn);
 }
index 35fd0cba3e353a2ee7edebb751039255461f8797..fbf3813afffd4f16c2e3271045c85f9bdada7370 100644 (file)
@@ -77,7 +77,7 @@ int FileSession::process(Packet* p)
 {
     Profile profile(file_ssn_stats);
 
-    p->flow->ssn_state.snort_protocol_id = SNORT_PROTO_USER;
+    p->flow->ssn_state.snort_protocol_id = SNORT_PROTO_FILE;
     StreamFileConfig* c = get_file_cfg(p->flow->ssn_server);
 
     FileFlows* file_flows = FileFlows::get_file_flows(p->flow);
index 98102b5248cd789888e64e73e80a394aa24dd7e2..715d64773fe1f14a822e3c755e229c6c5783cecb 100644 (file)
@@ -112,7 +112,7 @@ void ProtocolReference::init(ProtocolReference* old_proto_ref)
         ok = ( add("icmp") == SNORT_PROTO_ICMP ) and ok;
         ok = ( add("tcp") == SNORT_PROTO_TCP ) and ok;
         ok = ( add("udp") == SNORT_PROTO_UDP ) and ok;
-        ok = ( add("user") == SNORT_PROTO_USER ) and ok;
+        ok = ( add("file") == SNORT_PROTO_FILE ) and ok;
         assert(ok);
     }
     else
index 232a8c823273e546512a05d936553af70828b81f..f7f6b92c652aa176c81f763b6a2563e7ca630ddc 100644 (file)
@@ -40,7 +40,7 @@ enum SnortProtocols : SnortProtocolId
     SNORT_PROTO_ICMP,
     SNORT_PROTO_TCP,
     SNORT_PROTO_UDP,
-    SNORT_PROTO_USER,
+    SNORT_PROTO_FILE,
     SNORT_PROTO_MAX
 };
 
index ebf4ee2f9f9f0d32bbc1165db20d199c1ef7db37..5c606ca836f2cb4241a1ddf135ee49ca95c3cba3 100644 (file)
@@ -78,7 +78,7 @@ TEST(protocol_reference, service_protocols)
     CHECK( is_service_protocol(t3) );
 }
 
-// Builtin Protocols (ip, icmp, tcp, udp, user)
+// Builtin Protocols (ip, icmp, tcp, udp, file)
 //
 // Verify normal behaviour of the builtin protocols.
 //   1. Check the builtin protocols match the hardcoded ID's
@@ -120,11 +120,11 @@ TEST(protocol_reference, builtin_protocols)
     CHECK( is_builtin_protocol(udp) );
     CHECK( !is_service_protocol(udp) );
 
-    SnortProtocolId user = refs.add("user");
-    CHECK( user == SNORT_PROTO_USER );
-    CHECK( !is_network_protocol(user) );
-    CHECK( is_builtin_protocol(user) );
-    CHECK( is_service_protocol(user) );
+    SnortProtocolId file = refs.add("file");
+    CHECK( file == SNORT_PROTO_FILE );
+    CHECK( !is_network_protocol(file) );
+    CHECK( is_builtin_protocol(file) );
+    CHECK( is_service_protocol(file) );
 }
 
 // Find none