Skip to content

Commit

Permalink
feat: create modules for E2E Vuln operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Rebits committed Nov 15, 2023
1 parent 21176da commit b9f1101
Show file tree
Hide file tree
Showing 19 changed files with 652 additions and 430 deletions.
11 changes: 11 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@

fetched_alerts_json_path = os.path.join(gettempdir(), 'alerts.json')

configuration_filepath_os = {
'linux': '/var/ossec/etc/ossec.conf',
'windows': r'C:\\Program Files (x86)\\ossec-agent\\ossec.conf',
'macos': '/Library/Ossec/etc/ossec.conf'
}
logs_filepath_os = {
'linux': '/var/ossec/logs/ossec.log',
'windows': r'C:\\Program Files (x86)\\ossec-agent\\ossec.log',
'macos': '/Library/Ossec/logs/ossec.log'
}


@retry(Exception, attempts=3, delay=5)
def get_alert_indexer_api(query, credentials, ip_address, index='wazuh-alerts-4.x-*'):
Expand Down
Empty file.
55 changes: 55 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from multiprocessing.pool import ThreadPool
import xml.dom.minidom
from ansible.parsing.dataloader import DataLoader

from wazuh_testing.end_to_end import configuration_filepath_os
from wazuh_testing.tools.configuration import set_section_wazuh_conf


# Configuration methods
def backup_configurations(host_manager):
backup_configurations = {}
for host in host_manager.get_group_hosts('all'):
host_variables = host_manager.get_host_variables(host)
host_os = host_variables['os_name']
configuration_file_path = configuration_filepath_os[host_os]
current_configuration = host_manager.get_file_content(str(host), configuration_file_path)
backup_configurations[str(host)] = current_configuration
return backup_configurations


def restore_backup(host_manager, backup_configurations):
for host in host_manager.get_group_hosts('all'):
host_variables = host_manager.get_host_variables(host)
host_os = host_variables['os_name']
configuration_file_path = configuration_filepath_os[host_os]
host_manager.modify_file_content(str(host), configuration_file_path, backup_configurations[str(host)])


def configure_environment(host_manager, configurations):
def configure_host(host, host_configuration_role):
host_os = host_manager.get_host_variables(host)['os_name']
configuration_file_path = configuration_filepath_os[host_os]

host_groups = host_manager.get_host_groups(host)
host_configuration = None
if 'manager' in host_groups:
host_configuration = host_configuration_role['manager']
elif 'agent' in host_groups:
host_configuration = host_configuration_role['agent']

current_configuration = host_manager.get_file_content(str(host), configuration_file_path)
new_configuration = set_section_wazuh_conf(host_configuration[0].get('sections'), current_configuration.split("\n"))

new_configuration = [line for line in new_configuration if line.strip() != ""]
dom = xml.dom.minidom.parseString(''.join(new_configuration))
new_configuration = "\n".join(dom.toprettyxml().split("\n")[1:])

host_manager.modify_file_content(str(host), configuration_file_path, new_configuration)


loader = DataLoader()
configure_environment_parallel_map = [ (host, configurations) for host in host_manager.get_group_hosts('all')]

with ThreadPool() as pool:
pool.starmap(configure_host, configure_environment_parallel_map)
16 changes: 16 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/indexer_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import requests


STATE_INDEX_NAME = 'wazuh-vulnerabilities-states'

# Indexer API methods
def get_vuln_state_value(host_manager, credentials={'user': 'wazuh', 'password': 'wazuh'}):
url = f"https://{host_manager.get_master_ip(host_manager)}:9200/{STATE_INDEX_NAME}_search?"
query = {
"query": {
"match_all": {}
}
}
response = requests.get(url=url, params={'pretty': 'true'}, json=query, verify=False,
auth=requests.auth.HTTPBasicAuth(credentials['user'], credentials['password']))
return response.text
18 changes: 18 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from wazuh_testing.end_to_end import logs_filepath_os


def truncate_agents_logs(host_manager):
for agent in host_manager.get_group_hosts('agent'):
host_os_name = host_manager.get_host_variables(agent)['os_name']
host_manager.truncate_file(agent, logs_filepath_os[host_os_name])

def truncate_managers_logs(host_manager):
for agent in host_manager.get_group_hosts('manager'):
host_os_name = host_manager.get_host_variables(agent)['os_name']
host_manager.truncate_file(agent, logs_filepath_os[host_os_name])

def truncate_logs(host_manager):
# for manager in host_manager.get_group_hosts('manager'):
# host_manager.truncate_file(manager, '/var/ossec/logs/alerts/alerts.json')
truncate_managers_logs(host_manager)
truncate_agents_logs(host_manager)
85 changes: 85 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/monitoring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import os
import tempfile

from wazuh_testing.end_to_end import logs_filepath_os
from wazuh_testing.tools.file import create_temp_file
from wazuh_testing.tools.monitoring import HostMonitor
from wazuh_testing.end_to_end.regex import get_event_regex


def monitoring_events(host_manager, monitoring_data):
monitoring_file_content = ''
results = {}

for host, data in monitoring_data.items():
monitoring_file_content += f"{host}:\n"
for monitoring_event in data:
string_limiter = "'" if '"' in monitoring_event.get("regex", "") else '"'
print(f"String limiter {string_limiter}")
monitoring_file_content += f' - regex: {string_limiter}{monitoring_event.get("regex", "")}{string_limiter}\n'
monitoring_file_content += f' path: {string_limiter}{monitoring_event.get("path", "")}{string_limiter}\n'
monitoring_file_content += f' timeout: {monitoring_event.get("timeout", 0)}\n'

temp_file = create_temp_file(monitoring_file_content)
try:
temporal_directory = tempfile.TemporaryDirectory()
print(temporal_directory.name)
results.update(HostMonitor(inventory_path=host_manager.get_inventory_path(), messages_path=temp_file, tmp_path=temporal_directory.name).run())
except TimeoutError:
pass

os.remove(temp_file)

return results


def generate_monitoring_logs_all_agent(host_manager, regex_list, timeout_list):
monitoring_data = {}
for agent in host_manager.get_group_hosts('agent'):
monitoring_data[agent] = []
for index, regex_index in enumerate(regex_list):
os_name = host_manager.get_host_variables(agent)['os_name']
monitoring_data[agent].append({
'regex': regex_index,
'path': logs_filepath_os[os_name],
'timeout': timeout_list[index]

})
return monitoring_data


def generate_monitoring_logs_manager(host_manager, manager, regex, timeout):
monitoring_data = {}
os_name = host_manager.get_host_variables(manager)['os_name']
monitoring_data[manager] = [{
'regex': regex,
'path': logs_filepath_os[os_name],
'timeout': timeout

}]

return monitoring_data


def generate_monitoring_alerts_all_agent(host_manager, events_metadata):
monitoring_data = {}

for agent in host_manager.get_group_hosts('agent'):
host_os_name = host_manager.get_host_variables(agent)['os'].split('_')[0]
metadata_agent = events_metadata[host_os_name]

if not host_manager.get_host_variables(agent)['manager'] in monitoring_data:
monitoring_data[host_manager.get_host_variables(agent)['manager']] = []

for event in metadata_agent[agent.get_host_variables(agent)['arch']]:
event['parameters']['HOST_NAME'] = agent
monitoring_element = {
'regex': get_event_regex(event),
'path': '/var/ossec/logs/alerts/alerts.json',
'timeout': 120,
}

if 'parameters' in metadata_agent:
monitoring_element['parameters'] = metadata_agent['parameters']

monitoring_data[host_manager.get_host_variables(agent)['manager']].append(monitoring_element)
41 changes: 41 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/regex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

regex = {
'syscollector_scan_start': {
'regex': '.*INFO: Starting evaluation.'
},
'syscollector_scan_end': {
'regex': '.*INFO: Starting evaluation.'
},
'syscollector_install_package_alert_yum': {
'regex': '.*installed.*agent".*"name":"(\S+)".*Installed: (\S+).*?(\S+)',
'parameters': ['PACKAGE_NAME', 'PACKAGE_VERSION', 'HOST_NAME']
},
'syscollector_install_package_alert_apt': {
'regex': '.*New dpkg \(Debian Package\) installed.*.*agent".*"name":"(\S+).*package":"(\S+)","arch":"amd64","version":"(\S+)"',
'parameters': ['HOST_NAME', 'PACKAGE_NAME', 'PACKAGE_VERSION']
},
'syscollector_upgrade_package_alert_yum': {
'regex': '.*Yum package updated.*agent".*"name":"(\S+)".*Updated: (\S+).*?(\S+)',
'parameters': ['PACKAGE_NAME', 'PACKAGE_VERSION', 'HOST_NAME']
},
'vulnerability_alert':{
'regex': '.*HOST_NAME.*package:.*name":"PACKAGE_NAME".*version":"PACKAGE_VERSION".*"architecture":"ARCHITECTURE.*"cve":"CVE"',
'parameters': ['HOST_NAME', 'CVE', 'PACKAGE_NAME', 'PACKAGE_VERSION', 'ARCHITECTURE']
}
}


def get_event_regex(event):
"""
"""
expected_event = regex[event['event']]
expected_regex = expected_event['regex']

if 'parameters' in expected_event and not 'parameters' in event:
raise Exception(f"Not provided enaugh data to create regex. Missing {event['PARAMETERS']}")
elif 'parameters' in event:
for parameter in expected_event['parameters']:
expected_regex = expected_regex.replace(parameter, event['parameters'][parameter])


return expected_regex
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
from wazuh_testing.end_to_end.regex import get_event_regex
from wazuh_testing.end_to_end.monitoring import monitoring_events
from multiprocessing.pool import ThreadPool


def launch_remote_operation(host, operation, operation_data, host_manager):
host_os_name = host_manager.get_host_variables(host)['os'].split('_')[0]
host_os_arch = host_manager.get_host_variables(host)['arch']

system = host_manager.get_host_variables(host)['os_name']
if system == 'linux':
system = host_manager.get_host_variables(host)['os'].split('_')[0]


if operation == 'install_package':
package_data = operation_data['package']
package_url = package_data[host_os_name][host_os_arch]
host_manager.install_package(host, package_url, system)

elif operation == 'remove_package':
package_data = operation_data['package']
package_name = package_data[host_os_name]
host_manager.remove_package(host, package_name, system)

elif operation == 'check_agent_vulnerability':
if operation_data['parameters']['alert_indexed']:
check_vuln_indexer(host_manager, operation_data['vulnerability_data'])
if operation_data['parameters']['alert']:
check_vuln_alert(host_manager, operation_data['vulnerability_data'])
if operation_data['parameters']['api']:
check_vuln_alert_api(host_manager, operation_data['vulnerability_data'])
if operation_data['parameters']['state_indice']:
check_vuln_state_index(host_manager, operation_data['vulnerability_data'])


def check_vuln_state_index(host_manager, vulnerability_data):
pass

def check_vuln_indexer(host_manager, vulnerability_data):
pass

def check_vuln_alert_api(host_manager, vulnerability_data):
pass

def check_vuln_alert(host_manager, vulnerability_data):
monitoring_data = {}

for agent in host_manager.get_group_hosts('agent'):
host_os_name = host_manager.get_host_variables(agent)['os'].split('_')[0]
host_os_arch = host_manager.get_host_variables(agent)['arch']

agent_vulnerability_data_parameters = vulnerability_data[host_os_name][host_os_arch]
agent_vulnerability_data_parameters['HOST_NAME'] = agent

agent_vulnerability_data = {
'event': 'vulnerability_alert',
'parameters': agent_vulnerability_data_parameters
}

regex = get_event_regex(agent_vulnerability_data)

monitoring_element = {
'regex': regex,
'path': '/var/ossec/logs/alerts/alerts.json',
'timeout': 30,
}

if host_manager.get_host_variables(agent)['manager'] not in monitoring_data:
monitoring_data[host_manager.get_host_variables(agent)['manager']] = []

monitoring_data[host_manager.get_host_variables(agent)['manager']].append(monitoring_element)

monitoring_events(host_manager, monitoring_data)


def launch_remote_sequential_operation_on_agent(agent, task_list, host_manager):
if task_list:
for task in task_list:
task_keys = list(task.keys())
task_values = list(task.values())
operation, operation_data = task_keys[0], task_values[0]
launch_remote_operation(agent, operation, operation_data, host_manager)


def launch_parallel_operations(task_list, host_manager, group='agent'):
agents = host_manager.get_group_hosts('agent')
parallel_configuration = [(agent, task_list, host_manager) for agent in agents]
with ThreadPool() as pool:
# Use the pool to map the function to the list of hosts
pool.starmap(launch_remote_sequential_operation_on_agent, parallel_configuration)
4 changes: 4 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def control_environment(host_manager, operation, group_list):
for group in group_list:
for host in host_manager.get_group_hosts(group):
host_manager.handle_wazuh_services(host, operation)
19 changes: 19 additions & 0 deletions deps/wazuh_testing/wazuh_testing/end_to_end/waiters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from wazuh_testing.end_to_end.monitoring import generate_monitoring_logs_manager, monitoring_events
from wazuh_testing.end_to_end.wazuh_api import get_agents_id



def wait_until_vd_is_updated(host_manager):
monitoring_data = {}
for manager in host_manager.get_group_hosts('manager'):
monitoring_data = generate_monitoring_logs_manager(host_manager, manager, 'Starting vulnerability scan', 600)

monitoring_events(host_manager, monitoring_data)


def wait_until_vuln_scan_agents_finished(host_manager):
for agent in host_manager.get_group_hosts('agent'):
manager_host = host_manager.get_host_variables(agent)['manager']
agents_id = get_agents_id(host_manager)
monitoring_data = generate_monitoring_logs_manager(host_manager, manager_host,rf"Finished vulnerability assessment for agent '{agents_id[agent]}'", 30)
monitoring_events(host_manager, monitoring_data)

0 comments on commit b9f1101

Please sign in to comment.