diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..67c7c9ad9008a491d5e518b7c0cddf43a88587c1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,65 @@
+# Evidence Collector
+
+This project includes modules for collecting evidence regarding Wazuh and VAT.
+
+## Wazuh evidence collector
+
+Wazuh evidence collector uses [Wazuh's API](https://documentation.wazuh.com/current/user-manual/api/reference.html) to access information about manager's and agents' system informations and configurations. As an additional measure to ensure correct configuration of [ClamAV](https://www.clamav.net/) (if installed on machine) we also make use of [Elasticsearch's API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html) to dirrectly access collected logs - Elastic stack is one of the Wazuh's required components (usually installed on the same machine as Wazuh server, but can be stand alone as well).
+
+## Installation & use
+
+1. Set up your Wazuh development environment
+
+2. Clone this repository
+
+3. Install requirements
+
+```
+pip install -r requirements.txt
+```
+
+4. Run test script 
+
+```
+python3 test.py
+```
+
+### Setting up Wazuh development environment
+
+Use [Security Monitoring](https://gitlab.xlab.si/medina/security-monitoring) repository to create and deploy Vagrant box with all required components.
+
+### API User authentication
+
+Current implementation has disabled SSL certificate verification & uses simple username/password verification. Production version should change this with cert verification.
+
+### Manual Elasticsearch API testin with cURL
+
+Example command for testing the API via CLI: 
+
+```
+curl --user admin:changeme --insecure -X GET "https://192.168.33.10:9200/wazuh-alerts*/_search?pretty" -H 'Content-Type: application/json' -d'
+{"query": {
+  "bool": {
+    "must": [{"match": {"predecoder.program_name": "clamd"}},
+             {"match": {"rule.description": "Clamd restarted"}},
+             {"match": {"agent.id": "001"}}]
+    }
+  }
+}'
+```
+
+## Known issues
+
+### Python Elasticsearch library problems with ODFE
+
+Latest versions (`7.14.0` & `7.15.0`) of Python Elasticsearch library have problems connecting to Open Distro for Elasticsearch and produce the following error when trying to do so: 
+
+```
+elasticsearch.exceptions.UnsupportedProductError: The client noticed that the server is not a supported distribution of Elasticsearch
+```
+
+To resolve this, downgrade to older package version: 
+
+```
+pip install 'elasticsearch<7.14.0'
+```
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d63607f0bf727dd9ca5ede5cf09e8866190c00ec
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,3 @@
+elasticsearch_dsl==7.4.0
+urllib3==1.25.8
+elasticsearch==7.13.4
diff --git a/test.py b/test.py
new file mode 100644
index 0000000000000000000000000000000000000000..17fc4194afbaaa229f039984730af6102d4708a5
--- /dev/null
+++ b/test.py
@@ -0,0 +1,7 @@
+import pprint
+from  wazuh_evidence_collector import *
+
+evidences = run_full_check()
+
+for evidence in evidences:
+    pprint.pprint(evidence.__dict__)
diff --git a/verifier.py b/verifier.py
deleted file mode 100644
index 624a1bc1dc1a19084af8c15c7184044ff711030a..0000000000000000000000000000000000000000
--- a/verifier.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from wazuhclient import WazuhClient
-from evidence import Evidence, simple_evidence
-from random import randint
-from sys import maxsize
-from datetime import datetime
-import pprint
-
-wc = WazuhClient('192.168.33.10', 55000, 'wazuh-wui', 'wazuh-wui')
-
-# Get (temporary) ID
-def get_id(reqId):
-    return reqId + '-' + str(randint(0, maxsize))
-
-# Get timestamp (can be changed according to our preferences)
-def get_timestamp():
-    ts = datetime.utcnow()
-
-    return ts.strftime('%Y-%m-%dT%H:%M:%SZ')
-
-# Get list of all agent ids (including manager's)
-def get_agents(wc):
-    body = wc.req('GET', 'agents')
-    
-    agents_ids = []
-    for agent in body['data']['affected_items']:
-        agents_ids.append(agent['id'])
-
-    return body, agents_ids
-
-# Check if syscheck enabled
-def check_syscheck(wc, agent_id):
-    body = wc.req('GET', 'agents/' + agent_id + '/config/syscheck/syscheck')
-
-    measurement_result = ('true' if body['data']['syscheck']['disabled'] == 'no' else 'false')
-
-    evidence = simple_evidence(get_id('05.3'), get_timestamp(), measurement_result, body)
-
-    return evidence
-
-# Check if rootcheck enabled
-def check_rootcheck(wc, agent_id):
-    body = wc.req('GET', 'agents/' + agent_id + '/config/syscheck/rootcheck')
-
-    measurement_result = ('true' if body['data']['rootcheck']['disabled'] == 'no' else 'false')
-
-    evidence = simple_evidence(get_id('05.3'), get_timestamp(), measurement_result, body)
-
-    return evidence
-
-# 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 = ('true' if email_notifications or slack_notifications or pagerduty_notifications else 'false')
-
-    evidence = simple_evidence(get_id('05.3'), get_timestamp(), measurement_result, body)
-
-    return evidence
-
-# 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'
-
-    evidence = simple_evidence(get_id('05.3'), get_timestamp(), measurement_result, body)
-
-    return evidence
-
-# Check last Syscheck & Rootcheck scan times
-# When producing 'real' evidence, make sure to provide differentiation between Syscheck and Rootcheck outputs.
-def check_last_scan_time(wc, agent_id):
-    body = wc.req('GET', 'syscheck/' + agent_id + '/last_scan')
-
-    measurement_result = body['data']['affected_items'][0]['end']
-
-    evidence1 = simple_evidence(get_id('05.4'), get_timestamp(), measurement_result, body)
-
-    body = wc.req('GET', 'rootcheck/' + agent_id + '/last_scan')
-
-    measurement_result = body['data']['affected_items'][0]['end']
-
-    evidence2 = simple_evidence(get_id('05.4'), get_timestamp(), measurement_result, body)
-
-    return evidence1, evidence2
-
-# Check if ClamAV daemon package installed
-def check_clamd_install(wc, agent_id):
-    body = wc.req('GET', 'syscollector/' + agent_id + '/packages')
-
-    measurement_result = 'false'
-
-    for package in body['data']['affected_items']:
-        if package['name'] == 'clamd':
-            measurement_result = 'true'
-            break
-    
-    evidence = simple_evidence(get_id('05.3'), get_timestamp(), measurement_result, body)
-
-    return evidence
-
-# Check if ClamAV daemon process running
-def check_clamd_process(wc, agent_id):
-    body = wc.req('GET', 'syscollector/' + agent_id + '/processes')
-
-    measurement_result = 'false'
-
-    for package in body['data']['affected_items']:
-        if package['name'] == 'clamd':
-            measurement_result = 'true'
-            break
-
-    evidence = simple_evidence(get_id('05.3'), get_timestamp(), measurement_result, body)
-
-    return evidence
diff --git a/wazuhclient.py b/wazuh_client.py
similarity index 100%
rename from wazuhclient.py
rename to wazuh_client.py
diff --git a/wazuh_evidence_collector.py b/wazuh_evidence_collector.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9f8c774c12eda6a0930161487cb223f60d950c9
--- /dev/null
+++ b/wazuh_evidence_collector.py
@@ -0,0 +1,196 @@
+from wazuh_client import WazuhClient
+from elasticsearch import Elasticsearch
+from elasticsearch_dsl import Search
+from evidence import Evidence, simple_evidence
+from random import randint
+from sys import maxsize
+from datetime import datetime
+
+wc = WazuhClient('192.168.33.10', 55000, 'wazuh-wui', 'wazuh-wui')
+es = Elasticsearch(
+        '192.168.33.10',
+        http_auth=('admin', 'changeme'),
+        scheme='https',
+        port=9200,
+        use_ssl=False,
+        verify_certs=False,
+        ssl_show_warn=False,
+    )
+
+# Get (temporary) ID
+def get_id(reqId):
+    return reqId + '-' + str(randint(0, maxsize))
+
+# Get timestamp (can be changed according to our preferences)
+def get_timestamp():
+    ts = datetime.utcnow()
+
+    return ts.strftime('%Y-%m-%dT%H:%M:%SZ')
+
+# Wrapepr function that runs all the checks (for every manager/agent)
+def run_full_check():
+
+    # Get list of all agent ids (including manager's)
+    def get_agents(wc):
+        body = wc.req('GET', 'agents')
+        
+        agents_ids = []
+        for agent in body['data']['affected_items']:
+            agents_ids.append(agent['id'])
+
+        return body, agents_ids
+
+    body, agents_ids = get_agents(wc)
+
+    agent_evidences = []
+
+    for agent in agents_ids:
+        agent_evidences.append(wazuh_monitoring_enabled(wc, agent))
+        agent_evidences.append(malvare_protection_enabled(wc, es, agent))
+
+    return agent_evidences
+
+# Check Wazuh's configuration
+def wazuh_monitoring_enabled(wc, agent_id):
+
+    # Check if syscheck enabled
+    def check_syscheck(wc, agent_id):
+        body = wc.req('GET', 'agents/' + agent_id + '/config/syscheck/syscheck')
+
+        measurement_result = body['data']['syscheck']['disabled'] == 'no'
+
+        return body, measurement_result
+
+    # Check if rootcheck enabled
+    def check_rootcheck(wc, agent_id):
+        body = wc.req('GET', 'agents/' + agent_id + '/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
+
+    raw_evidence = []
+
+    evidence, result_syscheck = check_syscheck(wc, agent_id)
+    raw_evidence.append(evidence)
+
+    evidence, result_rootcheck = check_rootcheck(wc, agent_id)
+    raw_evidence.append(evidence)
+    
+    evidence, result_aler_integration = check_alert_integrations(wc)
+    raw_evidence.append(evidence)
+
+    if result_syscheck and result_rootcheck and result_aler_integration:
+        return simple_evidence(get_id('05.3'), get_timestamp(), "true", raw_evidence)
+    else: 
+        return simple_evidence(get_id('05.3'), get_timestamp(), "false", raw_evidence)
+
+# Check if agent uses ClamAV or VirusTotal
+def malvare_protection_enabled(wc, es, agent_id):
+
+    # 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_id):
+        body = wc.req('GET', 'syscollector/' + agent_id + '/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_id):
+        s = Search(using=es, index="wazuh-alerts-*") \
+        .query("match", predecoder__program_name="clamd") \
+        .query("match", rule__description="Clamd restarted") \
+        .query("match", agent__id=agent_id) 
+
+        body = s.execute().to_dict()
+
+        measurement_result = len(body['hits']['hits']) > 0
+
+        return body, measurement_result
+
+    raw_evidence = []
+
+    evidence, result_virus_total = check_virus_total_integration(wc)
+    raw_evidence.append(evidence)
+
+    evidence, result_lamd_process = check_clamd_process(wc, agent_id)
+    raw_evidence.append(evidence)
+    
+    evidence, result_clamd_logs = check_clamd_logs_elastic(es, agent_id)
+    raw_evidence.append(evidence)
+
+    if result_virus_total or (result_lamd_process and result_clamd_logs):
+        return simple_evidence(get_id('05.4'), get_timestamp(), "true", raw_evidence)
+    else: 
+        return simple_evidence(get_id('05.4'), get_timestamp(), "false", raw_evidence)
+
+# Check last Syscheck & Rootcheck scan times
+# When producing 'real' evidence, make sure to provide differentiation between Syscheck and Rootcheck outputs.
+def check_last_scan_time(wc, agent_id):
+    body = wc.req('GET', 'syscheck/' + agent_id + '/last_scan')
+
+    measurement_result = body['data']['affected_items'][0]['end']
+
+    evidence1 = simple_evidence(get_id('05.4'), get_timestamp(), measurement_result, body)
+
+    body = wc.req('GET', 'rootcheck/' + agent_id + '/last_scan')
+
+    measurement_result = body['data']['affected_items'][0]['end']
+
+    evidence2 = simple_evidence(get_id('05.4'), get_timestamp(), measurement_result, body)
+
+    return evidence1, evidence2