Example #1
0
def test_audit_key(audit_key, path, get_configuration, configure_environment,
                   restart_syscheckd):
    """Checks <audit_key> functionality by adding a audit rule and checking if alerts with that key are triggered when
    a file is created.

    This test is intended to be used with valid configurations

    Parameters
    ----------
    audit_key : str
        Name of the audit_key to monitor
    path : str
        Path of the folder to be monitored
    """
    check_apply_test({audit_key}, get_configuration['tags'])

    # Add watch rule
    os.system("auditctl -w " + path + " -p wa -k " + audit_key)

    # Restart and for wazuh
    truncate_file(LOG_FILE_PATH)
    control_service('restart')
    wazuh_log_monitor = FileMonitor(LOG_FILE_PATH)
    detect_initial_scan(wazuh_log_monitor)

    # Look for audit_key word
    create_file(REGULAR, path, "testfile")
    events = wazuh_log_monitor.start(timeout=30,
                                     callback=callback_audit_key,
                                     accum_results=1).result()
    assert audit_key in events

    # Remove watch rule
    os.system("auditctl -W " + path + " -p wa -k " + audit_key)
def test_ambiguous_complex(tags_to_apply, get_configuration,
                           configure_environment, restart_syscheckd,
                           wait_for_initial_scan):
    """ Automatic test for each configuration given in the yaml.

    The main purpose of this test is to check that syscheck will apply different configurations between subdirectories
    properly. Example:

    <directories realtime='yes' report_changes='yes' check_all='yes' check_owner='no'> /testdir </directories>
    <directories realtime='yes' report_changes='no' check_sum='no' check_owner='yes'> /testdir/subdir </directories>

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
      the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Standard params for each test
    file_list = ['example.csv']
    min_timeout = DEFAULT_TIMEOUT
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    conf_list, check_list = get_dir_and_attributes(
        get_configuration['elements'])
    param = (file_list, min_timeout, scheduled)
    # For every directory, apply each test depending of its attributes.
    # We assume we've set restrict attribute so it should not expect events
    # For further functionality with restrict, run ../test_restrict tests
    for directory, checkers in zip(conf_list, check_list):
        for path, attributes in directory.items():
            trigger = False if 'restrict' in attributes else True
            apply_test(path, attributes, trigger, checkers, param)
Example #3
0
def test_ambiguous_tags(folders, tags_to_apply, get_configuration,
                        configure_environment, restart_syscheckd,
                        wait_for_initial_scan):
    """Checks if syscheck detects the event property 'tags' for each event.

    This test validates both situations, making sure that if tags='no', there won't be a
    tags event property.

    This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.

    Parameters
    ----------
    folders : list
        Monitored directories
    tags_to_apply : set
        Run test if matches with a configuration identifier, skip otherwise
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    # Check that events inside folder[0] do not contain the key 'tags'.
    regular_file_cud(folders[0],
                     wazuh_log_monitor,
                     time_travel=scheduled,
                     min_timeout=DEFAULT_TIMEOUT,
                     validators_after_cud=[no_tag_validator])

    # Check that events inside folder[1] do contain the key 'tags'.
    regular_file_cud(folders[1],
                     wazuh_log_monitor,
                     time_travel=scheduled,
                     min_timeout=DEFAULT_TIMEOUT,
                     validators_after_cud=[tag_validator])
Example #4
0
def test_max_eps_on_start(get_configuration, configure_environment,
                          restart_syscheckd):
    """
    Checks that max_eps is respected when a big quatity of events are generated

    Before starting the service, a great number of files is created thanks to function `extra_configuration_before_yield`.
    After that, syscheck is launched and starts generating as much events as files created.

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
          the environment properly and restart the service.
    """
    check_apply_test({'max_eps'}, get_configuration['tags'])

    result = wazuh_log_monitor.start(timeout=150,
                                     accum_results=1000,
                                     callback=callback_syscheck_message,
                                     update_position=False).result()

    max_eps = int(get_configuration['metadata']['max_eps'])
    counter = Counter([date_time for date_time, _ in result])
    error_margin = (max_eps * 0.1)

    for date_time, n_occurrences in counter.items():
        assert n_occurrences <= round(
            max_eps + error_margin
        ), f'Sent {n_occurrences} but a maximum of {max_eps} was set'
Example #5
0
def test_scan_time(tags_to_apply,
                   get_configuration, configure_environment,
                   restart_syscheckd, wait_for_initial_scan):
    """ Check if there is a scan at a certain time

    scan_time option makes sure there is only one scan every 24 hours, at a certain time.

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Reformat given time to a readable format since it can be writen in several ways in ossec.conf
    scan_time = reformat_time(get_configuration['metadata']['scan_time'])
    current_time = datetime.now()

    # Calculate how much time we need to travel in time to make sure there hasn't been any scan until it is the given
    # time
    time_difference = (scan_time - current_time) if (scan_time - current_time).days == 0 else \
        ((scan_time - current_time) + timedelta(days=2))
    TimeMachine.travel_to_future(time_difference + timedelta(minutes=-30))
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT, callback=callback_detect_end_scan)
    TimeMachine.travel_to_future(timedelta(minutes=31))
    wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT, callback=callback_detect_end_scan)
def test_create_file_scheduled(folder, name, filetype, content, checkers, tags_to_apply, get_configuration,
                               configure_environment, restart_syscheckd, wait_for_initial_scan):
    """ Checks if a special or regular file creation is detected by syscheck using scheduled monitoring

        Regular files must be monitored. Special files must not.

        :param folder: Name of the monitored folder
        :param name: Name of the file
        :param filetype: Type of the file
        :param content: Content of the file
        :param checkers: Checks that will compared to the ones from the event

        * This test is intended to be used with valid configurations files. Each execution of this test will configure
          the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Create files
    create_file(filetype, folder, name, content=content)

    # Go ahead in time to let syscheck perform a new scan
    TimeMachine.travel_to_future(timedelta(hours=13))

    if filetype == REGULAR:
        # Wait until event is detected
        event = wazuh_log_monitor.start(
            timeout=DEFAULT_TIMEOUT, callback=callback_detect_event).result()
        validate_event(event, checkers)
    else:
        with pytest.raises(TimeoutError):
            wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT, callback=callback_detect_event)
def test_no_report_changes(folder, checkers, delete_dir, tags_to_apply,
                           get_configuration, configure_environment,
                           restart_syscheckd, wait_for_initial_scan):
    """ Check if duplicated directories in diff are deleted when changing
    report_changes to 'no' or deleting the monitored directories

    Since report_changes duplicates monitored files, we need to assert that once the original files are deleted,
    the duplicated ones are deleted too.

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan. This test will restart with a new
    configuration throughout its execution as well.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    filename = 'regularfile'
    fim_mode = get_configuration['metadata']['fim_mode']
    if delete_dir:
        check_when_deleted_directories(filename, folder, fim_mode)
    else:
        new_conf = change_conf(report_value='no')
        new_ossec_conf = set_section_wazuh_conf(new_conf[0].get('section'),
                                                new_conf[0].get('elements'))
        check_when_no_report_changes(filename, folder, fim_mode,
                                     new_ossec_conf)
Example #8
0
def test_check_others(path, checkers, get_configuration, configure_environment,
                      restart_syscheckd, wait_for_initial_scan):
    """Test the behaviour of several combinations of Check options over the same directory with Check_all disabled to
    avoid using the default check_all configuration. The order of the checks (including check_all="no") will be
    different on each case to test the behaviour of check_all="no".

    Example:
        check_all: "no" check_size: "yes" check_sum: "yes"
        check_all: "no" check_md5sum: "yes" check_mtime: "yes" check_group: "yes"
        check_md5sum: "yes" check_all: "no" check_mtime: "yes" check_group: "yes"
        ...

    This test is intended to be used with valid configurations files. Each execution of this test will configure the
    environment properly, restart the service and wait for the initial scan.

    :param path: Directory where the file is being created and monitored
    :param checkers: Dict with all the check options to be used
    """
    check_apply_test({'test_check_others'}, get_configuration['tags'])

    regular_file_cud(
        path,
        wazuh_log_monitor,
        min_timeout=15,
        options=checkers,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled')
Example #9
0
def test_check_others_individually(path, checkers, get_configuration,
                                   configure_environment, restart_syscheckd,
                                   wait_for_initial_scan):
    """Test the behaviour of every Check option individually without using the Check_all option. Check_all option will
    be set to "no" in order to avoid using the default check_all configuration.

    Example:
        check_all="no" check_sum="yes"
        check_all="no" check_mtime="yes"
        ...

    This test is intended to be used with valid configurations files. Each execution of this test will configure the
    environment properly, restart the service and wait for the initial scan.

    :param path: Directory where the file is being created and monitored
    :param checkers: Dict with all the check options to be used
    """
    check_apply_test({'test_check_others_individually'},
                     get_configuration['tags'])

    regular_file_cud(
        path,
        wazuh_log_monitor,
        min_timeout=15,
        options=checkers,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled')
Example #10
0
def test_events_from_existing_files(filename, tags_to_apply, get_configuration,
                                    configure_environment, restart_syscheckd, wait_for_initial_scan):
    """
        Checks if syscheck generates modified alerts for files that exists when starting the agent
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    # Modify file
    modify_file_content(testdir1, filename, new_content='Sample content')

    # Expect modified event
    check_time_travel(scheduled)
    modified_event = wazuh_log_monitor.start(timeout=timeout, callback=callback_detect_event).result()
    assert 'modified' in modified_event['data']['type'] and \
           os.path.join(testdir1, filename) in modified_event['data']['path']

    # Delete file
    delete_file(testdir1, filename)

    # Expect deleted event
    check_time_travel(scheduled)
    deleted_event = wazuh_log_monitor.start(timeout=timeout, callback=callback_detect_event).result()
    assert 'deleted' in deleted_event['data']['type'] and \
           os.path.join(testdir1, filename) in deleted_event['data']['path']
Example #11
0
def test_ambiguous_check(dirname, checkers, tags_to_apply, get_configuration,
                         configure_environment, restart_syscheckd,
                         wait_for_initial_scan):
    """Checks if syscheck detects every check set in the configuration.

    Checks are read from left to right, overwriting any ambiguous configuration.

    If we set check_all='yes' and then check_inode='no' for the same directory, syscheck must send an event
    containing every possible check without inode.

    This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.

    Parameters
    ----------
    dirname : string
        Name of the monitored directory
    checkers : set
        Checks to be compared to the actual event check list (the one we get from the event)
    tags_to_apply : set
        Run test if matches with a configuration identifier, skip otherwise
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    regular_file_cud(dirname,
                     wazuh_log_monitor,
                     min_timeout=DEFAULT_TIMEOUT,
                     options=checkers,
                     time_travel=scheduled)
def test_scan_day_and_time(tags_to_apply, get_configuration,
                           configure_environment, restart_syscheckd,
                           wait_for_initial_scan):
    """ Check if there is a scan in a certain day and time

    This test must check both scan params.

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    day_of_week = {
        'monday': 0,
        'tuesday': 1,
        'wednesday': 2,
        'thursday': 3,
        'friday': 4,
        'saturday': 5,
        'sunday': 6
    }
    current_day = datetime.now()
    scan_day = day_of_week[get_configuration['metadata']['scan_day']]
    scan_time = reformat_time(get_configuration['metadata']['scan_time'])
    day_diff = scan_day - current_day.weekday()
    scan_today = False

    if day_diff < 0:
        day_diff %= 7
    elif day_diff == 0:
        scan_today = True

    scan_time = replace_date(scan_time, day_diff)

    if scan_today:
        if (scan_time - current_day).days == 0:
            TimeMachine.travel_to_future(scan_time - current_day +
                                         timedelta(minutes=1))
            wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT,
                                    callback=callback_detect_end_scan)
            return
        else:
            day_diff = 7

    if day_diff > 1:
        TimeMachine.travel_to_future(timedelta(days=day_diff - 1))
        current_day = datetime.now()
        with pytest.raises(TimeoutError):
            wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT,
                                    callback=callback_detect_end_scan)

    TimeMachine.travel_to_future(scan_time - current_day -
                                 timedelta(minutes=5))
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT,
                                callback=callback_detect_end_scan)
    TimeMachine.travel_to_future(timedelta(minutes=6))
    wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT,
                            callback=callback_detect_end_scan)
Example #13
0
def test_symbolic_delete_target(tags_to_apply, main_folder, aux_folder,
                                get_configuration, configure_environment,
                                restart_syscheckd, wait_for_initial_scan):
    """ Check if syscheck detects events properly when removing a target, have the symlink updated and
        then recreating the target

    CHECK: Having a symbolic link pointing to a file/folder, remove that file/folder and check that deleted event is
    detected.
    Once symlink_checker runs create the same file. No events should be raised. Wait again for symlink_checker run
    and modify the file. Modification event must be detected this time.

    :param main_folder: Directory that is being pointed at or contains the pointed file
    :param aux_folder: Directory that will be pointed at or will contain the future pointed file

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    whodata = get_configuration['metadata']['fim_mode'] == 'whodata'
    file1 = 'regular1'

    # If symlink is pointing to a directory, we need to add files and expect their 'added' event (only if the file
    # is being created withing the pointed directory. Then, delete the pointed file or directory
    if tags_to_apply == {'monitored_dir'}:
        create_file(REGULAR, main_folder, file1, content='')
        check_time_travel(scheduled)
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)
        delete_f(main_folder)
    else:
        delete_f(main_folder, file1)
    check_time_travel(scheduled)
    delete = wazuh_log_monitor.start(timeout=3,
                                     callback=callback_detect_event).result()
    assert 'deleted' in delete['data']['type'] and file1 in delete['data']['path'], \
        f"'deleted' event not matching for {file1}"

    # If syscheck is monitoring with whodata, wait for audit to reload rules
    wait_for_audit(whodata, wazuh_log_monitor)
    wait_for_symlink_check(wazuh_log_monitor)

    # Restore the target and don't expect any event since symlink hasn't updated the link information
    create_file(REGULAR, main_folder, file1, content='')
    check_time_travel(scheduled)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)

    wait_for_symlink_check(wazuh_log_monitor)
    wait_for_audit(whodata, wazuh_log_monitor)

    # Modify the files and expect events since symcheck has updated now
    modify_file_content(main_folder, file1, 'Sample modification')
    check_time_travel(scheduled)
    modify = wazuh_log_monitor.start(timeout=3,
                                     callback=callback_detect_event).result()
    assert 'modified' in modify['data']['type'] and file1 in modify['data']['path'], \
        f"'modified' event not matching for {file1}"
Example #14
0
def test_invalid_sync_response(get_configuration, configure_environment,
                               restart_syscheckd):
    """Checks if an invalid ignore configuration is detected by catching the warning message displayed on the log.

    This test is intended to be used with valid configurations files. Each execution of this test will configure the
    environment properly and restart the service. No wait for the initial scan in this case as we need to detect the
    warning message.
    """
    check_apply_test({'sync_invalid'}, get_configuration['tags'])

    wazuh_log_monitor.start(timeout=3, callback=callback_configuration_warning)
Example #15
0
def test_added_rules(tags_to_apply, get_configuration, configure_environment,
                     restart_syscheckd):
    """Checks if the specified folders are added to Audit rules list."""
    check_apply_test(tags_to_apply, get_configuration['tags'])

    events = wazuh_log_monitor.start(timeout=20,
                                     callback=callback_audit_added_rule,
                                     accum_results=3).result()

    assert testdir1 in events, f'{testdir1} not detected in scan'
    assert testdir2 in events, f'{testdir2} not detected in scan'
    assert testdir3 in events, f'{testdir3} not detected in scan'
Example #16
0
def test_invalid(tags_to_apply, get_configuration, configure_environment):
    """ Checks if an invalid configuration is detected

    Using invalid configurations with different attributes, expect an error message and syscheck unable to restart.

    * This test is intended to be used with invalid configurations files. Each execution of this test will fail to
     configure the environment properly.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    # Configuration error -> ValueError raised
    with pytest.raises(ValueError):
        control_service('restart')
    wazuh_log_monitor.start(timeout=3, callback=callback_configuration_error)
Example #17
0
def test_move_folders_to_realtime(tags_to_apply, get_configuration, uninstall_install_audit,
                                  configure_environment, restart_syscheckd):
    """Check folders monitored with Whodata change to Real-time if auditd is not installed

    Parameters
    ----------
    tags_to_apply : set
        Configuration tag to apply
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])

    wazuh_log_monitor.start(timeout=20, callback=callback_audit_cannot_start)
Example #18
0
def test_reports_file_and_nodiff(folder, checkers, tags_to_apply,
                                 get_configuration, configure_environment,
                                 restart_syscheckd, wait_for_initial_scan):
    """ Check if report_changes events and diff truncated files are correct

    The report_changes attribute adds a new event property to the 'modified' sent event: 'content_changes'
    It has information about what changed from the previous content. To do so, it duplicates the file in the diff
    directory. We call this duplicated file 'diff_file'.

    :param folder: Directory where the files will be created
    :param checkers: Dict of syscheck checkers (check_all)

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    file_list = ['regular_file']
    is_truncated = folder == testdir_nodiff

    def report_changes_validator(event):
        """ Validate content_changes attribute exists in the event """
        for file in file_list:
            diff_file = os.path.join(WAZUH_PATH, 'queue', 'diff', 'local')
            if sys.platform == 'win32':
                diff_file = os.path.join(diff_file, 'c')
                diff_file = os.path.join(diff_file, folder.strip('C:\\'), file)
            else:
                diff_file = os.path.join(diff_file, folder.strip('/'), file)
            assert os.path.exists(diff_file), f'{diff_file} does not exist'
            assert event['data'].get(
                'content_changes') is not None, f'content_changes is empty'

    def no_diff_validator(event):
        """ Validate content_changes value is truncated if the file is set to no_diff """
        if is_truncated:
            assert '<Diff truncated because nodiff option>' in event['data'].get('content_changes'), \
                f'content_changes is not truncated'
        else:
            assert '<Diff truncated because nodiff option>' not in event['data'].get('content_changes'), \
                f'content_changes is truncated'

    regular_file_cud(
        folder,
        wazuh_log_monitor,
        file_list=file_list,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=DEFAULT_TIMEOUT,
        triggers_event=True,
        validators_after_update=[report_changes_validator, no_diff_validator])
def test_process_priority(get_configuration, configure_environment,
                          restart_syscheckd, wait_for_initial_scan):
    """Check if the ossec-syscheckd service priority is updated correctly using
       <process_priority> tag in ossec.conf.
    """
    check_apply_test({'ossec_conf'}, get_configuration['tags'])

    priority = int(get_configuration['metadata']['process_priority'])
    process_name = 'ossec-syscheckd'
    syscheckd_process = get_process(process_name)

    assert syscheckd_process is not None, f'Process {process_name} not found'
    assert syscheckd_process.nice(
    ) == priority, f'Process {process_name} has not updated its priority.'
Example #20
0
def test_no_diff_subdirectory(folder, filename, content, hidden_content,
                              tags_to_apply, get_configuration,
                              configure_environment, restart_syscheckd,
                              wait_for_initial_scan):
    """ Checks files are ignored in the subdirectory according to configuration

    When using the nodiff option for a file in syscheck configuration, every time we get an event from this file,
    we won't be able to see its content. We'll see 'Diff truncated because nodiff option' instead.

    :param folder: Directory where the file is being created
    :param filename: Name of the file to be created
    :param content: Content to fill the new file
    :param hidden_content: True if content must be truncated,, False otherwise
    :param tags_to_apply: Run test if matches with a configuration identifier, skip otherwise

    * This test is intended to be used with valid nodiff configurations. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    files = {filename: content}

    def report_changes_validator(event):
        """ Validate content_changes attribute exists in the event """
        for file in files:
            diff_file = os.path.join(WAZUH_PATH, 'queue', 'diff', 'local',
                                     folder.strip(PREFIX), file)
            assert os.path.exists(diff_file), f'{diff_file} does not exist'
            assert event['data'].get(
                'content_changes') is not None, f'content_changes is empty'

    def no_diff_validator(event):
        """ Validate content_changes value is truncated if the file is set to no_diff """
        if hidden_content:
            assert '<Diff truncated because nodiff option>' in event['data'].get('content_changes'), \
                f'content_changes is not truncated'
        else:
            assert '<Diff truncated because nodiff option>' not in event['data'].get('content_changes'), \
                f'content_changes is truncated'

    regular_file_cud(
        folder,
        wazuh_log_monitor,
        file_list=files,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=DEFAULT_TIMEOUT,
        triggers_event=True,
        validators_after_update=[report_changes_validator, no_diff_validator])
def test_reconnect_to_audit(tags_to_apply, get_configuration, configure_environment,
                            restart_syscheckd, wait_for_initial_scan):
    """Restart auditd and check Wazuh reconnect to auditd

    Parameters
    ----------
    tags_to_apply : set
        Configuration tag to apply in the test
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])

    subprocess.run(["service", "auditd", "restart"], check=True)

    wazuh_log_monitor.start(timeout=20, callback=callback_audit_connection_close)
    wazuh_log_monitor.start(timeout=20, callback=callback_audit_connection)
Example #22
0
def test_benchmark_regular_files(files, folder, tags_to_apply, get_configuration,
                                 configure_environment, restart_syscheckd,
                                 wait_for_initial_scan):
    """ Checks syscheckd detects a certain volume of file changes (add, modify, delete)

        :param files: List of regular files to be created
        :param folder: Monitored directory where files will be created

        * This test is intended to be used with valid configurations files. Each execution of this test will configure
          the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    min_timeout = 30

    regular_file_cud(folder, wazuh_log_monitor, file_list=files,
                     min_timeout=min_timeout, triggers_event=True)
Example #23
0
def test_readded_rules(tags_to_apply, get_configuration, configure_environment,
                       restart_syscheckd):
    """Checks if the removed rules are added to Audit rules list."""
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Remove added rules
    for dir in (testdir1, testdir2, testdir3):
        os.system("auditctl -W {0} -p wa -k wazuh_fim".format(dir))

        wazuh_log_monitor.start(timeout=20,
                                callback=callback_audit_rules_manipulation)

        events = wazuh_log_monitor.start(
            timeout=10, callback=callback_audit_reloaded_rule).result()

        assert dir in events, f'{dir} not in {events}'
Example #24
0
def test_ambiguous_recursion(dirname, recursion_level, tags_to_apply,
                             get_configuration, configure_environment,
                             restart_syscheckd, wait_for_initial_scan):
    """Checks alerts for each level defined in recursion_level

    Checks if syscheck detects alerts for each level defined in the recursion_level attribute.
    This overwrites the default value, restricting it.

    If we set recursion_level=1 and we have this monitored directory /testdir
    It will only monitor /testdir and /testdir/subdir
    If we had /testdir/subdir/subdir2, /subdir2 wouldn't be monitored

    This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.

    Parameters
    ----------
    dirname : string
        Name of the monitored directory
    recursion_level : int
        Value of the recursion_level attribute
    tags_to_apply : set
        Run test if matches with a configuration identifier, skip otherwise
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    recursion_subdir = 'subdir'
    path = dirname

    # Iterate from ini to fin and verify that events are generated in the nested directories.
    path = _test_recursion_cud(ini=0,
                               fin=recursion_level,
                               path=path,
                               recursion_subdir=recursion_subdir,
                               scheduled=scheduled,
                               min_timeout=DEFAULT_TIMEOUT,
                               triggers_event=True)

    # Iterate from ini to fin and verify that events are NOT generated in nested directories
    # beyond the established recursion level.
    _test_recursion_cud(ini=recursion_level,
                        fin=4,
                        path=path,
                        recursion_subdir=recursion_subdir,
                        scheduled=scheduled,
                        min_timeout=DEFAULT_TIMEOUT,
                        triggers_event=False)
Example #25
0
def test_ambiguous_recursion_tag(dirnames, recursion_level, triggers_event,
                                 tags_to_apply, get_configuration,
                                 configure_environment, restart_syscheckd,
                                 wait_for_initial_scan):
    """Checks alerts for each level defined in recursion_level with tags

    Checks if syscheck detects alerts for each level defined in the recursion_level attribute and
    if it detects the event property 'tags' for each of them.
    This overwrites the default value, restricting it.

    This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.

    Parameters
    ----------
    dirnames : list
        Monitored directories
    recursion_level : int
        Value of the recursion_level attribute
    triggers_event : bool
        determine if the event should be raised or not.
    tags_to_apply : set
        Run test if matches with a configuration identifier, skip otherwise
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    recursion_subdir = 'subdir'

    # Iterate from ini to fin and verify that events generated in the nested directories contain the key 'tags'.
    _test_recursion_cud(ini=0,
                        fin=recursion_level,
                        path=dirnames[0],
                        recursion_subdir=recursion_subdir,
                        scheduled=scheduled,
                        min_timeout=DEFAULT_TIMEOUT,
                        triggers_event=triggers_event,
                        validators_after_cud=[tag_validator])

    # Iterate from ini to fin and verify that events generated in the nested directories DO NOT contain the key 'tags'.
    _test_recursion_cud(ini=0,
                        fin=recursion_level,
                        path=dirnames[1],
                        recursion_subdir=recursion_subdir,
                        scheduled=scheduled,
                        min_timeout=DEFAULT_TIMEOUT,
                        triggers_event=triggers_event,
                        validators_after_cud=[no_tag_validator])
Example #26
0
def test_symbolic_delete_symlink(tags_to_apply, main_folder, aux_folder,
                                 get_configuration, configure_environment,
                                 restart_syscheckd, wait_for_initial_scan):
    """ Check if syscheck stops detecting events when deleting the monitored symlink.

    CHECK: Having a symbolic link pointing to a file/folder, remove that symbolic link file, wait for the symlink
    checker runs and modify the target file. No events should be detected. Restore the symbolic link and modify
    the target file again once symlink checker runs. Events should be detected now.

    :param main_folder: Directory that is being pointed at or contains the pointed file
    :param aux_folder: Directory that will be pointed at or will contain the future pointed file

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    file1 = 'regular1'
    if tags_to_apply == {'monitored_dir'}:
        create_file(REGULAR, main_folder, file1, content='')
        check_time_travel(scheduled)
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)

    # Remove symlink and don't expect events
    symlink = 'symlink' if tags_to_apply == {'monitored_file'} else 'symlink2'
    delete_f(testdir_link, symlink)
    wait_for_symlink_check(wazuh_log_monitor)
    modify_file_content(main_folder, file1, new_content='Sample modification')
    check_time_travel(scheduled)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)

    # Restore symlink and modify the target again. Expect events now
    create_file(SYMLINK,
                testdir_link,
                symlink,
                target=os.path.join(main_folder, file1))
    wait_for_symlink_check(wazuh_log_monitor)
    modify_file_content(main_folder,
                        file1,
                        new_content='Sample modification 2')
    check_time_travel(scheduled)
    modify = wazuh_log_monitor.start(timeout=3,
                                     callback=callback_detect_event).result()
    assert 'modified' in modify['data']['type'] and file1 in modify['data']['path'], \
        f"'modified' event not matching for {file1}"
Example #27
0
def test_symbolic_revert_symlink(tags_to_apply, get_configuration, configure_environment,
                                 restart_syscheckd, wait_for_initial_scan):
    """ Check if syscheck detects new targets properly

    CHECK: Having a symbolic link pointing to a file/folder, change its target to a folder. Check that the old file is not
     being monitored anymore and the new folder is. Revert the target change and ensure the file is being monitored
     and the folder is not.

    * This test is intended to be used with valid configurations files. Each execution of this test will configure
    the environment properly, restart the service and wait for the initial scan.
    """

    def modify_and_assert(file):
        modify_file_content(testdir1, file, new_content='Sample modification')
        check_time_travel(scheduled)
        ev = wazuh_log_monitor.start(timeout=3, callback=callback_detect_event).result()
        assert 'modified' in ev['data']['type'] and os.path.join(testdir1, file) in ev['data']['path'], \
            f"'modified' event not matching for {testdir1} {file}"

    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    whodata = get_configuration['metadata']['fim_mode'] == 'whodata'
    file1 = 'regular1'
    file2 = 'regular2'

    # Don't expect an event since it is not being monitored yet
    modify_file_content(testdir1, file2, new_content='Sample modification')
    check_time_travel(scheduled)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)

    # Change the target to the folder and now expect an event
    modify_symlink(testdir1, os.path.join(testdir_link, 'symlink'))
    wait_for_symlink_check(wazuh_log_monitor)
    wait_for_audit(whodata, wazuh_log_monitor)
    modify_and_assert(file2)

    # Modify symlink target, wait for sym_check to update it 
    modify_symlink(os.path.join(testdir1, file1), os.path.join(testdir_link, 'symlink'))
    wait_for_symlink_check(wazuh_log_monitor)
    modify_file_content(testdir1, file2, new_content='Sample modification2')
    check_time_travel(scheduled)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)
    modify_and_assert(file1)
Example #28
0
def test_readded_rules_on_restart(tags_to_apply, get_configuration,
                                  configure_environment, restart_syscheckd):
    """Checks if the rules are added to Audit when it restarts."""
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Restart Audit
    p = subprocess.Popen(["service", "auditd", "restart"])
    p.wait()

    wazuh_log_monitor.start(timeout=10, callback=callback_audit_connection)

    events = wazuh_log_monitor.start(timeout=30,
                                     callback=callback_audit_loaded_rule,
                                     accum_results=3).result()

    assert testdir1 in events, f'{testdir1} not in {events}'
    assert testdir2 in events, f'{testdir2} not in {events}'
    assert testdir3 in events, f'{testdir3} not in {events}'
def test_remove_and_read_folder(tags_to_apply, folder, get_configuration,
                                 configure_environment, restart_syscheckd,
                                 wait_for_initial_scan):
    """Remove folder which is monitored with auditd and then create it again.

    Parameters
    ----------
    tags_to_apply : set
        Configuration tag to apply in the test
    folder : str
        The folder to remove and readd
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])

    shutil.rmtree(folder, ignore_errors=True)
    wazuh_log_monitor.start(timeout=20, callback=callback_audit_removed_rule)

    os.makedirs(folder, mode=0o777)
    wazuh_log_monitor.start(timeout=30, callback=callback_audit_reloaded_rule)
def test_entries_match_path_count(get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_initial_scan):
    """Checks if FIM entries match the path count

       It creates two regular files, a symlink and a hard link before the scan begins. After events are logged,
       we should have 3 inode entries and a path count of 4.
       * This test is intended to be used with valid configurations files. Each execution of this test will configure
       the environment properly, restart the service and wait for the initial scan.
    """
    check_apply_test({'ossec_conf'}, get_configuration['tags'])

    entries, path_count = wazuh_log_monitor.start(
        timeout=DEFAULT_TIMEOUT,
        callback=callback_entries_path_count).result()
    check_time_travel(True)

    if entries and path_count:
        assert entries == '3' and path_count == '4', 'Wrong number of inodes and path count'
    else:
        raise AssertionError('Wrong number of inodes and path count')