-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add: Add event_monitor module to vuln detector #2462
- Loading branch information
Showing
2 changed files
with
249 additions
and
47 deletions.
There are no files selected for viewing
47 changes: 0 additions & 47 deletions
47
deps/wazuh_testing/wazuh_testing/modules/vulnerability_detector/callbacks.py
This file was deleted.
Oops, something went wrong.
249 changes: 249 additions & 0 deletions
249
deps/wazuh_testing/wazuh_testing/modules/vulnerability_detector/event_monitor.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
import re | ||
|
||
from wazuh_testing.modules import vulnerability_detector as vd | ||
from wazuh_testing.db_interface.cve_db import get_num_vulnerabilities | ||
|
||
|
||
def _make_vuln_callback(pattern, prefix=vd.VULNERABILITY_DETECTOR_PREFIX): | ||
"""Create a callback function from a text pattern. | ||
It already contains the vulnerability-detector prefix. | ||
Args: | ||
pattern (str): String to match on the log. | ||
prefix (str): regular expression used as prefix before the pattern. | ||
Returns: | ||
lambda: function that returns if there's a match in the file | ||
Examples: | ||
>>> callback_bionic_update_started = make_vuln_callback("Starting Ubuntu Bionic database update") | ||
""" | ||
pattern = r'\s+'.join(pattern.split()) | ||
regex = re.compile(r'{}{}'.format(prefix, pattern)) | ||
|
||
return lambda line: regex.match(line) is not None | ||
|
||
|
||
def callback_detect_vulnerability_scan_sleeping(line): | ||
msg = rf"{vd.VULNERABILITY_DETECTOR_PREFIX} Sleeping for (.*)..." | ||
match = re.match(msg, line) | ||
|
||
return match.group(1) if match is not None else "" | ||
|
||
|
||
def callback_detect_vulnerability_detector_disabled(line): | ||
msg = rf"{vd.VULNERABILITY_DETECTOR_PREFIX}DEBUG: Module disabled. Exiting..." | ||
match = re.match(msg, line) | ||
|
||
return match is not None | ||
|
||
|
||
def callback_detect_vulnerability_detector_enabled(line): | ||
msg = r'(.*)wazuh-modulesd:vulnerability-detector(.*)' | ||
match1 = re.match(msg, line) | ||
msg = r'(.*)DEBUG: Module disabled. Exiting...(.*)' | ||
match2 = re.match(msg, line) | ||
|
||
return match1 is not None and match2 is None | ||
|
||
|
||
def check_vuln_detector_event(wazuh_log_monitor, callback, error_message='', update_position=True, | ||
timeout=vd.VULN_DETECTOR_EXTENDED_GLOBAL_TIMEOUT, | ||
prefix=vd.VULNERABILITY_DETECTOR_PREFIX): | ||
"""Check if a vulnerability event occurs | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
callback (str): log regex to check in Wazuh log | ||
error_message (str): error message to show in case of expected event does not occur | ||
update_position (boolean): filter configuration parameter to search in Wazuh log | ||
timeout (str): timeout to check the event in Wazuh log | ||
prefix (str): log pattern regex | ||
""" | ||
wazuh_log_monitor.start(timeout=timeout, update_position=update_position, | ||
callback=_make_vuln_callback(callback, prefix), error_message=error_message) | ||
|
||
|
||
def check_vulnerabilities_number(expected_number): | ||
"""Check if the number of vulnerabilities inserted in VULNERABILITIES table of CVE DB is the expected. | ||
Args: | ||
expected_number (int): number of expected vulnerabilities | ||
""" | ||
vulnerabilities_number = get_num_vulnerabilities() | ||
assert vulnerabilities_number == expected_number, f"Number of inserted vulnerabilities is not the expected." \ | ||
f" Expected: {expected_number}, Got: {vulnerabilities_number}" | ||
|
||
|
||
def check_log_event(wazuh_log_monitor, log_event, update_position=False, | ||
timeout=vd.VULN_DETECTOR_EXTENDED_GLOBAL_TIMEOUT, prefix=vd.VULNERABILITY_DETECTOR_PREFIX): | ||
"""Check if the vulnerable package has been reported. | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
log_event (str): Log event to find in ossec.log | ||
update_position (boolean): Filter configuration parameter to search in Wazuh log | ||
timeout (str): Timeout to check the event in Wazuh log | ||
prefix (str): Log pattern regex | ||
""" | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_log_monitor, update_position=update_position, timeout=timeout, | ||
callback=log_event, error_message=f"Could not find the log event: {log_event}", | ||
prefix=prefix) | ||
|
||
|
||
def check_feed_imported_successfully(wazuh_log_monitor, log_system_name, expected_vulnerabilities_number, | ||
update_position=False, timeout=vd.VULN_DETECTOR_EXTENDED_GLOBAL_TIMEOUT, | ||
check_vuln_number=True): | ||
"""Check that redhat OVAL feeds have been imported successfully. | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
log_system_name (str): system name in ossec.log. For instance 'Red Hat Enterprise Linux' | ||
expected_vulnerabilities_number (int): number of expected vulnerabilities imported in the BD | ||
update_position (boolean): filter configuration parameter to search in Wazuh log | ||
timeout (str): timeout to check the event in Wazuh log | ||
check_vuln_number (bool): boolean to enable the check that compares the number of generated alerts with | ||
the number of expected alerts | ||
""" | ||
check_vuln_detector_event( | ||
wazuh_log_monitor=wazuh_log_monitor, update_position=update_position, timeout=timeout, | ||
callback=rf"INFO: \(\d+\): The update of the '{log_system_name}' feed finished successfully.", | ||
error_message=f"Could not find the message: '{log_system_name}' feed finished successfully" | ||
) | ||
|
||
if check_vuln_number: | ||
check_vulnerabilities_number(expected_number=expected_vulnerabilities_number) | ||
|
||
|
||
def check_failure_when_importing_feed(wazuh_log_monitor, expected_vulnerabilities_number=0, update_position=False, | ||
timeout=vd.VULN_DETECTOR_EXTENDED_GLOBAL_TIMEOUT, parser_error=False): | ||
"""Check an error message when importing redhat OVAL feeds and checks that the vulnerabilities table is empty | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
expected_vulnerabilities_number (int): number of expected vulnerabilities imported in the BD | ||
update_position (bool): filter configuration parameter to search in Wazuh log | ||
timeout (str): timeout to check the event in Wazuh log | ||
parser_error (bool): check if there is a parser error message | ||
""" | ||
if parser_error: | ||
check_log_event(wazuh_log_monitor=wazuh_log_monitor, update_position=update_position, timeout=timeout, | ||
log_event=r"ERROR: \(\d+\): The .* feed couldn't be parsed from .* file") | ||
|
||
check_log_event(wazuh_log_monitor=wazuh_log_monitor, update_position=update_position, timeout=timeout, | ||
log_event=r"ERROR: \(\d+\): CVE database could not be updated.") | ||
|
||
check_vulnerabilities_number(expected_number=expected_vulnerabilities_number) | ||
|
||
|
||
def check_detected_vulnerabilities_number(wazuh_log_monitor, expected_vulnerabilities_number, feed_source, agent=None, | ||
update_position=False, timeout=vd.VULN_DETECTOR_GLOBAL_TIMEOUT): | ||
"""Check the number of vulnerabilities found by the feed source. | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
expected_vulnerabilities_number (int): number of expected vulnerabilities | ||
feed_source (str): OVAL or NVD | ||
agent (str, optional): Agent id | ||
update_position (bool): filter configuration parameter to search in Wazuh log | ||
timeout (str): timeout to check the event in Wazuh log | ||
""" | ||
callback = f"The {feed_source} found a total of '{expected_vulnerabilities_number}' " \ | ||
"potential vulnerabilities for agent .* " | ||
if agent is not None: | ||
callback = f"The {feed_source} found a total of '{expected_vulnerabilities_number}' " \ | ||
f"potential vulnerabilities for agent '{agent}' " | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_log_monitor, update_position=update_position, timeout=timeout, | ||
callback=callback, error_message=f"The expected number of {feed_source} vulnerabilities " | ||
f"have not been found") | ||
|
||
|
||
def check_feed_uncompressed_successfully(wazuh_log_monitor, feed, update_position=False, | ||
timeout=vd.VULN_DETECTOR_EXTENDED_GLOBAL_TIMEOUT): | ||
"""Check that a feed from path or url have been uncompressed successfully | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
feed (str): Path or url where the feed is | ||
update_position (boolean): Filter configuration parameter to search in Wazuh log | ||
timeout (str): Timeout to check the event in Wazuh log | ||
""" | ||
feed = feed[:-1] if feed[-1] == '$' else feed | ||
|
||
prefix = r'.*wazuh-modulesd.*' | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_log_monitor, update_position=update_position, timeout=timeout, | ||
callback=rf"(The file|File from URL) '{feed}' was successfully uncompressed into .*", | ||
error_message=f"Could not find the message: '{feed}' was successfully uncompressed", | ||
prefix=prefix) | ||
|
||
|
||
def check_vulnerability_scan_log(wazuh_log_monitor, package, cve): | ||
"""Check if inserted vulnerable packages are reported by vulnerability detector. | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
package (str): Name of custom package to check. Example: 'firefox-0' | ||
cve (str): Package CVE. Example: 'CVE-2019-11764' | ||
""" | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_log_monitor, timeout=vd.VULN_DETECTOR_EXTENDED_GLOBAL_TIMEOUT, | ||
update_position=False, | ||
callback=f"The '{package}' package .* from agent .* is vulnerable to '{cve}'", | ||
error_message=f"Could not find the report which says that the package {package} is " | ||
f"vulnerable with {cve}") | ||
|
||
|
||
def check_vulnerability_scan_discarded(wazuh_log_monitor, package): | ||
"""Check if kernel packages are discarded by vulnerability detector. | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
package (str): Name of custom kernel package to check. Example: 'linux-image-aws' | ||
""" | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_log_monitor, timeout=vd.VULN_DETECTOR_SCAN_TIMEOUT, | ||
update_position=False, callback=f"Discarded Linux Kernel package '{package}' .*", | ||
error_message=f"Could not find the report which says that the package {package} was " | ||
f"discarded", | ||
prefix='.*') | ||
|
||
|
||
def check_vulnerability_scan_alert(wazuh_alert_monitor, package, cve): | ||
"""Check if inserted vulnerable packages are reported by vulnerability detector. | ||
Args: | ||
wazuh_alert_monitor (FileMonitor): FileMonitor object to monitor the Wazuh alerts log | ||
package (str): Name of custom package to check. Example: 'firefox-0' | ||
cve (str): Package CVE. Example: 'CVE-2019-11764' | ||
""" | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_alert_monitor, timeout=vd.VULN_DETECTOR_SCAN_TIMEOUT, | ||
update_position=False, callback=f"{cve} affects {package}", | ||
error_message=f"Could not find the report which says that {cve} affects the package " | ||
f"{package}", | ||
prefix='.*') | ||
|
||
|
||
def check_vulnerability_scan_remove_log(wazuh_log_monitor, package, cve): | ||
"""Check if removed vulnerable packages are reported by vulnerability detector in yhe logs. | ||
Args: | ||
wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log | ||
package (str): Name of custom package to check. Example: 'firefox-0' | ||
cve (str): Package CVE. Example: 'CVE-2019-11764' | ||
""" | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_log_monitor, timeout=vd.VULN_DETECTOR_SCAN_TIMEOUT, | ||
update_position=False, callback=f"The vulnerability '{cve}' affecting '{package}' was " | ||
f"eliminated", | ||
error_message=f"Could not find the log which says that the package {package} is no " | ||
f"longer vulnerable with {cve}") | ||
|
||
|
||
def check_vulnerability_scan_remove_alerts(wazuh_alerts_monitor, package, cve): | ||
"""Check if removed vulnerable packages are reported by vulnerability detector in the alerts. | ||
Args: | ||
wazuh_alerts_monitor (FileMonitor): FileMonitor object to monitor the Wazuh alerts log | ||
package (str): Name of custom package to check. Example: 'firefox-0' | ||
cve (str): Package CVE. Example: 'CVE-2019-11764' | ||
""" | ||
check_vuln_detector_event(wazuh_log_monitor=wazuh_alerts_monitor, timeout=vd.VULN_DETECTOR_SCAN_TIMEOUT, | ||
update_position=False, callback=f"The {cve} that affected {package} was eliminated due " | ||
f"to a package removal/update or a system upgrade", | ||
prefix='.*', error_message='Could not find the alert which says that the package ' | ||
f"{package} is no longer vulnerable with {cve}") |