From: Lukasz Czarnik -X (lczarnik - SOFTSERVE INC at Cisco) Date: Wed, 28 Feb 2024 20:12:54 +0000 (+0000) Subject: Pull request #4215: appid: change eve pattern matching logic X-Git-Tag: 3.1.82.0~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3bf02766f8db386149bfa2a95d938c9db3a0c434;p=thirdparty%2Fsnort3.git Pull request #4215: appid: change eve pattern matching logic Merge in SNORT/snort3 from ~LCZARNIK/snort3:eve to master Squashed commit of the following: commit fcc27614cacf8e7a712429522b35e9e41522c07f Author: Lukasz Czarnik Date: Tue Feb 20 08:27:01 2024 -0500 appid: change eve pattern matching logic --- diff --git a/src/network_inspectors/appid/client_plugins/eve_ca_patterns.cc b/src/network_inspectors/appid/client_plugins/eve_ca_patterns.cc index 66c501013..d9d6a85f7 100644 --- a/src/network_inspectors/appid/client_plugins/eve_ca_patterns.cc +++ b/src/network_inspectors/appid/client_plugins/eve_ca_patterns.cc @@ -35,10 +35,12 @@ using namespace snort; using namespace std; void EveCaPatternMatchers::add_eve_ca_pattern(AppId app_id, const string& pattern_str, - uint8_t confidence, const string& detector) + uint8_t confidence, const string& detector, bool literal) { auto match = find_if(eve_ca_load_list.begin(), eve_ca_load_list.end(), - [pattern_str] (EveCaPattern* eve_ca) { return eve_ca->pattern == pattern_str; }); + [pattern_str, literal] (EveCaPattern* eve_ca) + { return (eve_ca->pattern == pattern_str) and (eve_ca->literal == literal); }); + if (match != eve_ca_load_list.end()) { if ((*match)->app_id != app_id) @@ -48,7 +50,7 @@ void EveCaPatternMatchers::add_eve_ca_pattern(AppId app_id, const string& patter } else { - EveCaPattern* new_eve_ca_pattern = new EveCaPattern(app_id, pattern_str, confidence); + EveCaPattern* new_eve_ca_pattern = new EveCaPattern(app_id, pattern_str, confidence, literal); eve_ca_load_list.push_back(new_eve_ca_pattern); } } @@ -71,19 +73,22 @@ AppId EveCaPatternMatchers::match_eve_ca_pattern(const string& pattern, for (auto &mp : *eve_ca_match_list) { - if (mp->pattern.size() == pattern.size()) + const bool confident = (reported_confidence >= mp->confidence); + const bool same_size = (mp->pattern.size() == pattern.size()); + + if (not confident) + continue; + + if (mp->literal) { - if (reported_confidence >= mp->confidence) + if (same_size) best_match = mp; - else if (best_match) - best_match = nullptr; - break; } - else if ((reported_confidence >= mp->confidence) and - (!best_match or (mp->pattern.size() > best_match->pattern.size()))) + + if (not mp->literal) { - best_match = mp; - continue; + if (!best_match or (mp->pattern.size() > best_match->pattern.size())) + best_match = mp; } } AppId ret_app_id = APP_ID_NONE; @@ -106,7 +111,7 @@ void EveCaPatternMatchers::finalize_patterns() { for (auto& p : eve_ca_load_list) { - eve_ca_pattern_matcher.add(p->pattern.data(), p->pattern.size(), p, true); + eve_ca_pattern_matcher.add(p->pattern.data(), p->pattern.size(), p, true, p->literal); #ifdef REG_TEST AppIdInspector* inspector = diff --git a/src/network_inspectors/appid/client_plugins/eve_ca_patterns.h b/src/network_inspectors/appid/client_plugins/eve_ca_patterns.h index b83c7d398..cb23e2db4 100644 --- a/src/network_inspectors/appid/client_plugins/eve_ca_patterns.h +++ b/src/network_inspectors/appid/client_plugins/eve_ca_patterns.h @@ -31,9 +31,10 @@ struct EveCaPattern const AppId app_id; const std::string pattern; const uint8_t confidence; + bool literal; - EveCaPattern(AppId id, const std::string& name, uint8_t conf) : app_id(id), pattern(name), - confidence(conf) {} + EveCaPattern(AppId id, const std::string& name, uint8_t conf, bool literal = true) : app_id(id), pattern(name), + confidence(conf), literal(literal) {} ~EveCaPattern() {} }; @@ -45,7 +46,7 @@ class EveCaPatternMatchers public: ~EveCaPatternMatchers(); AppId match_eve_ca_pattern(const std::string&, uint8_t); - void add_eve_ca_pattern(AppId, const std::string&, uint8_t, const std::string&); + void add_eve_ca_pattern(AppId, const std::string&, uint8_t, const std::string&, bool literal = true); void finalize_patterns(); void reload_patterns(); unsigned get_pattern_count(); diff --git a/src/network_inspectors/appid/lua_detector_api.cc b/src/network_inspectors/appid/lua_detector_api.cc index 1760f14b2..23e0105a1 100644 --- a/src/network_inspectors/appid/lua_detector_api.cc +++ b/src/network_inspectors/appid/lua_detector_api.cc @@ -1187,7 +1187,51 @@ static int add_process_to_client_mapping(lua_State* L) const std::string detector_name = ud->get_detector()->get_name(); ud->get_odp_ctxt().get_eve_ca_matchers().add_eve_ca_pattern(appid, process_name, - process_score, detector_name); + process_score, detector_name, true); + + ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appid); + + return 0; +} + +/** Add a fp process name regex to client app mapping. + * @param Lua_State* - Lua state variable. + * @param appid/stack - the AppId to map the fp data to + * @param process_name/stack - encrypted fingerprint process name regex + * @param process_score - encrypted fingerprint process_score + */ +static int add_process_to_client_mapping_regex(lua_State* L) +{ + auto& ud = *UserData::check(L, DETECTOR, 1); + // Verify detector user data and that we are NOT in packet context + ud->validate_lua_state(false); + if (!init(L)) + return 0; + + const FastPatternConfig* const fp = SnortConfig::get_conf()->fast_pattern_config; + if (!MpseManager::is_regex_capable(fp->get_search_api())){ + appid_log(nullptr, TRACE_WARNING_LEVEL, "WARNING: appid: Regex patterns require usage of " + "regex capable search engine like hyperscan in %s\n", ud->get_detector()->get_name().c_str()); + return 0; + } + + int index = 1; + uint32_t appid = lua_tointeger(L, ++index); + + // Verify that process_name is a valid string + size_t pattern_size = 0; + const char* tmp_string = lua_tolstring(L, ++index, &pattern_size); + if (!tmp_string or !pattern_size) + { + appid_log(nullptr, TRACE_ERROR_LEVEL, "appid: Invalid eve process_name regex string: appid %u.\n", appid); + return 0; + } + const std::string process_name(tmp_string); + uint8_t process_score = lua_tointeger(L, ++index); + const std::string detector_name = ud->get_detector()->get_name(); + + ud->get_odp_ctxt().get_eve_ca_matchers().add_eve_ca_pattern(appid, process_name, + process_score, detector_name, false); ud->get_odp_ctxt().get_app_info_mgr().set_app_info_active(appid); @@ -3259,6 +3303,7 @@ static const luaL_Reg detector_methods[] = /* add client mapping for process name derived by fingerprinting */ { "addProcessToClientMapping", add_process_to_client_mapping }, { "addAlpnToServiceMapping", add_alpn_to_service_mapping }, + { "addProcessToClientMappingRegex", add_process_to_client_mapping_regex }, //HTTP Multi Pattern engine { "CHPCreateApp", detector_chp_create_application },