-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: create modules for E2E Vuln operations
- Loading branch information
Showing
19 changed files
with
652 additions
and
430 deletions.
There are no files selected for viewing
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
Empty file.
55 changes: 55 additions & 0 deletions
55
deps/wazuh_testing/wazuh_testing/end_to_end/configuration.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,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
16
deps/wazuh_testing/wazuh_testing/end_to_end/indexer_api.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,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 |
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,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) |
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,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) |
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,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 |
File renamed without changes.
90 changes: 90 additions & 0 deletions
90
deps/wazuh_testing/wazuh_testing/end_to_end/remote_operations_handler.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,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) |
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,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) |
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,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) |
Oops, something went wrong.