def remove_field_feed(request): """ It allows to modify the feed by removing a certain field and loading the new feed configuration """ backup_data = read_json_file(custom_msu_json_feed_path) data = read_json_file(custom_msu_json_feed_path) data_removed_field = dict(data['vulnerabilities']['CVE-010'][0]) data_removed_field.pop(request.param, None) data['vulnerabilities']['CVE-010'][0] = data_removed_field write_json_file(custom_msu_json_feed_path, data) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='Windows10') yield request.param write_json_file(custom_msu_json_feed_path, backup_data) vd.clean_vuln_and_sys_programs_tables() truncate_file(LOG_FILE_PATH)
def override_wazuh_conf(configuration, set_password): # Stop Wazuh control_service('stop', daemon='wazuh-authd') time.sleep(1) check_daemon_status(running=False, daemon='wazuh-authd') truncate_file(LOG_FILE_PATH) # Configuration for testing test_config = set_section_wazuh_conf(configuration.get('sections')) # Set new configuration write_wazuh_conf(test_config) # reset_client_keys clean_client_keys_file() # reset password reset_password(set_password) time.sleep(1) # Start Wazuh control_service('start', daemon='wazuh-authd') """Wait until agentd has begun""" def callback_agentd_startup(line): if 'Accepting connections on port 1515' in line: return line return None log_monitor = FileMonitor(LOG_FILE_PATH) log_monitor.start(timeout=30, callback=callback_agentd_startup) time.sleep(1)
def modify_feed(test_data, request): """ Modify the redhat OVAL feed, setting a test field value """ backup_data = file.read_xml_file(file_path=custom_redhat_oval_feed_path, namespaces=vd.XML_FEED_NAMESPACES, xml_header=True) modified_data = replace_regex(pattern=test_data['pattern'], new_value=test_data['update'], data=str(backup_data), replace_group=True) file.write_file(file_path=custom_redhat_oval_feed_path, data=modified_data) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='RHEL8') yield file.write_file(file_path=custom_redhat_oval_feed_path, data=backup_data) vd.clean_vuln_and_sys_programs_tables() file.truncate_file(LOG_FILE_PATH)
def test_agentd_state(configure_environment, test_case: list): global remoted_server if remoted_server is not None: remoted_server.stop() # Stop service control_service('stop') if 'interval' in test_case['input']: set_state_interval(test_case['input']['interval'], internal_options) else: set_state_interval(1, internal_options) # Truncate ossec.log in order to watch it correctly truncate_file(LOG_FILE_PATH) # Remove state file to check if agent behavior is as expected os.remove(state_file_path) if os.path.exists(state_file_path) else None # Add dummy key in order to communicate with RemotedSimulator add_custom_key() # Start service control_service('start') # Start RemotedSimulator if test case need it if 'remoted' in test_case['input'] and test_case['input']['remoted']: remoted_server = RemotedSimulator(protocol='tcp', mode='DUMMY_ACK', client_keys=CLIENT_KEYS_PATH) # Check fields for every expected output type for expected_output in test_case['output']: check_fields(expected_output)
def restart_logcollector(get_configuration, request): """Reset log file and start a new monitor.""" control_service('stop', daemon=DAEMON_NAME) truncate_file(LOG_FILE_PATH) file_monitor = FileMonitor(LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) control_service('start', daemon=DAEMON_NAME)
def modify_feed(test_data, custom_input, request): """ Modify the MSU feed, setting a test field value """ backup_data = read_json_file(custom_msu_json_feed_path) data = read_json_file(custom_msu_json_feed_path) modified_data = dict(data['vulnerabilities']['CVE-010'][0]) modified_data[test_data['field']] = custom_input data['vulnerabilities']['CVE-010'][0] = modified_data write_json_file(custom_msu_json_feed_path, data) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='Windows10') yield write_json_file(custom_msu_json_feed_path, backup_data) vd.clean_vuln_and_sys_programs_tables() truncate_file(LOG_FILE_PATH)
def test_agentd_state_config(configure_environment, test_case: list): control_service('stop', 'wazuh-agentd') # Truncate ossec.log in order to watch it correctly truncate_file(LOG_FILE_PATH) # Remove state file to check if agent behavior is as expected os.remove(state_file_path) if os.path.exists(state_file_path) else None # Set state interval value according to test case specs set_state_interval(test_case['interval'], internal_options) control_service('start', 'wazuh-agentd') # Check if test require checking state file existance if 'state_file_exist' in test_case: if test_case['state_file_exist']: # Wait until state file was dumped time.sleep(test_case['interval']) assert test_case['state_file_exist'] == os.path.exists(state_file_path) # Follow ossec.log to find desired messages by a callback wazuh_log_monitor = FileMonitor(LOG_FILE_PATH) wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=callbacks.get(test_case['log_expect']), error_message='Event not found') assert wazuh_log_monitor.result() # Check if test require checking agentd status if 'agentd_ends' in test_case: assert (test_case['agentd_ends'] is not check_if_process_is_running('wazuh-agentd'))
def modify_feed(test_values, request): """ Modify the MSU OVAL feed, setting a test field value """ backup_data = read_json_file(custom_msu_json_feed_path) modified_data = dict(backup_data) # Insert key:value pair as string, since otherwise, you could not insert lists or dictionaries as a key modified_string_data = vd.insert_data_json_feed(data=modified_data, field_name=test_values[0], field_value=test_values[1], append_data=None) write_file(custom_msu_json_feed_path, modified_string_data) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='Windows10') yield write_json_file(custom_msu_json_feed_path, backup_data) vd.clean_vuln_and_sys_programs_tables() truncate_file(LOG_FILE_PATH)
def test_providers_no_os(clean_vuln_tables, get_configuration, configure_environment): """ Check if modulesd downloads the feeds without specifing the os version. """ check_apply_test({'test_providers_no_os'}, get_configuration['tags']) provider_name = get_configuration['metadata']['provider_name'] # Those providers that aren't expected to work without the <os> tag. try: control_service('restart') except ValueError: assert 'error' in get_configuration['metadata'] if 'error' in get_configuration['metadata']: wazuh_log_monitor.start(timeout=vd.VULN_DETECTOR_GLOBAL_TIMEOUT, callback=vd.make_vuln_callback(r".* \(\d+\): Configuration error at.*", prefix='.*wazuh-modulesd.*'), error_message=f"Error log 'Configuration error at '/var/ossec/etc/ossec.conf'.' " f"not found") else: for os in get_configuration['metadata']['os']: if os != '': os_name = f"{provider_name} {os}" else: os_name = f"JSON {provider_name}" if 'Red Hat' in provider_name else f"{provider_name}" wazuh_log_monitor.start( timeout=80 if 'Red Hat' in os_name else VULN_DETECTOR_GLOBAL_TIMEOUT, callback=make_vuln_callback(f"Starting '{os_name}' database update"), error_message=f"Could not find {os_name} update starting log", )
def restart_modulesd(get_configuration, request): # Reset ossec.log and start a new monitor control_service('stop', daemon='wazuh-modulesd') truncate_file(LOG_FILE_PATH) file_monitor = FileMonitor(LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) control_service('start', daemon='wazuh-modulesd')
def modify_feed(test_values, request): """Modify the Arch Linux JSON feed by setting a test tag value.""" backup_data = read_json_file(custom_archlinux_json_feed_path) modified_data = deepcopy(backup_data) modified_data[0]['replace_this'] = test_values[1] modified_string = json.dumps(modified_data, indent=4) new_key = test_values[0] if isinstance(new_key, str): new_key = f'"{new_key}"' else: new_key = str(new_key) modified_string = modified_string.replace('"replace_this"', new_key) write_file(custom_archlinux_json_feed_path, modified_string) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='ARCH') yield write_json_file(custom_archlinux_json_feed_path, backup_data) vd.clean_vuln_and_sys_programs_tables() file.truncate_file(LOG_FILE_PATH)
def remove_tag_feed(request): """ It allows to modify the feed by removing a certain tag and loading the new feed configuration """ backup_data = file.read_xml_file(file_path=custom_canonical_oval_feed_path, namespaces=vd.XML_FEED_NAMESPACES) data_removed_tag = replace_regex(request.param['pattern'], '', str(backup_data)) file.write_file(file_path=custom_canonical_oval_feed_path, data=data_removed_tag) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='BIONIC') yield request.param file.write_file(file_path=custom_canonical_oval_feed_path, data=backup_data) vd.clean_vuln_and_sys_programs_tables() file.truncate_file(LOG_FILE_PATH)
def modify_feed(test_values, request): """ Modify the Debian OVAL feed, setting a test tag value """ backup_data = file.read_xml_file(file_path=custom_debian_oval_feed_path, namespaces=vd.XML_FEED_NAMESPACES, xml_header=True) modified_data = insert_xml_tag(pattern=insert_pattern, tag=test_values[0], value=test_values[1], data=str(backup_data)) file.write_file(file_path=custom_debian_oval_feed_path, data=modified_data) vd.clean_vuln_and_sys_programs_tables() control_service('restart', daemon='wazuh-modulesd') vd.set_system(system='BUSTER') yield file.write_file(file_path=custom_debian_oval_feed_path, data=backup_data) vd.clean_vuln_and_sys_programs_tables() truncate_file(LOG_FILE_PATH)
def clean_environment(original_conf): control_service('stop') for d in directories_list: shutil.rmtree(d, ignore_errors=True) with open(WAZUH_CONF, 'w') as o_conf: o_conf.writelines(original_conf)
def configure_api_environment(get_configuration, request): """Configure a custom environment for API testing. Restart API is needed for applying the configuration.""" # Save current configuration backup_config = get_api_conf(WAZUH_API_CONF) # Save current security config backup_security_config = get_api_conf( WAZUH_SECURITY_CONF) if os.path.exists(WAZUH_SECURITY_CONF) else None # Set new configuration api_config = get_configuration.get('configuration', None) if api_config: write_api_conf(WAZUH_API_CONF, api_config) # Set security configuration security_config = get_configuration.get('security_config', None) if security_config: write_security_conf(WAZUH_SECURITY_CONF, security_config) # Create test directories if hasattr(request.module, 'test_directories'): test_directories = getattr(request.module, 'test_directories') for test_dir in test_directories: oldmask = os.umask(0000) os.makedirs(test_dir, exist_ok=True, mode=0O777) os.umask(oldmask) # Call extra functions before yield if hasattr(request.module, 'extra_configuration_before_yield'): func = getattr(request.module, 'extra_configuration_before_yield') func() yield # Remove created folders (parents) if hasattr(request.module, 'test_directories'): for test_dir in test_directories: shutil.rmtree(test_dir, ignore_errors=True) # Restore previous configuration if backup_config: write_api_conf(WAZUH_API_CONF, backup_config) # Restore previous RBAC configuration if backup_security_config: write_security_conf(WAZUH_SECURITY_CONF, backup_security_config) elif security_config and not backup_security_config: os.remove(WAZUH_SECURITY_CONF) # Call extra functions after yield if hasattr(request.module, 'extra_configuration_after_yield'): func = getattr(request.module, 'extra_configuration_after_yield') func() if hasattr(request.module, 'force_restart_after_restoring'): if getattr(request.module, 'force_restart_after_restoring'): control_service('restart')
def restart_modulesd_catching_ossec_conf_error(request): control_service('stop', daemon='wazuh-modulesd') truncate_file(LOG_FILE_PATH) file_monitor = FileMonitor(LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) try: control_service('start', daemon='wazuh-modulesd') except (ValueError, CalledProcessError): pass
def restart_syscheck_function(get_configuration, request): """ Reset ossec.log and start a new monitor. """ control_service('stop', daemon='wazuh-syscheckd') truncate_file(fim.LOG_FILE_PATH) file_monitor = FileMonitor(fim.LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) control_service('start', daemon='wazuh-syscheckd')
def restart_remoted(get_configuration, request): # Reset ossec.log and start a new monitor control_service('stop', daemon=DAEMON_NAME) truncate_file(LOG_FILE_PATH) file_monitor = FileMonitor(LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) try: control_service('start', daemon=DAEMON_NAME) except sb.CalledProcessError: pass
def clean_environment(original_conf): control_service('stop') for r in reg_list: delete_registry(registry_parser[KEY], r, KEY_ALL_ACCESS | KEY_WOW64_64KEY) with open(WAZUH_CONF, 'w') as o_conf: o_conf.writelines(original_conf) control_service('start')
def restart_wazuh(get_configuration, request): # Stop Wazuh control_service('stop') # Reset ossec.log and start a new monitor truncate_file(LOG_FILE_PATH) file_monitor = FileMonitor(LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) # Start Wazuh control_service('start')
def restart_syscheckd_each_time(request): control_service('stop', daemon='ossec-syscheckd') truncate_file(LOG_FILE_PATH) file_monitor = FileMonitor(LOG_FILE_PATH) setattr(request.module, 'wazuh_log_monitor', file_monitor) if not os.path.exists(testdir): os.mkdir(testdir) control_service('start', daemon='ossec-syscheckd') detect_initial_scan(file_monitor)
def restart_wazuh_alerts(get_configuration, request): # Stop Wazuh control_service('stop') # Reset alerts.json and start a new monitor truncate_file(ALERT_FILE_PATH) file_monitor = FileMonitor(ALERT_FILE_PATH) setattr(request.module, 'wazuh_alert_monitor', file_monitor) # Start Wazuh control_service('start')
def modify_metadata_vuldet_feed(feed, timestamp): """Function to modify the timestamp value of the metadata table for a specific feed. Args: feed (str): The feed name. timestamp (str): The new timestamp value to set. """ query_string = f'update METADATA set TIMESTAMP="{timestamp}" where TARGET="{feed}"' control_service('stop', daemon='wazuh-db') make_query(CVE_DB_PATH, [query_string]) sleep(1) control_service('start', daemon='wazuh-db')
def test_configuration_age_datetime(new_datetime, get_files_list, get_configuration, create_file_structure_function, configure_environment): """Check if logcollector age option works correctly when date time of the system changes. Ensure that when date of the system change logcollector use properly age value, ignoring files that have not been modified for a time greater than age value using current date. Raises: TimeoutError: If the expected callbacks are not generated. """ cfg = get_configuration['metadata'] age_seconds = time_to_seconds(cfg['age']) control_service('stop', daemon=DAEMON_NAME) truncate_file(LOG_FILE_PATH) wazuh_log_monitor = FileMonitor(LOG_FILE_PATH) control_service('start', daemon=DAEMON_NAME) TimeMachine.travel_to_future(time_to_timedelta(new_datetime)) for file in file_structure: for name in file['filename']: absolute_file_path = os.path.join(file['folder_path'], name) log_callback = logcollector.callback_match_pattern_file( cfg['location'], absolute_file_path) wazuh_log_monitor.start(timeout=5, callback=log_callback, error_message=f"{name} was not detected") fileinfo = os.stat(absolute_file_path) current_time = time.time() mfile_time = current_time - fileinfo.st_mtime if age_seconds <= int(mfile_time): log_callback = logcollector.callback_ignoring_file( absolute_file_path) wazuh_log_monitor.start( timeout=5, callback=log_callback, error_message=f"{name} was not ignored") else: with pytest.raises(TimeoutError): log_callback = logcollector.callback_ignoring_file( absolute_file_path) wazuh_log_monitor.start( timeout=5, callback=log_callback, error_message=f"{name} was not ignored") TimeMachine.time_rollback()
def prepare_agent(mock_agent): control_service('stop', daemon='wazuh-db') vd.clean_vd_tables(mock_agent) vd.insert_package(agent=mock_agent, vendor="Red Hat, Inc.") vd.insert_vulnerability() control_service('start', daemon='wazuh-db') yield mock_agent vd.clean_vuln_and_sys_programs_tables(mock_agent)
def check_queue_socket_event(raw_events=EXAMPLE_MESSAGE_PATTERN, timeout=30, update_position=False): """Allow searching for an expected event in the queue socket. Args: raw_events (str or list<str>): Pattern/s regex to be found in the socket. timeout (int): Maximum search time of the event in the socket. Default is 30 to allow enough time for the other thread to send messages. update_position (boolean): True to search in the entire queue, False to search in the current position of the queue. Raises: TimeoutError: if could not find the pattern regex event in the queue socket. """ # Do not delete. Function required for MITM to work def intercept_socket_data(data): return data error_message = 'Could not find the expected event in queue socket' # Get the event list event_list = [raw_events] if isinstance(raw_events, str) else raw_events # Stop analysisd daemon to free the socket. Important note: control_service(stop) deletes the daemon sockets. control_service('stop', daemon='wazuh-analysisd') # Create queue socket if it does not exist. file.bind_unix_socket(QUEUE_SOCKET_PATH, UDP) # Intercept queue sockets events mitm = monitoring.ManInTheMiddle(address=QUEUE_SOCKET_PATH, family='AF_UNIX', connection_protocol=UDP, func=intercept_socket_data) mitm.start() # Monitor MITM queue socket_monitor = monitoring.QueueMonitor(mitm.queue) try: # Start socket monitoring for event in event_list: socket_monitor.start(timeout=timeout, callback=monitoring.make_callback( event, '.*'), error_message=error_message, update_position=update_position) finally: mitm.shutdown() control_service('start', daemon='wazuh-analysisd')
def insert_custom_package(**kwargs): """Insert a custom package in sys_programs table Args: kwargs (dict): Required arguments of the ``insert_package`` function (see its argument list) """ control_service('stop', daemon='wazuh-db') insert_package(**kwargs) sleep(1) control_service('start', daemon='wazuh-db')
def clean_vuln_and_sys_programs_tables(agent='000'): """Clean vulnerability detector and sys programs table/s Args: agent (str): id of the agent """ control_service('stop', daemon='wazuh-db') clean_vd_tables(agent) sleep(1) control_service('start', daemon='wazuh-db')
def clean_client_keys_file(): client_keys_path = os.path.join(WAZUH_PATH, 'etc', 'client.keys') # Stop Wazuh control_service('stop') # Clean client.keys try: with open(client_keys_path, 'w') as client_file: client_file.close() except IOError as exception: raise # Start Wazuh control_service('start')
def set_custom_system(**kwargs): """It allows to modify the agent system, modifying the corresponding entry in the agent table of the global.d Args: kwargs (dict): Required arguments of the ``modify_system`` function (see its argument list) """ control_service('stop', daemon='wazuh-db') # Wait until modulesd is restarted to avoid overwriting the system sleep(5) modify_system(**kwargs) control_service('start', daemon='wazuh-db')