diff --git a/MANIFEST b/MANIFEST index 6253e9198a8b23ae4f0cb7d41bbbacc283042a43..1e73e6ff437fc0d6c96000a7e02be5291a5f4fa1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,2 +1,2 @@ -VERSION=v0.0.6 +VERSION=v0.0.7 SERVICE=evidence-collector diff --git a/constants.json b/constants.json index 4e7c12ae7da9a2efc7379f4c70538953354e4dfa..a56e8782390bd552f684d1575b8ff9d0b6d6c24d 100644 --- a/constants.json +++ b/constants.json @@ -1,4 +1,7 @@ { + "general": { + "demo": false + }, "wazuh": { "host": "192.168.33.10", "port": 55000, diff --git a/wazuh_evidence_collector/checker.py b/wazuh_evidence_collector/checker.py new file mode 100644 index 0000000000000000000000000000000000000000..f6034cf027b9186e67c9833e77cd5ae47be3d7bf --- /dev/null +++ b/wazuh_evidence_collector/checker.py @@ -0,0 +1,100 @@ +from wazuh_evidence_collector.wazuh_client import WazuhClient +from elasticsearch import Elasticsearch +from elasticsearch_dsl import Search + + +class Checker: + def __init__(self, wc, es): + self.wc = wc + self.es = es + + # Check if syscheck enabled + def check_syscheck(self, agent): + body = self.wc.req('GET', 'agents/' + agent[0] + '/config/syscheck/syscheck') + + measurement_result = body['data']['syscheck']['disabled'] == 'no' + + return body, measurement_result + + # Check if rootcheck enabled + def check_rootcheck(self, agent): + body = self.wc.req('GET', 'agents/' + agent[0] + '/config/syscheck/rootcheck') + + measurement_result = body['data']['rootcheck']['disabled'] == 'no' + + return body, measurement_result + + # Check if there's at least one valid alerting service + def check_alert_integrations(self): + body = self.wc.req('GET', 'manager/configuration') + + # Check email notifications integration + try: + email_notifications = ( + True if body['data']['affected_items'][0]['global']['email_notification'] == 'yes' else False) + except: + email_notifications = False + + # Check Slack and PagerDuty notifications integration + try: + integrations = body['data']['affected_items'][0]['integration'] + + slack_notifications = pagerduty_notifications = False + + for integration in integrations: + if integration['name'] == 'slack': + slack_notifications = True + + if integration['name'] == 'pagerduty': + pagerduty_notifications = True + except: + slack_notifications = pagerduty_notifications = False + + measurement_result = email_notifications or slack_notifications or pagerduty_notifications + + return body, measurement_result + + # Check for VirusTotal integration + def check_virus_total_integration(self): + body = self.wc.req('GET', 'manager/configuration') + + # Check VirusTotal integration + try: + integrations = body['data']['affected_items'][0]['integration'] + + measurement_result = False + + for integration in integrations: + if integration['name'] == 'virustotal': + measurement_result = True + break + except: + measurement_result = False + + return body, measurement_result + + # Check if ClamAV daemon process running + def check_clamd_process(self, agent): + body = self.wc.req('GET', 'syscollector/' + agent[0] + '/processes') + + measurement_result = False + + for package in body['data']['affected_items']: + if package['name'] == 'clamd': + measurement_result = True + break + + return body, measurement_result + + # Check ClamAV logs in Elasticsearch + def check_clamd_logs_elastic(self, agent): + s = Search(using=self.es, index="wazuh-alerts-*") \ + .query("match", predecoder__program_name="clamd") \ + .query("match", rule__descrhosttion="Clamd restarted") \ + .query("match", agent__id=agent[0]) + + body = s.execute().to_dict() + + measurement_result = len(body['hits']['hits']) > 0 + + return body, measurement_result diff --git a/wazuh_evidence_collector/demo_checker.py b/wazuh_evidence_collector/demo_checker.py new file mode 100644 index 0000000000000000000000000000000000000000..893fdffa2b0f4a41d185a0aaf3699709f6661a6b --- /dev/null +++ b/wazuh_evidence_collector/demo_checker.py @@ -0,0 +1,45 @@ +import random + +class DemoChecker: + + def __init__(self): + self.result = bool(random.getrandbits(1)) + + def __body(self, name): + return {name: self.result} + + # Check if syscheck enabled + def check_syscheck(self, *_): + body = self.__body("syscheck") + + return body, self.result + + # Check if rootcheck enabled + def check_rootcheck(self, *_): + body = self.__body("rootcheck") + + return body, self.result + + # Check if there's at least one valid alerting service + def check_alert_integrations(self, *_): + body = self.__body("alerting_services") + + return body, self.result + + # Check for VirusTotal integration + def check_virus_total_integration(self, *_): + body = self.__body("virustotal_integration") + + return body, self.result + + # Check if ClamAV daemon process running + def check_clamd_process(self, *_): + body = self.__body("clamd_process") + + return body, self.result + + # Check ClamAV logs in Elasticsearch + def check_clamd_logs_elastic(self, *_): + body = self.__body("clamd_logs") + + return body, self.result diff --git a/wazuh_evidence_collector/wazuh_evidence_collector.py b/wazuh_evidence_collector/wazuh_evidence_collector.py index f9eed214d69f0bde4ff460e3703137d820875fe0..be42932421a0f62af488ab0b036f3fc3718068b5 100644 --- a/wazuh_evidence_collector/wazuh_evidence_collector.py +++ b/wazuh_evidence_collector/wazuh_evidence_collector.py @@ -4,6 +4,8 @@ from elasticsearch import Elasticsearch from elasticsearch_dsl import Search from forward_evidence.forward_evidence import ForwardEvidence from forward_evidence.generate_evidence import create_resource, create_assessevidence_request, print_evidence +from wazuh_evidence_collector.checker import Checker +from wazuh_evidence_collector.demo_checker import DemoChecker import uuid import configparser import logging.config @@ -15,18 +17,20 @@ f.close() logging.config.fileConfig('logging.conf') LOGGER = logging.getLogger('root') +DEMO = CONSTANTS["general"]["demo"] -wc = WazuhClient(CONSTANTS['wazuh']['host'], CONSTANTS['wazuh']['port'], CONSTANTS['wazuh']['username'], CONSTANTS['wazuh']['password']) +if not DEMO: + wc = WazuhClient(CONSTANTS['wazuh']['host'], CONSTANTS['wazuh']['port'], CONSTANTS['wazuh']['username'], CONSTANTS['wazuh']['password']) -es = Elasticsearch( - CONSTANTS['elastic']['host'], - http_auth=(CONSTANTS['elastic']['username'], CONSTANTS['elastic']['password']), - scheme='https', - port=CONSTANTS['elastic']['port'], - use_ssl=False, - verify_certs=False, - ssl_show_warn=False, - ) + es = Elasticsearch( + CONSTANTS['elastic']['host'], + http_auth=(CONSTANTS['elastic']['username'], CONSTANTS['elastic']['password']), + scheme='https', + port=CONSTANTS['elastic']['port'], + use_ssl=False, + verify_certs=False, + ssl_show_warn=False, + ) forwarder = ForwardEvidence(CONSTANTS, LOGGER) @@ -56,6 +60,7 @@ def main(): # Wrapper function that runs all the checks (for every manager/agent) def run_collector(): + checker = Checker(wc, es) if not DEMO else DemoChecker() # Get list of all agent ids (including manager's) def get_agents(wc): @@ -67,12 +72,12 @@ def run_collector(): return body, agent_list - body, agent_list = get_agents(wc) + body, agent_list = get_agents(wc) if not DEMO else ({}, [[0, "dummyAgent0"], [1, "dummyAgent1"]]) ae_req_list = [] for agent in agent_list: - ae_req_list.append(generate_evidence(wc, es, agent)) + ae_req_list.append(generate_evidence(agent, checker)) # TODO: for ae_req in ae_req_list: @@ -82,116 +87,25 @@ def run_collector(): return ae_req_list # Run checks and generate evidence -def generate_evidence(wc, es, agent): - - # Check if syscheck enabled - def check_syscheck(wc, agent): - body = wc.req('GET', 'agents/' + agent[0] + '/config/syscheck/syscheck') - - measurement_result = body['data']['syscheck']['disabled'] == 'no' - - return body, measurement_result - - # Check if rootcheck enabled - def check_rootcheck(wc, agent): - body = wc.req('GET', 'agents/' + agent[0] + '/config/syscheck/rootcheck') - - measurement_result = body['data']['rootcheck']['disabled'] == 'no' - - return body, measurement_result - - # Check if there's at least one valid alerting service - def check_alert_integrations(wc): - body = wc.req('GET', 'manager/configuration') - - # Check email notifications integration - try: - email_notifications = (True if body['data']['affected_items'][0]['global']['email_notification'] == 'yes' else False) - except: - email_notifications = False - - # Check Slack and PagerDuty notifications integration - try: - integrations = body['data']['affected_items'][0]['integration'] - - slack_notifications = pagerduty_notifications = False - - for integration in integrations: - if integration['name'] == 'slack': - slack_notifications = True - - if integration['name'] == 'pagerduty': - pagerduty_notifications = True - except: - slack_notifications = pagerduty_notifications = False - - measurement_result = email_notifications or slack_notifications or pagerduty_notifications - - return body, measurement_result - - # Check for VirusTotal integration - def check_virus_total_integration(wc): - body = wc.req('GET', 'manager/configuration') - - # Check VirusTotal integration - try: - integrations = body['data']['affected_items'][0]['integration'] - - measurement_result = False - - for integration in integrations: - if integration['name'] == 'virustotal': - measurement_result = True - break - except: - measurement_result = False - - return body, measurement_result - - # Check if ClamAV daemon process running - def check_clamd_process(wc, agent): - body = wc.req('GET', 'syscollector/' + agent[0] + '/processes') - - measurement_result = False - - for package in body['data']['affected_items']: - if package['name'] == 'clamd': - measurement_result = True - break - - return body, measurement_result - - # Check ClamAV logs in Elasticsearch - def check_clamd_logs_elastic(es, agent): - s = Search(using=es, index="wazuh-alerts-*") \ - .query("match", predecoder__program_name="clamd") \ - .query("match", rule__descrhosttion="Clamd restarted") \ - .query("match", agent__id=agent[0]) - - body = s.execute().to_dict() - - measurement_result = len(body['hits']['hits']) > 0 - - return body, measurement_result - +def generate_evidence(agent, checker): raw_evidence = [] - evidence, result_syscheck = check_syscheck(wc, agent) + evidence, result_syscheck = checker.check_syscheck(agent) raw_evidence.append(evidence) - evidence, result_rootcheck = check_rootcheck(wc, agent) + evidence, result_rootcheck = checker.check_rootcheck(agent) raw_evidence.append(evidence) - evidence, result_alert_integration = check_alert_integrations(wc) + evidence, result_alert_integration = checker.check_alert_integrations() raw_evidence.append(evidence) - evidence, result_virus_total = check_virus_total_integration(wc) + evidence, result_virus_total = checker.check_virus_total_integration() raw_evidence.append(evidence) - evidence, result_clamd_process = check_clamd_process(wc, agent) + evidence, result_clamd_process = checker.check_clamd_process(agent) raw_evidence.append(evidence) - evidence, result_clamd_logs = check_clamd_logs_elastic(es, agent) + evidence, result_clamd_logs = checker.check_clamd_logs_elastic(agent) raw_evidence.append(evidence) # TODO: