]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4215: appid: change eve pattern matching logic
authorLukasz Czarnik -X (lczarnik - SOFTSERVE INC at Cisco) <lczarnik@cisco.com>
Wed, 28 Feb 2024 20:12:54 +0000 (20:12 +0000)
committerChris Sherwin (chsherwi) <chsherwi@cisco.com>
Wed, 28 Feb 2024 20:12:54 +0000 (20:12 +0000)
Merge in SNORT/snort3 from ~LCZARNIK/snort3:eve to master

Squashed commit of the following:

commit fcc27614cacf8e7a712429522b35e9e41522c07f
Author: Lukasz Czarnik <lczarnik@cisco.com>
Date:   Tue Feb 20 08:27:01 2024 -0500

    appid: change eve pattern matching logic

src/network_inspectors/appid/client_plugins/eve_ca_patterns.cc
src/network_inspectors/appid/client_plugins/eve_ca_patterns.h
src/network_inspectors/appid/lua_detector_api.cc

index 66c501013b828dc3797b4581606f55ee25225d7a..d9d6a85f7e7eb55d5e551be6542ea24e96dc9691 100644 (file)
@@ -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 =
index b83c7d39891baca5fd9b8c78b3491464cb958a59..cb23e2db49a2c15865f2c01a09ebfc65c504d102 100644 (file)
@@ -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();
index 1760f14b219bc4c2f502e49932fc88d1a0b0877b..23e0105a18f3bfd05a0f914faa7f7356bb6b6dca 100644 (file)
@@ -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<LuaObject>::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 },