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)
Exemple #3
0
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)
Exemple #5
0
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)
Exemple #7
0
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'))
Exemple #8
0
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)
Exemple #9
0
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",
            )
Exemple #10
0
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)
Exemple #14
0
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)
Exemple #15
0
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')
Exemple #16
0
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')
Exemple #18
0
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')
Exemple #20
0
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)
Exemple #22
0
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)
Exemple #26
0
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')
Exemple #29
0
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')