コード例 #1
0
ファイル: test_skip.py プロジェクト: spothound/wazuh-qa
def test_skip_nfs(modify_inode_mock, directory, tags_to_apply, configure_nfs, get_configuration, configure_environment,
                  restart_syscheckd, wait_for_fim_start):
    """Check if syscheckd skips nfs directories when setting 'skip_nfs="yes"'.

    This test assumes you have a nfs directory mounted on '/nfs-mount-point'. If you do not have one, use the fixture
    `configure_nfs`.

    Parameters
    ----------
    directory : str
        Directory that will be monitored.
    """

    def custom_callback(filename):
        def callback(line):
            match = callback_detect_event(line)
            if match and filename in match['data']['path']:
                return match

        return callback

    file = str(uuid.uuid1())
    check_apply_test(tags_to_apply, get_configuration['tags'])
    trigger = get_configuration['metadata']['skip'] == 'no'

    try:
        regular_file_cud(directory, wazuh_log_monitor, file_list=[file], time_travel=True, min_timeout=3,
                         triggers_event=trigger, callback=custom_callback(file))

    finally:
        delete_file(directory, file)
コード例 #2
0
def test_regular_file_changes(sleep, tags_to_apply, get_configuration, configure_environment, restart_syscheckd,
                              wait_for_initial_scan):
    """
    Check if syscheckd detects regular file changes (add, modify, delete) with a very specific delay between every
    action.

    Parameters
    ----------
    sleep : float
        Delay in seconds between every action.
    """
    threshold = 1.5 if sys.platform == 'win32' else 1.25
    if sleep < threshold and get_configuration['metadata']['fim_mode'] == 'whodata':
        pytest.xfail('Xfailing due to whodata threshold.')
    check_apply_test(tags_to_apply, get_configuration['tags'])

    file = 'regular'
    create_file(REGULAR, path=testdir1, name=file, content='')
    time.sleep(sleep)
    modify_file(path=testdir1, name=file, new_content='Sample')
    time.sleep(sleep)
    delete_file(path=testdir1, name=file)

    events = wazuh_log_monitor.start(timeout=max(sleep * 3, global_parameters.default_timeout), callback=callback_detect_event, accum_results=3,
                                     error_message='Did not receive expected "Sending FIM event: ..." event').result()

    for ev in events:
        validate_event(ev)
コード例 #3
0
def test_events_from_existing_files(filename, tags_to_apply, get_configuration,
                                    configure_environment, restart_syscheckd,
                                    wait_for_fim_start):
    """Check 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'
    mode = get_configuration['metadata']['fim_mode']

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

    # Expect modified event
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    modified_event = wazuh_log_monitor.start(
        timeout=timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    assert 'modified' in modified_event['data']['type'] and \
           os.path.join(testdir1, filename) in modified_event['data']['path']
    validate_event(modified_event, mode=mode)

    # Delete file
    delete_file(testdir1, filename)

    # Expect deleted event
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    deleted_event = wazuh_log_monitor.start(
        timeout=timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    assert 'deleted' in deleted_event['data']['type'] and \
           os.path.join(testdir1, filename) in deleted_event['data']['path']
    validate_event(deleted_event, mode=mode)
コード例 #4
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']
コード例 #5
0
ファイル: common.py プロジェクト: adampielak/wazuh-qa
def multiple_dirs_test(dir_list=None,
                       file=None,
                       scheduled=None,
                       log_monitor=None,
                       timeout=1):
    """Perform a given action for every directory and validate all the events.

    Parameters
    ----------
    dir_list : list, optional
        List of created/monitored directories. Default `None`
    file : str, optional
        Name of the file to be created. Default `None`
    scheduled : str, optional
        Monitoring mode. Default `None`
    log_monitor : FileMonitor, optional
        File monitor. Default `None`
    timeout : int, optional
        Maximum timeout to raise a TimeoutError. Default `1`
    """
    def perform_and_validate_events(func, kwargs):
        for directory in dir_list:
            args = [REGULAR, directory, file
                    ] if func.__name__ == 'create_file' else [directory, file]
            func(*args, **kwargs)
            time.sleep(
                0.01)  # This sleep is to let whodata fetching all events

        check_time_travel(time_travel=scheduled)
        try:
            events = log_monitor.start(
                timeout=timeout,
                callback=callback_detect_event,
                accum_results=len(dir_list),
                error_message=
                'Did not receive expected "Sending FIM event: ..." '
                'event').result()
            time.sleep(1)

            for ev in events:
                validate_event(ev)
        except TimeoutError as e:
            if len(log_monitor.result()) == 63:
                pytest.xfail(
                    reason=
                    'Xfailed due to issue: https://github.com/wazuh/wazuh/issues/4719'
                )
            else:
                raise e

    try:
        perform_and_validate_events(create_file, {'content': ''})
        perform_and_validate_events(modify_file,
                                    {'new_content': 'New content'})
        perform_and_validate_events(delete_file, {})

    finally:
        for directory in dir_list:
            delete_file(directory, file)
コード例 #6
0
ファイル: test_check_all.py プロジェクト: muharihar/wazuh-qa
def test_check_all_no(path, checkers, get_configuration, configure_environment,
                      restart_syscheckd, wait_for_initial_scan):
    """
    Test the functionality of `check_all` option when set to no.

    When setting `check_all` to no, only 'type' and 'checksum' attributes should appear in every event. This will
    avoid any modification event.

    Parameters
    ----------
    path : str
        Directory where the file is being created and monitored.
    checkers : dict
        Check options to be used.
    """
    check_apply_test({'test_check_all_no'}, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    # Create regular file and dont expect any check
    file = 'regular'
    create_file(REGULAR, path, file)
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    create_event = wazuh_log_monitor.start(
        callback=callback_detect_event,
        timeout=15,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    assert create_event['data']['type'] == 'added'
    assert list(
        create_event['data']['attributes'].keys()) == ['type', 'checksum']

    # Delete regular file and dont expect any check. Since it is not using any check, modification events will not
    # be triggered
    modify_file(path, file, 'Sample modification')
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(callback=callback_detect_event,
                                        timeout=5)
        raise AttributeError(f'Unexpected event {event}')

    delete_file(path, file)
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    delete_event = wazuh_log_monitor.start(
        callback=callback_detect_event,
        timeout=15,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    assert delete_event['data'][
        'type'] == 'deleted', f'Current value is {delete_event["data"]["type"]}'
    assert list(delete_event['data']['attributes'].keys()) == ['type', 'checksum'], \
        f'Current value is {list(delete_event["data"]["attributes"].keys())}'
コード例 #7
0
ファイル: common.py プロジェクト: spothound/wazuh-qa
def multiple_dirs_test(mode=None, dir_list=None, file=None, scheduled=None, whodata=None,
                       log_monitor=None, timeout=1):
    """Perform a given action for every directory and validate all the events.

    Parameters
    ----------
    dir_list : list, optional
        List of created/monitored directories. Default `None`
    file : str, optional
        Name of the file to be created. Default `None`
    scheduled : str, optional
        Monitoring mode. Default `None`
    log_monitor : FileMonitor, optional
        File monitor. Default `None`
    timeout : int, optional
        Maximum timeout to raise a TimeoutError. Default `1`
    """

    if mode == "entries":
        n_results = len(dir_list)
    elif mode == "dirs":
        n_results = 64  # Maximum number of directories monitored in one line

    def perform_and_validate_events(func, kwargs):
        for directory in dir_list:
            args = [REGULAR, directory, file] if func.__name__ == 'create_file' else [directory, file]
            func(*args, **kwargs)
            if whodata:
                time.sleep(0.05)  # This sleep is to let whodata fetching all events

        check_time_travel(time_travel=scheduled)

        events = log_monitor.start(timeout=timeout,
                                   callback=callback_detect_event,
                                   accum_results=n_results,
                                   error_message='Did not receive expected "Sending FIM event: ..." event').result()
        time.sleep(1)

        for ev in events:
            validate_event(ev)

    try:
        perform_and_validate_events(create_file, {'content': ''})
        perform_and_validate_events(modify_file, {'new_content': 'New content'})
        perform_and_validate_events(delete_file, {})

    finally:
        for directory in dir_list:
            delete_file(directory, file)
コード例 #8
0
def configure_syscheck_environment(time_sleep):
    # Create every needed directory
    for n in range(n_directories):
        t_dir = os.path.join(PREFIX, f'{testdir}{n}')
        os.makedirs(t_dir, exist_ok=True, mode=0o777)
        directories_list.append(t_dir)

    wazuh_log_monitor = FileMonitor(LOG_FILE_PATH)
    control_service('restart')
    logger.debug('Waiting 15 seconds for syscheckd to start.')
    time.sleep(15)

    file = 'regular'

    logger.debug(
        f'Waiting {str(time_sleep)} seconds. Execute `generate_windows_yaml.py` now.'
    )
    time.sleep(time_sleep)

    logger.debug('Creating files...')
    for directory in directories_list:
        create_file(REGULAR, directory, file, content='')
        time.sleep(0.01)
    try:
        while True:
            wazuh_log_monitor.start(timeout=5, callback=callback_detect_event)
    except TimeoutError:
        pass

    logger.debug('Modifying files...')
    for directory in directories_list:
        modify_file(directory, file, new_content='Modified')
        time.sleep(0.01)
    try:
        while True:
            wazuh_log_monitor.start(timeout=5, callback=callback_detect_event)
    except TimeoutError:
        pass

    logger.debug('Deleting files...')
    for directory in directories_list:
        delete_file(directory, file)
        time.sleep(0.01)
    try:
        while True:
            wazuh_log_monitor.start(timeout=5, callback=callback_detect_event)
    except TimeoutError:
        pass
コード例 #9
0
def test_file_limit_delete_full(folder, file_name, tags_to_apply,
                                get_configuration, configure_environment,
                                restart_syscheckd):
    """
    This test checks a specific case:
    If in a file (for example test_1) is not inserted in the database and a file ended in 0 (for example test_10) is
    inserted in the DB, after deleting test_1, the delete alert was raised for test_10.

    Parameters
    ----------
    folder: path
        Path to the folder where the test is going to be executed.
    file_name:
        base name of the file (in the example above it will be test_)
    tags_to_apply : set
        Run test if matches with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    database_state = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_file_limit_capacity,
        error_message='Did not receive expected '
        '"DEBUG: ...: Sending DB 100% full alert." event').result()

    if database_state:
        assert database_state == '100', 'Wrong value for full database alert'

    create_file(REGULAR, testdir1, file_name)
    sleep(2)

    delete_file(folder, file_name)

    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event).result()
        assert event is None, 'No events should be detected.'

    delete_file(folder, f'{file_name}{0}')

    event = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected deleted event').result()

    assert event['data']['path'] == os.path.join(folder, f'{file_name}{0}')
コード例 #10
0
def test_follow_symbolic_disabled(path, tags_to_apply, get_configuration, configure_environment, restart_syscheckd,
                                  wait_for_fim_start):
    """Check what happens when follow_symbolic_link option is set to "no".

    Ensure that the monitored symbolic link is considered a regular file and it will not follow its target path. It will
    only generate events if it changes somehow, not its target (file or directory)

    Args:
        path (str): Path of the target file or directory
        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.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    regular_file = 'regular1'
    error_msg = 'A "Sending FIM event: ..." event has been detected. No events should be detected at this time.'

    # If the symlink targets to a directory, create a file in it and ensure no event is raised.
    if tags_to_apply == {'monitored_dir'}:
        fim.create_file(fim.REGULAR, path, regular_file)
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        with pytest.raises(TimeoutError):
            wazuh_log_monitor.start(timeout=5, callback=fim.callback_detect_event)
            logger.error(error_msg)
            raise AttributeError(error_msg)

    # Modify the target file and don't expect any events
    fim.modify_file(path, regular_file, new_content='Modify sample')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=5, callback=fim.callback_detect_event)
        logger.error(error_msg)
        raise AttributeError(error_msg)

    # Delete the target file and don't expect any events
    fim.delete_file(path, regular_file)
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=5, callback=fim.callback_detect_event)
        logger.error(error_msg)
        raise AttributeError(error_msg)
コード例 #11
0
def test_follow_symbolic_disabled(path, tags_to_apply, get_configuration,
                                  configure_environment, restart_syscheckd,
                                  wait_for_initial_scan):
    """Check what happens when follow_symbolic_link option is set to "no".

    Ensure that the monitored symbolic link is considered a regular file and it will not follow its target path. It will
    only generate events if it changes somehow, not its target (file or directory)

    Parameters
    ----------
    path : str
        Path of the target file or directory
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    regular_file = 'regular1'
    error_msg = 'A "Sending FIM event: ..." event has been detected. No events should be detected at this time.'

    # If the symlink targets to a directory, create a file in it and ensure no event is raised.
    if tags_to_apply == {'monitored_dir'}:
        create_file(REGULAR, path, regular_file)
        check_time_travel(scheduled, monitor=wazuh_log_monitor)
        with pytest.raises(TimeoutError):
            wazuh_log_monitor.start(timeout=5, callback=callback_detect_event)
            logger.error(error_msg)
            raise AttributeError(error_msg)

    # Modify the target file and don't expect any events
    modify_file(path, regular_file, new_content='Modify sample')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=5, callback=callback_detect_event)
        logger.error(error_msg)
        raise AttributeError(error_msg)

    # Delete the target file and don't expect any events
    delete_file(path, regular_file)
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=5, callback=callback_detect_event)
        logger.error(error_msg)
        raise AttributeError(error_msg)
コード例 #12
0
def test_regular_file_changes(sleep, tags_to_apply, get_configuration,
                              configure_environment, restart_syscheckd,
                              wait_for_initial_scan):
    """
    Check if syscheckd detects regular file changes (add, modify, delete) with a very specific delay between every
    action.

    Parameters
    ----------
    sleep : float
        Delay in seconds between every action.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    file = 'regular'
    create_file(REGULAR, path=testdir1, name=file, content='')
    time.sleep(sleep)
    modify_file(path=testdir1, name=file, new_content='Sample')
    time.sleep(sleep)
    delete_file(path=testdir1, name=file)

    try:
        events = wazuh_log_monitor.start(
            timeout=max(sleep * 3, global_parameters.default_timeout),
            callback=callback_detect_event,
            accum_results=3,
            error_message='Did not receive expected '
            '"Sending FIM event: ..." event').result()
        for ev in events:
            validate_event(ev)
    except TimeoutError as e:
        if get_configuration['metadata']['fim_mode'] == 'whodata':
            pytest.xfail(
                reason=
                'Xfailing due to issue: https://github.com/wazuh/wazuh/issues/4710'
            )
        else:
            raise e
コード例 #13
0
def test_symbolic_monitor_directory_with_symlink(
        monitored_dir, non_monitored_dir1, non_monitored_dir2, sym_target,
        tags_to_apply, get_configuration, configure_environment,
        restart_syscheckd, wait_for_fim_start):
    """Check what happens with a symlink and its target when syscheck monitors a directory with a symlink
    and not the symlink itself.

    When this happens, the symbolic link is considered a regular file and it will not follow its target path.
    It will only generate events if it changes somehow, not its target (file or directory)


    Args:
        monitored_dir (str): Monitored directory.
        non_monitored_dir1 (str): Non-monitored directory.
        non_monitored_dir2 (str): Non-monitored directory.
        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.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    name1 = f'{sym_target}regular1'
    name2 = f'{sym_target}regular2'
    sl_name = f'{sym_target}symlink'
    a_path = os.path.join(non_monitored_dir1, name1)
    b_path = os.path.join(
        non_monitored_dir1,
        name2) if sym_target == 'file' else non_monitored_dir2
    sl_path = os.path.join(monitored_dir, sl_name)
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    # Create regular files out of the monitored directory and don't expect its event
    fim.create_file(fim.REGULAR, non_monitored_dir1, name1, content='')
    fim.create_file(fim.REGULAR, non_monitored_dir1, name2, content='')
    target = a_path if sym_target == 'file' else non_monitored_dir1
    fim.create_file(fim.SYMLINK, monitored_dir, sl_name, target=target)

    # Create the syslink and expect its event, since it's withing the monitored directory
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=fim.callback_detect_event,
        error_message='Did not receive expected "Sending FIM event: ..." event'
    )

    # Modify the target file and don't expect any event
    fim.modify_file(non_monitored_dir1, name1, new_content='Modify sample')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=5,
                                        callback=fim.callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')

    # Modify the target of the symlink and expect the modify event
    modify_symlink(target=b_path, path=sl_path)
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    result = 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()
    if 'modified' in result['data']['type']:
        logger.info(
            "Received modified event. No more events will be expected.")
    elif 'deleted' in result['data']['type']:
        logger.info(
            "Received deleted event. Now an added event will be expected.")
        result = 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 'added' in result['data'][
            'type'], f"The event {result} should be of type 'added'"
    else:
        assert False, f"Detected event {result} should be of type 'modified' or 'deleted'"

    # Remove and restore the target file. Don't expect any events
    fim.delete_file(b_path, name2)
    fim.create_file(fim.REGULAR, non_monitored_dir1, name2, content='')
    fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=5,
                                        callback=fim.callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')
コード例 #14
0
def test_hard_link(path_file, path_link, num_links, get_configuration,
                   configure_environment, restart_syscheckd,
                   wait_for_initial_scan):
    """Test the check_inode option when used with Hard links by creating a hard link file inside and outside the
    monitored directory.

    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_file: The path to the regular file to be created
    :param path_link: The path to the Hard links to be created
    :param num_links: Number of hard links to create. All of them will be pointing to the same regular file.
    :param checkers: Dict with all the check options to be used
    """
    truncate_file(LOG_FILE_PATH)
    wazuh_log_monitor = FileMonitor(LOG_FILE_PATH)
    is_scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    regular_file_name = "testregularfile"
    file_list = [regular_file_name]
    hardlinks_list = []

    try:
        event_checker = EventChecker(wazuh_log_monitor, path_file, file_list)

        # Create the regular file
        create_file(REGULAR,
                    path_file,
                    regular_file_name,
                    content='test content')
        check_time_travel(is_scheduled)
        event_checker.fetch_and_check('added', min_timeout=DEFAULT_TIMEOUT)

        # Create as many links pointing to the regular file as num_links
        for link in range(0, num_links):
            hardlinks_list.append("HardLink" + str(link))
            create_file(HARDLINK,
                        path_link,
                        "HardLink" + str(link),
                        target=os.path.join(path_file, regular_file_name))

        # Try to detect the creation events for all the created links
        if path_file == path_link:
            check_time_travel(is_scheduled)
            event_checker.file_list = hardlinks_list
            event_checker.fetch_and_check('added', min_timeout=DEFAULT_TIMEOUT)

        # Update file_list with the links if these were created in the monitored folder
        event_checker.file_list = file_list + hardlinks_list if path_file == path_link else file_list

        # Modify the original file and detect the events for the entire file_list
        modify_file_content(path_file,
                            regular_file_name,
                            new_content="modified testregularfile")
        check_time_travel(is_scheduled)
        event_checker.fetch_and_check('modified', min_timeout=DEFAULT_TIMEOUT)

        # Modify one of the hard links
        modify_file_content(path_link,
                            "HardLink0",
                            new_content="modified HardLink0")

        # If the hard link is inside the monitored dir alerts should be triggered for the entire file_list
        # Scheduled run should ALWAYS detect the modification of the file, even if we are using Real-time or Whodata.
        check_time_travel(path_file != path_link or is_scheduled)
        event_checker.fetch_and_check('modified', min_timeout=DEFAULT_TIMEOUT)

    finally:
        # Clean up
        delete_file(path_file, regular_file_name)
        for link in hardlinks_list:
            delete_file(path_link, link)
        check_time_travel(True)
コード例 #15
0
def test_file_limit_capacity_alert(percentage, tags_to_apply, get_configuration, configure_environment,
                                   restart_syscheckd, wait_for_fim_start):
    """
    Checks that the corresponding alerts appear in schedule mode for different capacity thresholds.

    Parameters
    ----------
    tags_to_apply : set
        Run test if matches with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    NUM_FILES = percentage + 1

    if percentage == 0:
        NUM_FILES = 0

    if percentage >= 80:  # Percentages 80 and 90
        for i in range(NUM_FILES):
            create_file(REGULAR, testdir1, f'test{i}')
    else:  # Database back to normal
        for i in range(91):
            delete_file(testdir1, f'test{i}')

    check_time_travel(True, monitor=wazuh_log_monitor)

    if percentage >= 80:  # Percentages 80 and 90
        file_limit_capacity = wazuh_log_monitor.start(timeout=global_parameters.default_timeout,
                                                      callback=callback_file_limit_capacity,
                                                      error_message='Did not receive expected '
                                                                    '"DEBUG: ...: Sending DB ...% full alert." event'
                                                      ).result()

        if file_limit_capacity:
            assert file_limit_capacity == str(percentage), 'Wrong capacity log for DB file_limit'
        else:
            raise AssertionError('Wrong capacity log for DB file_limit')
    else:  # Database back to normal
        event_found = wazuh_log_monitor.start(timeout=global_parameters.default_timeout,
                                              callback=callback_file_limit_back_to_normal,
                                              error_message='Did not receive expected '
                                                            '"DEBUG: ...: Sending DB back to normal alert." event'
                                              ).result()

        assert event_found, 'Event "Sending DB back to normal alert." not found'

    entries, path_count = wazuh_log_monitor.start(timeout=global_parameters.default_timeout,
                                                  callback=callback_entries_path_count,
                                                  error_message='Did not receive expected '
                                                                '"Fim inode entries: ..." event'
                                                  ).result()

    check_time_travel(True, monitor=wazuh_log_monitor)

    if sys.platform != 'win32':
        if entries and path_count:
            assert entries == str(NUM_FILES) and path_count == str(NUM_FILES), 'Wrong number of inodes and path count'
        else:
            raise AssertionError('Wrong number of inodes and path count')
    else:
        if entries:
            assert entries == str(NUM_FILES), 'Wrong number of entries count'
        else:
            raise AssertionError('Wrong number of entries count')
コード例 #16
0
def test_move_file(file, file_content, tags_to_apply, source_folder,
                   target_folder, triggers_delete_event, triggers_add_event,
                   get_configuration, configure_environment, restart_syscheckd,
                   wait_for_initial_scan):
    """ Checks if syscheckd detects 'added' or 'deleted' events when moving a file.

        :param file str Name of the file to be created
        :param file_content str Content of the file to be created
        :param source_folder str Folder to move the file from
        :param target_folder str Destination folder to move the file to
        :param triggers_delete_event boolean Expects a 'deleted' event in the source folder
        :param triggers_add_event boolean Expects a 'added' event in the target folder
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    # Create file inside folder
    create_file(REGULAR, source_folder, file, content=file_content)

    if source_folder in test_directories:
        check_time_travel(scheduled)
        wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT,
                                callback=callback_detect_event)

    # Move file to target directory
    os.rename(os.path.join(source_folder, file),
              os.path.join(target_folder, file))
    check_time_travel(scheduled)

    # Monitor expected events
    events = wazuh_log_monitor.start(
        timeout=DEFAULT_TIMEOUT,
        callback=callback_detect_event,
        accum_results=(triggers_add_event + triggers_delete_event)).result()

    # Expect deleted events
    if isinstance(events, list):
        events_data = [
            (event['data']['type'], event['data']['path'],
             os.path.join(source_folder, file) if event['data']['type']
             == 'deleted' else os.path.join(target_folder, file))
            for event in events
        ]
        assert set([event[0] for event in events_data]) == {'deleted', 'added'}
        for _, path, expected_path in events_data:
            assert path == expected_path
    else:
        if triggers_delete_event:
            assert 'deleted' in events['data']['type'] and os.path.join(
                source_folder, file) in events['data']['path']
        else:
            assert 'added' in events['data']['type'] and os.path.join(
                target_folder, file) in events['data']['path']

    # Remove file
    delete_file(target_folder, file)
    if target_folder in test_directories:
        check_time_travel(scheduled)
        wazuh_log_monitor.start(timeout=DEFAULT_TIMEOUT,
                                callback=callback_detect_event)
コード例 #17
0
def generate_analysisd_yaml(n_events, modify_events):
    def parse_events_into_yaml(requests, yaml_file):
        yaml_result = []
        with open(yaml_file, 'a') as y_f:
            id_ev = 0
            for req, event in requests:
                type_ev = event['data']['type']
                stage_ev = type_ev.title()
                mode = None
                agent_id = callback_analysisd_agent_id(req) or '000'

                del event['data']['mode']
                del event['data']['type']
                if 'tags' in event['data']:
                    del event['data']['tags']
                if type_ev == 'added':
                    mode = 'save2'
                    output_ev = json.dumps(event['data'])

                elif type_ev == 'deleted':
                    mode = 'delete'
                    output_ev = json.dumps(event['data']['path']).replace(
                        '"', '')

                elif type_ev == 'modified':
                    mode = 'save2'
                    for field in [
                            'old_attributes', 'changed_attributes',
                            'content_changes'
                    ]:
                        if field in event['data']:
                            del event['data'][field]
                    output_ev = json.dumps(event['data'])

                yaml_result.append({
                    'name':
                    f"{stage_ev}{id_ev}",
                    'test_case': [{
                        'input': f"{req}",
                        'output':
                        f"agent {agent_id} syscheck {mode} {output_ev}",
                        'stage': f"{stage_ev}"
                    }]
                })
                id_ev += 1
            y_f.write(yaml.safe_dump(yaml_result))

    def remove_logs():
        for root, dirs, files in os.walk(WAZUH_LOGS_PATH):
            for file in files:
                os.remove(os.path.join(root, file))

    file = 'regular'

    # Restart syscheckd with the new configuration
    truncate_file(LOG_FILE_PATH)
    file_monitor = FileMonitor(LOG_FILE_PATH)
    control_service('stop')
    check_daemon_status(running=False)
    remove_logs()

    control_service('start', daemon='wazuh-db', debug_mode=True)
    check_daemon_status(running=True, daemon='wazuh-db')

    control_service('start', daemon='wazuh-analysisd', debug_mode=True)
    check_daemon_status(running=True, daemon='wazuh-analysisd')

    mitm_analysisd = ManInTheMiddle(address=analysis_path,
                                    family='AF_UNIX',
                                    connection_protocol='UDP')
    analysis_queue = mitm_analysisd.queue
    mitm_analysisd.start()

    control_service('start', daemon='wazuh-syscheckd', debug_mode=True)
    check_daemon_status(running=True, daemon='wazuh-syscheckd')

    # Wait for initial scan
    detect_initial_scan(file_monitor)

    analysis_monitor = QueueMonitor(analysis_queue)

    for directory in directories_list:
        create_file(REGULAR, directory, file, content='')
        time.sleep(0.01)
    added = analysis_monitor.start(
        timeout=max(0.01 * n_events, 10),
        callback=callback_analysisd_event,
        accum_results=len(directories_list)).result()
    logger.debug('"added" alerts collected.')

    for directory in directories_list:
        modify_file(directory, file, new_content='Modified')
        time.sleep(0.01)
    modified = analysis_monitor.start(timeout=max(0.01 * n_events, 10),
                                      callback=callback_analysisd_event,
                                      accum_results=modify_events).result()
    logger.debug('"modified" alerts collected.')

    for directory in directories_list:
        delete_file(directory, file)
        time.sleep(0.01)
    deleted = analysis_monitor.start(
        timeout=max(0.01 * len(directories_list), 10),
        callback=callback_analysisd_event,
        accum_results=len(directories_list)).result()
    logger.debug('"deleted" alerts collected.')

    # Truncate file
    with open(yaml_file, 'w') as y_f:
        y_f.write(f'---\n')

    for ev_list in [added, modified, deleted]:
        parse_events_into_yaml(ev_list, yaml_file)
    logger.debug(f'YAML done: "{yaml_file}"')

    return mitm_analysisd
コード例 #18
0
def test_symbolic_monitor_directory_with_symlink(
        monitored_dir, non_monitored_dir1, non_monitored_dir2, sym_target,
        tags_to_apply, get_configuration, configure_environment,
        clean_directories, restart_syscheckd, wait_for_initial_scan):
    """
    Check what happens with a symlink and its target when syscheck monitors a directory with a symlink
    and not the symlink itself.

    When this happens, the symbolic link is considered a regular file and it will not follow its target path.
    It will only generate events if it changes somehow, not its target (file or directory)

    Parameters
    ----------
    monitored_dir : str
        Monitored directory.
    non_monitored_dir1 : str
        Non-monitored directory.
    non_monitored_dir2 : str
        Non-monitored directory.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    name1 = 'regular1'
    name2 = 'regular2'
    sl_name = 'symlink'
    a_path = os.path.join(non_monitored_dir1, name1)
    b_path = os.path.join(
        non_monitored_dir1,
        name2) if sym_target == 'file' else non_monitored_dir2
    sl_path = os.path.join(monitored_dir, sl_name)
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'

    # Create regular files out of the monitored directory and don't expect its event
    create_file(REGULAR, non_monitored_dir1, name1, content='')
    create_file(REGULAR, non_monitored_dir1, name2, content='')
    target = a_path if sym_target == 'file' else non_monitored_dir1
    create_file(SYMLINK, monitored_dir, sl_name, target=target)

    # Create the syslink and expect its event, since it's withing the monitored directory
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected "Sending FIM event: ..." event'
    )

    # Modify the target file and don't expect any event
    modify_file(non_monitored_dir1, name1, new_content='Modify sample')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=5,
                                        callback=callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')

    # Modify the target of the symlink and expect the modify event
    modify_symlink(target=b_path, path=sl_path)
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    result = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    assert 'modified' in result['data'][
        'type'], f"No 'modified' event when modifying symlink"

    # Remove and restore the target file. Don't expect any events
    delete_file(b_path, name2)
    create_file(REGULAR, non_monitored_dir1, name2, content='')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=5,
                                        callback=callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')
コード例 #19
0
ファイル: test_cache.py プロジェクト: spothound/wazuh-qa
def extra_configuration_after_yield():
    # Delete file created in the test.
    delete_file(rules_directory, test_file)
コード例 #20
0
ファイル: test_cache.py プロジェクト: spothound/wazuh-qa
def extra_configuration_before_yield():
    # Delete file before running the test if it exists.
    delete_file(rules_directory, test_file)
コード例 #21
0
def test_move_file(file, file_content, tags_to_apply, source_folder, target_folder,
                   triggers_delete_event, triggers_add_event,
                   get_configuration, configure_environment,
                   restart_syscheckd, wait_for_fim_start):
    """
    Check if syscheckd detects 'added' or 'deleted' events when moving a file.

    Parameters
    ----------
    file : str
        Name of the file to be created.
    file_content : str
        Content of the file to be created.
    source_folder : str
        Folder to move the file from.
    target_folder : str
        Destination folder to move the file to.
    triggers_delete_event : bool
        Expects a 'deleted' event in the `source_folder`.
    triggers_add_event : bool
        Expects a 'added' event in the `target_folder`.
    """

    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    mode = get_configuration['metadata']['fim_mode']

    # Create file inside folder
    create_file(REGULAR, source_folder, file, content=file_content)

    if source_folder in test_directories:
        check_time_travel(scheduled, monitor=wazuh_log_monitor)
        event = wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=callback_detect_event,
                                        error_message='Did not receive expected "Sending FIM event: .." event').result()
        validate_event(event, mode=mode)

    # Move file to target directory
    os.rename(os.path.join(source_folder, file), os.path.join(target_folder, file))
    check_time_travel(scheduled, monitor=wazuh_log_monitor)

    # Monitor expected events
    events = wazuh_log_monitor.start(timeout=global_parameters.default_timeout,
                                     callback=callback_detect_event,
                                     accum_results=(triggers_add_event + triggers_delete_event),
                                     error_message='Did not receive expected '
                                                   '"Sending FIM event: ..." event').result()

    # Expect deleted events
    if isinstance(events, list):
        events_data = [(event['data']['type'],
                        event['data']['path'],
                        os.path.join(source_folder, file) if event['data']['type'] == 'deleted' else os.path.join(
                            target_folder, file))
                       for event in events]
        assert set([event[0] for event in events_data]) == {'deleted', 'added'}
        for _, path, expected_path in events_data:
            assert path == expected_path
    else:
        if triggers_delete_event:
            assert 'deleted' in events['data']['type'] and os.path.join(source_folder, file) in events['data']['path']
        else:
            assert 'added' in events['data']['type'] and os.path.join(target_folder, file) in events['data']['path']

    events = [events] if not isinstance(events, list) else events
    for ev in events:
        validate_event(ev, mode=mode)

    # Remove file
    delete_file(target_folder, file)
    if target_folder in test_directories:
        check_time_travel(scheduled, monitor=wazuh_log_monitor)
        event = wazuh_log_monitor.start(timeout=global_parameters.default_timeout, callback=callback_detect_event,
                                        error_message='Did not receive expected "Sending FIM event: .." event').result()
        validate_event(event, mode=mode)
コード例 #22
0
def extra_configuration_after_yield():
    delete_file(testdir1, 'regular')
    set_local_timezone()