From cce9159eda9845431b753be015d5ffb8b07106c2 Mon Sep 17 00:00:00 2001 From: Nex Date: Sun, 23 Jan 2022 15:01:49 +0100 Subject: [PATCH] Adding indicator to matched results --- mvt/common/indicators.py | 86 ++++++++----------- mvt/common/version.py | 2 +- .../modules/backup/configuration_profiles.py | 4 +- mvt/ios/modules/fs/analytics.py | 8 +- mvt/ios/modules/fs/cache_files.py | 4 +- mvt/ios/modules/fs/filesystem.py | 5 +- mvt/ios/modules/fs/safari_favicon.py | 7 +- mvt/ios/modules/fs/shutdownlog.py | 9 +- mvt/ios/modules/fs/webkit_base.py | 8 +- mvt/ios/modules/mixed/chrome_favicon.py | 7 +- mvt/ios/modules/mixed/chrome_history.py | 4 +- mvt/ios/modules/mixed/firefox_favicon.py | 8 +- mvt/ios/modules/mixed/firefox_history.py | 4 +- mvt/ios/modules/mixed/idstatuscache.py | 4 +- mvt/ios/modules/mixed/locationd.py | 16 +++- mvt/ios/modules/mixed/osanalytics_addaily.py | 4 +- mvt/ios/modules/mixed/safari_browserstate.py | 16 ++-- mvt/ios/modules/mixed/safari_history.py | 4 +- mvt/ios/modules/mixed/shortcuts.py | 8 +- mvt/ios/modules/mixed/sms.py | 10 ++- mvt/ios/modules/mixed/tcc.py | 5 +- .../mixed/webkit_resource_load_statistics.py | 4 +- .../mixed/webkit_session_resource_log.py | 4 +- mvt/ios/modules/mixed/whatsapp.py | 8 +- mvt/ios/modules/net_base.py | 4 +- 25 files changed, 149 insertions(+), 94 deletions(-) diff --git a/mvt/common/indicators.py b/mvt/common/indicators.py index 4286670..4f0a79c 100644 --- a/mvt/common/indicators.py +++ b/mvt/common/indicators.py @@ -26,7 +26,7 @@ class Indicators: def _load_downloaded_indicators(self): if not os.path.isdir(self.data_dir): - return False + return for f in os.listdir(self.data_dir): if f.lower().endswith(".stix2"): @@ -37,7 +37,7 @@ class Indicators: Checks if a variable MVT_STIX2 contains path to STIX Files. """ if "MVT_STIX2" not in os.environ: - return False + return paths = os.environ["MVT_STIX2"].split(":") for path in paths: @@ -164,10 +164,11 @@ class Indicators: for ioc in ioc_file.get(ioc_type, []): yield { "value": ioc, + "type": ioc_type, "name": ioc_file["name"] } - def check_domain(self, url) -> bool: + def check_domain(self, url): """Check if a given URL matches any of the provided domain indicators. :param url: URL to match against domain indicators @@ -179,7 +180,7 @@ class Indicators: # TODO: If the IOC domain contains a subdomain, it is not currently # being matched. if not url: - return False + return None try: # First we use the provided URL. @@ -211,10 +212,10 @@ class Indicators: if ioc["value"].lower() in url: self.log.warning("Maybe found a known suspicious domain %s matching indicators from \"%s\"", url, ioc["name"]) - return True + return ioc # If nothing matched, we can quit here. - return False + return None # If all parsing worked, we start walking through available domain indicators. for ioc in self.get_iocs("domains"): @@ -227,7 +228,7 @@ class Indicators: self.log.warning("Found a known suspicious domain %s matching indicators from \"%s\"", final_url.url, ioc["name"]) - return True + return ioc # Then we just check the top level domain. if final_url.top_level.lower() == ioc["value"]: @@ -238,11 +239,9 @@ class Indicators: self.log.warning("Found a sub-domain with a suspicious top level %s matching indicators from \"%s\"", final_url.url, ioc["name"]) - return True + return ioc - return False - - def check_domains(self, urls) -> bool: + def check_domains(self, urls): """Check a list of URLs against the provided list of domain indicators. :param urls: List of URLs to check against domain indicators @@ -252,15 +251,14 @@ class Indicators: """ if not urls: - return False + return None for url in urls: - if self.check_domain(url): - return True + check = self.check_domain(url) + if check: + return check - return False - - def check_process(self, process) -> bool: + def check_process(self, process): """Check the provided process name against the list of process indicators. @@ -271,24 +269,22 @@ class Indicators: """ if not process: - return False + return None proc_name = os.path.basename(process) for ioc in self.get_iocs("processes"): if proc_name == ioc["value"]: self.log.warning("Found a known suspicious process name \"%s\" matching indicators from \"%s\"", process, ioc["name"]) - return True + return ioc if len(proc_name) == 16: if ioc["value"].startswith(proc_name): self.log.warning("Found a truncated known suspicious process name \"%s\" matching indicators from \"%s\"", process, ioc["name"]) - return True + return ioc - return False - - def check_processes(self, processes) -> bool: + def check_processes(self, processes): """Check the provided list of processes against the list of process indicators. @@ -299,15 +295,14 @@ class Indicators: """ if not processes: - return False + return None for process in processes: - if self.check_process(process): - return True + check = self.check_process(process) + if check: + return check - return False - - def check_email(self, email) -> bool: + def check_email(self, email): """Check the provided email against the list of email indicators. :param email: Email address to check against email indicators @@ -317,17 +312,15 @@ class Indicators: """ if not email: - return False + return None for ioc in self.get_iocs("emails"): if email.lower() == ioc["value"].lower(): self.log.warning("Found a known suspicious email address \"%s\" matching indicators from \"%s\"", email, ioc["name"]) - return True + return ioc - return False - - def check_file_name(self, file_name) -> bool: + def check_file_name(self, file_name): """Check the provided file name against the list of file indicators. :param file_name: File name to check against file @@ -338,17 +331,15 @@ class Indicators: """ if not file_name: - return False + return None for ioc in self.get_iocs("file_names"): if ioc["value"] == file_name: self.log.warning("Found a known suspicious file name \"%s\" matching indicators from \"%s\"", file_name, ioc["name"]) - return True + return ioc - return False - - def check_file_path(self, file_path) -> bool: + def check_file_path(self, file_path): """Check the provided file path against the list of file indicators (both path and name). :param file_path: File path or file name to check against file @@ -359,21 +350,20 @@ class Indicators: """ if not file_path: - return False + return None - if self.check_file_name(os.path.basename(file_path)): - return True + ioc = self.check_file_name(os.path.basename(file_path)) + if ioc: + return ioc for ioc in self.get_iocs("file_paths"): # Strip any trailing slash from indicator paths to match directories. if file_path.startswith(ioc["value"].rstrip("/")): self.log.warning("Found a known suspicious file path \"%s\" matching indicators form \"%s\"", file_path, ioc["name"]) - return True + return ioc - return False - - def check_profile(self, profile_uuid) -> bool: + def check_profile(self, profile_uuid): """Check the provided configuration profile UUID against the list of indicators. :param profile_uuid: Profile UUID to check against configuration profile indicators @@ -386,9 +376,7 @@ class Indicators: if profile_uuid in ioc["value"]: self.log.warning("Found a known suspicious profile ID \"%s\" matching indicators from \"%s\"", profile_uuid, ioc["name"]) - return True - - return False + return ioc def download_indicators_files(log): diff --git a/mvt/common/version.py b/mvt/common/version.py index 3d3e9c5..7e28abe 100644 --- a/mvt/common/version.py +++ b/mvt/common/version.py @@ -6,7 +6,7 @@ import requests from packaging import version -MVT_VERSION = "1.4.6" +MVT_VERSION = "1.4.7" def check_for_updates(): diff --git a/mvt/ios/modules/backup/configuration_profiles.py b/mvt/ios/modules/backup/configuration_profiles.py index 0c4fc06..5b3010a 100644 --- a/mvt/ios/modules/backup/configuration_profiles.py +++ b/mvt/ios/modules/backup/configuration_profiles.py @@ -46,8 +46,10 @@ class ConfigurationProfiles(IOSExtraction): payload_content = result["plist"]["PayloadContent"][0] # Alert on any known malicious configuration profiles in the indicator list. - if self.indicators.check_profile(result["plist"]["PayloadUUID"]): + ioc = self.indicators.check_profile(result["plist"]["PayloadUUID"]) + if ioc: self.log.warning(f"Found a known malicious configuration profile \"{result['plist']['PayloadDisplayName']}\" with UUID '{result['plist']['PayloadUUID']}'.") + result["matched_indicator"] = ioc self.detected.append(result) continue diff --git a/mvt/ios/modules/fs/analytics.py b/mvt/ios/modules/fs/analytics.py index f399a1d..58ae12e 100644 --- a/mvt/ios/modules/fs/analytics.py +++ b/mvt/ios/modules/fs/analytics.py @@ -41,15 +41,19 @@ class Analytics(IOSExtraction): if not isinstance(value, str): continue - if self.indicators.check_process(value): + ioc = self.indicators.check_process(value) + if ioc: self.log.warning("Found mention of a malicious process \"%s\" in %s file at %s", value, result["artifact"], result["timestamp"]) + result["matched_indicator"] = ioc self.detected.append(result) continue - if self.indicators.check_domain(value): + ioc = self.indicators.check_domain(value) + if ioc: self.log.warning("Found mention of a malicious domain \"%s\" in %s file at %s", value, result["artifact"], result["timestamp"]) + result["matched_indicator"] = ioc self.detected.append(result) def _extract_analytics_data(self): diff --git a/mvt/ios/modules/fs/cache_files.py b/mvt/ios/modules/fs/cache_files.py index 522360d..ed66551 100644 --- a/mvt/ios/modules/fs/cache_files.py +++ b/mvt/ios/modules/fs/cache_files.py @@ -36,7 +36,9 @@ class CacheFiles(IOSExtraction): self.detected = {} for key, values in self.results.items(): for value in values: - if self.indicators.check_domain(value["url"]): + ioc = self.indicators.check_domain(value["url"]) + if ioc: + value["matched_indicator"] = ioc if key not in self.detected: self.detected[key] = [value, ] else: diff --git a/mvt/ios/modules/fs/filesystem.py b/mvt/ios/modules/fs/filesystem.py index f8abff1..f09047c 100644 --- a/mvt/ios/modules/fs/filesystem.py +++ b/mvt/ios/modules/fs/filesystem.py @@ -40,7 +40,9 @@ class Filesystem(IOSExtraction): if "path" not in result: continue - if self.indicators.check_file_path(result["path"]): + ioc = self.indicators.check_file_path(result["path"]) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) # If we are instructed to run fast, we skip the rest. @@ -52,6 +54,7 @@ class Filesystem(IOSExtraction): if ioc["value"] in parts: self.log.warning("Found known suspicious process name mentioned in file at path \"%s\" matching indicators from \"%s\"", result["path"], ioc["name"]) + result["matched_indicator"] = ioc self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/fs/safari_favicon.py b/mvt/ios/modules/fs/safari_favicon.py index f2b84fc..70b894f 100644 --- a/mvt/ios/modules/fs/safari_favicon.py +++ b/mvt/ios/modules/fs/safari_favicon.py @@ -37,7 +37,12 @@ class SafariFavicon(IOSExtraction): return for result in self.results: - if self.indicators.check_domain(result["url"]) or self.indicators.check_domain(result["icon_url"]): + ioc = self.indicators.check_domain(result["url"]) + if not ioc: + ioc = self.indicators.check_domain(result["icon_url"]) + + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def _process_favicon_db(self, file_path): diff --git a/mvt/ios/modules/fs/shutdownlog.py b/mvt/ios/modules/fs/shutdownlog.py index 5efcdb6..ee86c89 100644 --- a/mvt/ios/modules/fs/shutdownlog.py +++ b/mvt/ios/modules/fs/shutdownlog.py @@ -34,15 +34,18 @@ class ShutdownLog(IOSExtraction): return for result in self.results: - if self.indicators.check_file_path(result["client"]): - self.detected.append(result) - continue + ioc = self.indicators.check_file_path(result["client"]) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) + continue for ioc in self.indicators.get_iocs("processes"): parts = result["client"].split("/") if ioc in parts: self.log.warning("Found mention of a known malicious process \"%s\" in shutdown.log", ioc) + result["matched_indicator"] = ioc self.detected.append(result) continue diff --git a/mvt/ios/modules/fs/webkit_base.py b/mvt/ios/modules/fs/webkit_base.py index b0bc0eb..834dace 100644 --- a/mvt/ios/modules/fs/webkit_base.py +++ b/mvt/ios/modules/fs/webkit_base.py @@ -18,9 +18,11 @@ class WebkitBase(IOSExtraction): if not self.indicators: return - for item in self.results: - if self.indicators.check_domain(item["url"]): - self.detected.append(item) + for result in self.results: + ioc = self.indicators.check_domain(result["url"]) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) def _process_webkit_folder(self, root_paths): for found_path in self._get_fs_files_from_patterns(root_paths): diff --git a/mvt/ios/modules/mixed/chrome_favicon.py b/mvt/ios/modules/mixed/chrome_favicon.py index 97812df..c806a97 100644 --- a/mvt/ios/modules/mixed/chrome_favicon.py +++ b/mvt/ios/modules/mixed/chrome_favicon.py @@ -42,7 +42,12 @@ class ChromeFavicon(IOSExtraction): return for result in self.results: - if self.indicators.check_domain(result["url"]) or self.indicators.check_domain(result["icon_url"]): + ioc = self.indicators.check_domain(result["url"]) + if not ioc: + ioc = self.indicators.check_domain(result["icon_url"]) + + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/mixed/chrome_history.py b/mvt/ios/modules/mixed/chrome_history.py index ae8bfe0..dd1751f 100644 --- a/mvt/ios/modules/mixed/chrome_history.py +++ b/mvt/ios/modules/mixed/chrome_history.py @@ -41,7 +41,9 @@ class ChromeHistory(IOSExtraction): return for result in self.results: - if self.indicators.check_domain(result["url"]): + ioc = self.indicators.check_domain(result["url"]) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/mixed/firefox_favicon.py b/mvt/ios/modules/mixed/firefox_favicon.py index b4de540..8f4db93 100644 --- a/mvt/ios/modules/mixed/firefox_favicon.py +++ b/mvt/ios/modules/mixed/firefox_favicon.py @@ -40,8 +40,12 @@ class FirefoxFavicon(IOSExtraction): return for result in self.results: - if (self.indicators.check_domain(result.get("url", "")) or - self.indicators.check_domain(result.get("history_url", ""))): + ioc = self.indicators.check_domain(result.get("url", "")) + if not ioc: + ioc = self.indicators.check_domain(result.get("history_url", "")) + + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/mixed/firefox_history.py b/mvt/ios/modules/mixed/firefox_history.py index 892fc1e..78d2794 100644 --- a/mvt/ios/modules/mixed/firefox_history.py +++ b/mvt/ios/modules/mixed/firefox_history.py @@ -44,7 +44,9 @@ class FirefoxHistory(IOSExtraction): return for result in self.results: - if self.indicators.check_domain(result["url"]): + ioc = self.indicators.check_domain(result["url"]) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/mixed/idstatuscache.py b/mvt/ios/modules/mixed/idstatuscache.py index dcc990a..b06f7df 100644 --- a/mvt/ios/modules/mixed/idstatuscache.py +++ b/mvt/ios/modules/mixed/idstatuscache.py @@ -43,7 +43,9 @@ class IDStatusCache(IOSExtraction): for result in self.results: if result.get("user", "").startswith("mailto:"): email = result["user"][7:].strip("'") - if self.indicators.check_email(email): + ioc = self.indicators.check_email(email) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) continue diff --git a/mvt/ios/modules/mixed/locationd.py b/mvt/ios/modules/mixed/locationd.py index f20c43b..b572fbf 100644 --- a/mvt/ios/modules/mixed/locationd.py +++ b/mvt/ios/modules/mixed/locationd.py @@ -60,30 +60,38 @@ class LocationdClients(IOSExtraction): parts = result["package"].split("/") proc_name = parts[len(parts)-1] - if self.indicators.check_process(proc_name): + ioc = self.indicators.check_process(proc_name) + if ioc: self.log.warning("Found a suspicious process name in LocationD entry %s", result["package"]) + result["matched_indicator"] = ioc self.detected.append(result) continue if "BundlePath" in result: - if self.indicators.check_file_path(result["BundlePath"]): + ioc = self.indicators.check_file_path(result["BundlePath"]) + if ioc: self.log.warning("Found a suspicious file path in Location D: %s", result["BundlePath"]) + result["matched_indicator"] = ioc self.detected.append(result) continue if "Executable" in result: - if self.indicators.check_file_path(result["Executable"]): + ioc = self.indicators.check_file_path(result["Executable"]) + if ioc: self.log.warning("Found a suspicious file path in Location D: %s", result["Executable"]) + result["matched_indicator"] = ioc self.detected.append(result) continue if "Registered" in result: - if self.indicators.check_file_path(result["Registered"]): + ioc = self.indicators.check_file_path(result["Registered"]) + if ioc: self.log.warning("Found a suspicious file path in Location D: %s", result["Registered"]) + result["matched_indicator"] = ioc self.detected.append(result) continue diff --git a/mvt/ios/modules/mixed/osanalytics_addaily.py b/mvt/ios/modules/mixed/osanalytics_addaily.py index b3d7f2d..60b064c 100644 --- a/mvt/ios/modules/mixed/osanalytics_addaily.py +++ b/mvt/ios/modules/mixed/osanalytics_addaily.py @@ -41,7 +41,9 @@ class OSAnalyticsADDaily(IOSExtraction): return for result in self.results: - if self.indicators.check_process(result["package"]): + ioc = self.indicators.check_process(result["package"]) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/mixed/safari_browserstate.py b/mvt/ios/modules/mixed/safari_browserstate.py index 66461dd..38de49f 100644 --- a/mvt/ios/modules/mixed/safari_browserstate.py +++ b/mvt/ios/modules/mixed/safari_browserstate.py @@ -44,16 +44,22 @@ class SafariBrowserState(IOSExtraction): return for result in self.results: - if "tab_url" in result and self.indicators.check_domain(result["tab_url"]): - self.detected.append(result) - continue + if "tab_url" in result: + ioc = self.indicators.check_domain(result["tab_url"]) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) + continue if "session_data" not in result: continue for session_entry in result["session_data"]: - if "entry_url" in session_entry and self.indicators.check_domain(session_entry["entry_url"]): - self.detected.append(result) + if "entry_url" in session_entry: + ioc = self.indicators.check_domain(session_entry["entry_url"]) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) def _process_browser_state_db(self, db_path): conn = sqlite3.connect(db_path) diff --git a/mvt/ios/modules/mixed/safari_history.py b/mvt/ios/modules/mixed/safari_history.py index 4fc4113..9c5e36c 100644 --- a/mvt/ios/modules/mixed/safari_history.py +++ b/mvt/ios/modules/mixed/safari_history.py @@ -80,7 +80,9 @@ class SafariHistory(IOSExtraction): return for result in self.results: - if self.indicators.check_domain(result["url"]): + ioc = self.indicators.check_domain(result["url"]) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def _process_history_db(self, history_path): diff --git a/mvt/ios/modules/mixed/shortcuts.py b/mvt/ios/modules/mixed/shortcuts.py index c5ec8e4..7b6706f 100644 --- a/mvt/ios/modules/mixed/shortcuts.py +++ b/mvt/ios/modules/mixed/shortcuts.py @@ -54,9 +54,11 @@ class Shortcuts(IOSExtraction): if not self.indicators: return - for action in self.results: - if self.indicators.check_domains(action["action_urls"]): - self.detected.append(action) + for result in self.results: + ioc = self.indicators.check_domains(result["action_urls"]) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) def run(self): self._find_ios_database(backup_ids=SHORTCUT_BACKUP_IDS, diff --git a/mvt/ios/modules/mixed/sms.py b/mvt/ios/modules/mixed/sms.py index c8ab2c5..0e3225a 100644 --- a/mvt/ios/modules/mixed/sms.py +++ b/mvt/ios/modules/mixed/sms.py @@ -41,10 +41,12 @@ class SMS(IOSExtraction): if not self.indicators: return - for message in self.results: - message_links = check_for_links(message.get("text", "")) - if self.indicators.check_domains(message_links): - self.detected.append(message) + for result in self.results: + message_links = check_for_links(result.get("text", "")) + ioc = self.indicators.check_domains(message_links) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) def run(self): self._find_ios_database(backup_ids=SMS_BACKUP_IDS, diff --git a/mvt/ios/modules/mixed/tcc.py b/mvt/ios/modules/mixed/tcc.py index cd626d0..3dfd8e5 100644 --- a/mvt/ios/modules/mixed/tcc.py +++ b/mvt/ios/modules/mixed/tcc.py @@ -71,8 +71,9 @@ class TCC(IOSExtraction): return for result in self.results: - if self.indicators.check_process(result["client"]): - self.log.warning("Found malicious process in TCC database: %s", result["client"]) + ioc = self.indicators.check_process(result["client"]) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result) def process_db(self, file_path): diff --git a/mvt/ios/modules/mixed/webkit_resource_load_statistics.py b/mvt/ios/modules/mixed/webkit_resource_load_statistics.py index fa4df9b..3a53a40 100644 --- a/mvt/ios/modules/mixed/webkit_resource_load_statistics.py +++ b/mvt/ios/modules/mixed/webkit_resource_load_statistics.py @@ -37,7 +37,9 @@ class WebkitResourceLoadStatistics(IOSExtraction): self.detected = {} for key, items in self.results.items(): for item in items: - if self.indicators.check_domain(item["registrable_domain"]): + ioc = self.indicators.check_domain(item["registrable_domain"]) + if ioc: + item["matched_indicator"] = ioc if key not in self.detected: self.detected[key] = [item, ] else: diff --git a/mvt/ios/modules/mixed/webkit_session_resource_log.py b/mvt/ios/modules/mixed/webkit_session_resource_log.py index 947de82..4a3e41d 100644 --- a/mvt/ios/modules/mixed/webkit_session_resource_log.py +++ b/mvt/ios/modules/mixed/webkit_session_resource_log.py @@ -66,7 +66,9 @@ class WebkitSessionResourceLog(IOSExtraction): all_origins = set([entry["origin"]] + source_domains + destination_domains) - if self.indicators.check_domains(all_origins): + ioc = self.indicators.check_domains(all_origins) + if ioc: + entry["matched_indicator"] = ioc self.detected.append(entry) redirect_path = "" diff --git a/mvt/ios/modules/mixed/whatsapp.py b/mvt/ios/modules/mixed/whatsapp.py index 42c5c7b..d3c9dae 100644 --- a/mvt/ios/modules/mixed/whatsapp.py +++ b/mvt/ios/modules/mixed/whatsapp.py @@ -47,9 +47,11 @@ class Whatsapp(IOSExtraction): if not self.indicators: return - for message in self.results: - if self.indicators.check_domains(message.get("links", [])): - self.detected.append(message) + for result in self.results: + ioc = self.indicators.check_domains(result.get("links", [])) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) def run(self): self._find_ios_database(backup_ids=WHATSAPP_BACKUP_IDS, diff --git a/mvt/ios/modules/net_base.py b/mvt/ios/modules/net_base.py index 4e170b9..fcb252a 100644 --- a/mvt/ios/modules/net_base.py +++ b/mvt/ios/modules/net_base.py @@ -237,5 +237,7 @@ class NetBase(IOSExtraction): if not result["proc_id"]: continue - if self.indicators.check_process(proc_name): + ioc = self.indicators.check_process(proc_name) + if ioc: + result["matched_indicator"] = ioc self.detected.append(result)