def test_remove_and_read_folder(tags_to_apply, folder, get_configuration,
                                configure_environment, restart_syscheckd,
                                wait_for_fim_start):
    """Remove folder which is monitored with auditd and then create it again.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        folder (str): The folder to remove and read.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If an expected event couldn't be captured.
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])

    shutil.rmtree(folder, ignore_errors=True)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_audit_removed_rule,
        error_message=f'Did not receive expected "removed" event '
        f'removing the folder {folder}')

    os.makedirs(folder, mode=0o777)
    fim.wait_for_audit(True, wazuh_log_monitor)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_audit_added_rule,
        error_message='Did not receive expected "added" event')
Beispiel #2
0
def test_symbolic_change_target_inside_folder(tags_to_apply, previous_target, new_target, get_configuration,
                                              configure_environment, restart_syscheckd, wait_for_fim_start):
    """Check if syscheck stops detecting events from previous target when pointing to a new folder

    Having a symbolic link pointing to a file/folder, change its target to another file/folder inside a monitored
    folder. After symlink_checker runs check that no events for the previous target file are detected while events for
    the new target are still being raised.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        previous_target (str): Previous symlink target.
        new_target (str): New symlink target (path).
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If a expected event wasn't triggered.
        AttributeError: If a unexpected event was captured.
        ValueError: If the event's type and path are not the expected.
    """

    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'
    symlink = 'symlink' if tags_to_apply == {'monitored_file'} else 'symlink2'

    # Check create event if it's pointing to a directory
    if tags_to_apply == {'monitored_dir'}:
        fim.create_file(fim.REGULAR, previous_target, file1, content='')
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                error_message='Did not receive expected "Sending FIM event: ..." event')

    # Change the target to another file and wait the symcheck to update the link information
    modify_symlink(new_target, os.path.join(testdir_link, symlink))
    wait_for_symlink_check(wazuh_log_monitor)
    fim.wait_for_audit(whodata, wazuh_log_monitor)

    # Modify the content of the previous target and don't expect events. Modify the new target and expect an event
    fim.modify_file_content(previous_target, file1, new_content='Sample modification')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')

    fim.modify_file_content(testdir2, file1, new_content='Sample modification')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    modify = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                     error_message='Did not receive expected '
                                                   '"Sending FIM event: ..." event').result()
    assert 'modified' in modify['data']['type'] and os.path.join(testdir2, file1) in modify['data']['path'], \
        f"'modified' event not matching for {testdir2} {file1}"
def test_audit_rules_removed_after_change_link(replaced_target, new_target,
                                               file_name, tags_to_apply,
                                               get_configuration,
                                               configure_environment,
                                               restart_syscheckd,
                                               wait_for_fim_start):
    """Test that checks if the audit rules are removed when the symlink target's is changed.

    Args:
        replaced_target (str): Directory where the link is pointing.
        new_target (str): Directory where the link will be pointed after it's updated.
        file_name (str): Name of the file that will be created inside the folders.
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If an expected event couldn't be captured.
        ValueError: If the event type isn't added or if the audit rule for ``replaced_target`` isn't removed.

    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    fim.create_file(fim.REGULAR, replaced_target, file_name)
    ev = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_detect_event,
        error_message='Did not receive expected "Sending FIM event: ..." event'
    ).result()

    assert ev['data']['type'] == 'added' and ev['data'][
        'path'] == os.path.join(replaced_target, file_name)

    # Change the target of the symlink and expect events while there's no syscheck scan

    modify_symlink(new_target, symlink_path)
    wait_for_symlink_check(wazuh_log_monitor)
    fim.wait_for_audit(True, wazuh_log_monitor)

    rules_paths = str(subprocess.check_output(['auditctl', '-l']))
    fim.create_file(fim.REGULAR, new_target, file_name)
    ev = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_detect_event,
        error_message='Did not receive expected "Sending FIM event: ..." event'
    ).result()

    assert ev['data']['type'] == 'added' and ev['data'][
        'path'] == os.path.join(new_target, file_name)

    assert replaced_target not in rules_paths, f'The audit rule has been reloaded for {replaced_target}'
Beispiel #4
0
def test_audit_no_dir(tags_to_apply, get_configuration, configure_environment,
                      restart_syscheckd):
    """Monitor non-existent directory in whodata. Check that it is added to the rules after creating it.

    The audit thread runs always a directory that is configured to be monitored in
    who-data mode. Doesn't matter if it exists at start-up or not. Once that thread
    is up, the audit rules are reloaded every 30 seconds (not configurable), so
    when the directory is created, it starts to be monitored.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If an expected event couldn't be captured.
        ValueError: If the path of the event is wrong.
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Assert message is generated: Unable to add audit rule for ....
    result = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_audit_unable_dir,
        error_message=
        'Did not receive message "Unable to add audit rule for ..."').result()
    assert result == testdir, f'{testdir} not in "Unable to add audit rule for {result}" message'

    # Create the directory and verify that it is added to the audit rules. It is checked every 30 seconds.
    os.makedirs(testdir)
    fim.wait_for_audit(True, wazuh_log_monitor)
    result = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_audit_added_rule,
        error_message='Folders were not added to Audit rules list').result()
    assert result == testdir, f'{testdir} not in "Added audit rule for monitoring directory: {result}" message'
def test_symbolic_revert_symlink(tags_to_apply, get_configuration,
                                 configure_environment, restart_syscheckd,
                                 wait_for_fim_start):
    """Check if syscheck detects new targets properly

    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.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If a expected event wasn't triggered.
        AttributeError: If a unexpected event was captured.
        ValueError: If the event's type and path are not the expected.
    """
    def modify_and_assert(file):
        fim.modify_file_content(testdir1,
                                file,
                                new_content='Sample modification')
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        ev = wazuh_log_monitor.start(
            timeout=3, callback=fim.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
    fim.modify_file_content(testdir1, file2, new_content='Sample modification')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3,
                                        callback=fim.callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')

    # 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)
    fim.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)
    # Wait for audit to reload the rules
    fim.wait_for_audit(whodata, wazuh_log_monitor)

    fim.modify_file_content(testdir1,
                            file2,
                            new_content='Sample modification2')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3,
                                        callback=fim.callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')
    modify_and_assert(file1)
def test_symbolic_change_target(tags_to_apply, main_folder, aux_folder, get_configuration, configure_environment,
                                restart_syscheckd, wait_for_fim_start):
    """Check if syscheck updates the symlink target properly

    Having a symbolic link pointing to a file/folder, change the target of the link to another file/folder.
    Ensure that the old file is being monitored and the new one is not before symlink_checker runs.
    Wait until symlink_checker runs and ensure that the new file is being monitored and the old one is not.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        main_folder (str): Directory that is being pointed at or contains the pointed file.
        aux_folder (str): Directory that will be pointed at or will contain the future pointed file.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If a expected event wasn't triggered.
        AttributeError: If a unexpected event was captured.
    """

    def modify_and_check_events(f1, f2, text):
        """
        Modify the content of 2 given files. We assume the first one is being monitored and the other one is not.
        We expect a 'modified' event for the first one and a timeout for the second one.
        """
        fim.modify_file_content(f1, file1, text)
        fim.modify_file_content(f2, file1, text)
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        modify = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                         error_message='Did not receive expected "Sending FIM event: ..." event'
                                         ).result()
        assert 'modified' in modify['data']['type'] and f1 in modify['data']['path'], \
            f"'modified' event not matching for {file1}"
        with pytest.raises(TimeoutError):
            event = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event)
            logger.error(f'Unexpected event {event.result()}')
            raise AttributeError(f'Unexpected event {event.result()}')

    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
    if main_folder == testdir_target:
        fim.create_file(fim.REGULAR, main_folder, file1, content='')
        fim.create_file(fim.REGULAR, aux_folder, file1, content='')
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        add = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                      error_message='Did not receive expected "Sending FIM event: ..." event'
                                      ).result()
        assert 'added' in add['data']['type'] and file1 in add['data']['path'], \
            f"'added' event not matching for {file1}"
        with pytest.raises(TimeoutError):
            event = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event)
            logger.error(f'Unexpected event {event.result()}')
            raise AttributeError(f'Unexpected event {event.result()}')
    else:
        fim.create_file(fim.REGULAR, aux_folder, file1, content='')
        with pytest.raises(TimeoutError):
            event = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event)
            logger.error(f'Unexpected event {event.result()}')
            raise AttributeError(f'Unexpected event {event.result()}')

    # Change the target of the symlink and expect events while there's no syscheck scan
    # Don't expect events from the new target
    if tags_to_apply == {'monitored_dir'}:
        modify_symlink(aux_folder, os.path.join(testdir_link, 'symlink2'))
    else:
        modify_symlink(aux_folder, os.path.join(testdir_link, 'symlink'), file=file1)
    modify_and_check_events(main_folder, aux_folder, 'Sample number one')

    wait_for_symlink_check(wazuh_log_monitor)
    fim.wait_for_audit(whodata, wazuh_log_monitor)

    # Expect events the other way around now
    modify_and_check_events(aux_folder, main_folder, 'Sample number two')
def test_symbolic_delete_target(tags_to_apply, main_folder, aux_folder, get_configuration, configure_environment,
                                restart_syscheckd, wait_for_fim_start):
    """Check if syscheck detects events properly when removing a target, have the symlink updated and
    then recreating the target

    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.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        main_folder (str): Directory that is being pointed at or contains the pointed file.
        aux_folder (str): Directory that will be pointed at or will contain the future pointed file.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If a expected event wasn't triggered.
        AttributeError: If a unexpected event was captured.
        ValueError: If the event's type and path are not the expected.
    """
    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'
    RELOAD_RULES_INTERVAL = 30

    # 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'}:
        fim.create_file(fim.REGULAR, main_folder, file1, content='')
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                error_message='Did not receive expected "Sending FIM event: ..." event')
        delete_f(main_folder)
    else:
        delete_f(main_folder, file1)

    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    delete = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                     error_message='Did not receive expected "Sending FIM event: ..." event').result()
    assert 'deleted' in delete['data']['type'] and file1 in delete['data']['path'], \
        f"'deleted' event not matching for {file1}"

    if tags_to_apply == {'monitored_dir'} and whodata:
        wazuh_log_monitor.start(timeout=3, callback=fim.callback_audit_removed_rule,
                                error_message='Did not receive expected "Monitored directory \'{main_folder}\' was'
                                              'removed: Audit rule removed')
        os.makedirs(main_folder, exist_ok=True, mode=0o777)
        wazuh_log_monitor.start(timeout=RELOAD_RULES_INTERVAL, callback=fim.callback_audit_reloading_rules,
                                error_message='Did not receive expected "Reloading Audit rules" event')
        wazuh_log_monitor.start(timeout=RELOAD_RULES_INTERVAL, callback=fim.callback_audit_added_rule,
                                error_message='Did not receive expected "Added audit rule... '
                                '\'{main_folder}\'" event')
    else:
        # If syscheck is monitoring with whodata, wait for audit to reload rules
        fim.wait_for_audit(whodata, wazuh_log_monitor)
        wait_for_symlink_check(wazuh_log_monitor)

    # Restore the target
    fim.create_file(fim.REGULAR, main_folder, file1, content='')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)

    if tags_to_apply == {'monitored_dir'} and whodata:
        wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                error_message='Did not receive expected "Sending FIM event: ..." event')
    else:
        # We don't expect any event since symlink hasn't updated the link information
        with pytest.raises(TimeoutError):
            event = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event)
            logger.error('A "Sending FIM event: ..." event has been detected. No event should be detected as symlink '
                         'has not updated the link information yet.')
            logger.error(f'Unexpected event {event.result()}')
            raise AttributeError(f'Unexpected event {event.result()}')

    wait_for_symlink_check(wazuh_log_monitor)
    fim.wait_for_audit(whodata, wazuh_log_monitor)

    # Modify the files and expect events since symcheck has updated now
    fim.modify_file_content(main_folder, file1, 'Sample modification')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    modify = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event,
                                     error_message='Did not receive expected "Sending FIM event: ..." event').result()
    assert 'modified' in modify['data']['type'] and file1 in modify['data']['path'], \
        f"'modified' event not matching for {file1}"
def test_symbolic_delete_symlink(tags_to_apply, main_folder, aux_folder,
                                 get_configuration, configure_environment,
                                 restart_syscheckd, wait_for_fim_start):
    """Check if syscheck stops detecting events when deleting the monitored symlink.

    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.

    Args:
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        main_folder (str): Directory that is being pointed at or contains the pointed file.
        aux_folder (str): Directory that will be pointed at or will contain the future pointed file.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.

    Raises:
        TimeoutError: If a expected event wasn't triggered.
        AttributeError: If a unexpected event was captured.
        ValueError: If the event's type and path are not the expected.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    file1 = 'regular1'
    if tags_to_apply == {'monitored_dir'}:
        fim.create_file(fim.REGULAR, main_folder, file1, content='')
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        wazuh_log_monitor.start(
            timeout=3,
            callback=fim.callback_detect_event,
            error_message=
            'Did not receive expected "Sending FIM event: ..." 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)
    fim.modify_file_content(main_folder,
                            file1,
                            new_content='Sample modification')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3,
                                        callback=fim.callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')

    # Restore symlink and modify the target again. Expect events now
    fim.create_file(fim.SYMLINK,
                    testdir_link,
                    symlink,
                    target=os.path.join(main_folder, file1))
    wait_for_symlink_check(wazuh_log_monitor)
    # Wait unitl the audit rule of the link's target is loaded again
    fim.wait_for_audit(get_configuration['metadata']['fim_mode'] == "whodata",
                       wazuh_log_monitor)

    fim.modify_file_content(main_folder,
                            file1,
                            new_content='Sample modification 2')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    modify = wazuh_log_monitor.start(
        timeout=3, callback=fim.callback_detect_event).result()
    assert 'modified' in modify['data']['type'] and file1 in modify['data']['path'], \
        f"'modified' event not matching for {file1}"