From: Russ Combs (rucombs) Date: Fri, 24 Jan 2020 21:30:39 +0000 (+0000) Subject: Merge pull request #1951 in SNORT/snort3 from ~RUCOMBS/snort3:ports_and_services... X-Git-Tag: 3.0.0-268~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=723c0ffaa3d917279e6942115d50d80d5f8c6876;p=thirdparty%2Fsnort3.git Merge pull request #1951 in SNORT/snort3 from ~RUCOMBS/snort3:ports_and_services to master Squashed commit of the following: commit bd7626b4fdfcd27e2502859ea742c89a8460b6db Author: russ Date: Mon Jan 20 07:35:50 2020 -0500 ips: alert service rules check ports commit 1df737255567925932f6c68db0d557edab560688 Author: russ Date: Sat Jan 18 15:28:01 2020 -0500 ips: refactor rule parsing commit 257406547538e5ba728240047f617e494e7f1256 Author: russ Date: Sat Jan 18 11:35:57 2020 -0500 ips: remove dead code from rule parser commit d1a4bf86979b7379ca00ce3265e710d38163cf9b Author: russ Date: Sat Jan 18 07:53:25 2020 -0500 bufferlen: match on total length unless remaining is specified commit 202b4a29e00148ed79143f0a1b80fb79447be71e Author: russ Date: Fri Jan 17 16:16:22 2020 -0500 ips: use service "file" instead of "user" --- diff --git a/src/detection/rtn_checks.cc b/src/detection/rtn_checks.cc index 75745c5a2..29bdb1fe5 100644 --- a/src/detection/rtn_checks.cc +++ b/src/detection/rtn_checks.cc @@ -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; } diff --git a/src/detection/treenodes.h b/src/detection/treenodes.h index f99d9338a..b4f4fa268 100644 --- a/src/detection/treenodes.h +++ b/src/detection/treenodes.h @@ -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 diff --git a/src/ips_options/ips_bufferlen.cc b/src/ips_options/ips_bufferlen.cc index 4d22cbc72..a058c5bd4 100644 --- a/src/ips_options/ips_bufferlen.cc +++ b/src/ips_options/ips_bufferlen.cc @@ -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) diff --git a/src/parser/parse_conf.cc b/src/parser/parse_conf.cc index 9c54f609e..9d18d604c 100644 --- a/src/parser/parse_conf.cc +++ b/src/parser/parse_conf.cc @@ -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; } diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index c154ad5b3..9ae690d9c 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -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); } diff --git a/src/stream/file/file_session.cc b/src/stream/file/file_session.cc index 35fd0cba3..fbf3813af 100644 --- a/src/stream/file/file_session.cc +++ b/src/stream/file/file_session.cc @@ -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); diff --git a/src/target_based/snort_protocols.cc b/src/target_based/snort_protocols.cc index 98102b524..715d64773 100644 --- a/src/target_based/snort_protocols.cc +++ b/src/target_based/snort_protocols.cc @@ -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 diff --git a/src/target_based/snort_protocols.h b/src/target_based/snort_protocols.h index 232a8c823..f7f6b92c6 100644 --- a/src/target_based/snort_protocols.h +++ b/src/target_based/snort_protocols.h @@ -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 }; diff --git a/src/target_based/test/proto_ref_test.cc b/src/target_based/test/proto_ref_test.cc index ebf4ee2f9..5c606ca83 100644 --- a/src/target_based/test/proto_ref_test.cc +++ b/src/target_based/test/proto_ref_test.cc @@ -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