예제 #1
0
 def modify_and_assert(file):
     modify_file_content(testdir1, file, new_content='Sample modification')
     check_time_travel(scheduled, monitor=wazuh_log_monitor)
     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}"
예제 #2
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']
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_file_size_default(tags_to_apply, filename, folder, get_configuration,
                           configure_environment, restart_syscheckd,
                           wait_for_fim_start):
    """
    Check that the file_size option with a default value for report_changes is working correctly.

    Create a file smaller than the default limit and check that the compressed file has been created. If the first part
    is successful, increase the size of the file and expect the message for file_size limit reached and no compressed
    file in the queue/diff/local folder.

    Parameters
    ----------
    filename : str
        Name of the file to be created.
    folder : str
        Directory where the files are being created.
    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'
    size_limit = translate_size('50MB')
    diff_file_path = make_diff_file_path(folder=folder, filename=filename)

    # Create file with a smaller size than the configured value
    to_write = generate_string(int(size_limit / 10), '0')
    create_file(REGULAR, folder, filename, content=to_write)

    check_time_travel(scheduled)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected "Sending FIM event: ..." event.'
    )

    if not os.path.exists(diff_file_path):
        pytest.raises(
            FileNotFoundError(
                f"{diff_file_path} not found. It should exist before increasing the size."
            ))

    # Increase the size of the file over the configured value
    to_write = generate_string(size_limit, '0')
    modify_file_content(folder, filename, new_content=to_write * 3)

    check_time_travel(scheduled)

    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_file_size_limit_reached,
        error_message='Did not receive expected '
        '"File ... is too big for configured maximum size to perform diff operation" event.'
    )

    if os.path.exists(diff_file_path):
        pytest.raises(
            FileExistsError(
                f"{diff_file_path} found. It should not exist after incresing the size."
            ))
예제 #5
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}"
예제 #6
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}"
예제 #7
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.

    Parameters
    ----------
    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.
    """
    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, monitor=wazuh_log_monitor)
        wazuh_log_monitor.start(
            timeout=3,
            callback=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)
    modify_file_content(main_folder, file1, new_content='Sample modification')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3,
                                        callback=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
    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, monitor=wazuh_log_monitor)
    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}"
예제 #8
0
 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.
     """
     modify_file_content(f1, file1, text)
     modify_file_content(f2, file1, text)
     check_time_travel(scheduled)
     modify = wazuh_log_monitor.start(
         timeout=3, callback=callback_detect_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):
         wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)
예제 #9
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.
    """
    def modify_and_assert(file):
        modify_file_content(testdir1, file, new_content='Sample modification')
        check_time_travel(scheduled, monitor=wazuh_log_monitor)
        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, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3,
                                        callback=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)
    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, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3,
                                        callback=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_inside_folder(tags_to_apply, previous_target, new_target, get_configuration,
                                              configure_environment, restart_syscheckd, wait_for_initial_scan):
    """
    Check if syscheck stops detecting events from previous target when pointing to a new folder

    CHECK: 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.

    Parameters
    ----------
    previous_target : str
        Previous symlink target (path)
    new_target : str
        New symlink target (path).
    """
    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'}:
        create_file(REGULAR, previous_target, file1, content='')
        check_time_travel(scheduled, monitor=wazuh_log_monitor)
        wazuh_log_monitor.start(timeout=3, callback=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)
    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
    modify_file_content(previous_target, file1, new_content='Sample modification')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        event = wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)
        logger.error(f'Unexpected event {event.result()}')
        raise AttributeError(f'Unexpected event {event.result()}')

    modify_file_content(testdir2, file1, new_content='Sample modification')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    modify = wazuh_log_monitor.start(timeout=3, callback=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}"
예제 #11
0
def test_symbolic_monitor_symlink(tags_to_apply, main_folder,
                                  get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_initial_scan):
    """
    Check what happens with a symlink and its target when syscheck monitors it.

    CHECK: Having a symbolic link pointing to a file/folder, modify and delete the file. Check that alerts are
    being raised.

    Parameters
    ----------
    main_folder : str
        Directory that is being pointed at or contains the pointed file.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    file1 = 'regular1'

    # Add creation if symlink is pointing to a folder
    if tags_to_apply == {'monitored_dir'}:
        create_file(REGULAR, main_folder, file1, content='')
        check_time_travel(scheduled, monitor=wazuh_log_monitor)
        add = wazuh_log_monitor.start(timeout=3,
                                      callback=callback_detect_event).result()
        assert 'added' in add['data']['type'] and file1 in add['data']['path'], \
            f"'added' event not matching"

    # Modify the linked file and expect an event
    modify_file_content(main_folder, file1, 'Sample modification')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    modify = wazuh_log_monitor.start(
        timeout=3,
        callback=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"

    # Delete the linked file and expect an event
    delete_f(main_folder, file1)
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    delete = wazuh_log_monitor.start(
        timeout=3,
        callback=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"
예제 #12
0
def test_symbolic_monitor_symlink(tags_to_apply, main_folder, get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_fim_start):
    """Check what happens with a symlink and its target when syscheck monitors it.

    CHECK: Having a symbolic link pointing to a file/folder, modify and delete the file. Check that alerts are
    being raised.

    Args:
        main_folder (str): Directory that is being pointed at or contains the 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.
        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'

    # Add creation if symlink is pointing to a folder
    if tags_to_apply == {'monitored_dir'}:
        fim.create_file(fim.REGULAR, main_folder, file1, content='')
        fim.check_time_travel(scheduled, monitor=wazuh_log_monitor)
        add = wazuh_log_monitor.start(timeout=3, callback=fim.callback_detect_event).result()
        assert 'added' in add['data']['type'] and file1 in add['data']['path'], \
            "'added' event not matching"

    # Modify the linked file and expect an event
    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'], \
        "'modified' event not matching"

    # Delete the linked file and expect an event
    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'], \
        "'deleted' event not matching"
예제 #13
0
 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()}')
예제 #14
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}"
def test_symbolic_change_target_inside_folder(tags_to_apply, previous_target, new_target, get_configuration,
                                              configure_environment, restart_syscheckd, wait_for_initial_scan):
    """ Check if syscheck stops detecting events from previous target when pointing to a new folder

    CHECK: 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.

    :param previous_target: Previous symlink target (path)
    :param new_target: New symlink target (path)

    * 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'
    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'}:
        create_file(REGULAR, previous_target, file1, content='')
        check_time_travel(scheduled)
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_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)
    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
    modify_file_content(previous_target, file1, new_content='Sample modification')
    check_time_travel(scheduled)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(timeout=3, callback=callback_detect_event)
    modify_file_content(testdir2, file1, new_content='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 os.path.join(testdir2, file1) in modify['data']['path'], \
        f"'modified' event not matching for {testdir2} {file1}"
예제 #16
0
def test_symbolic_monitor_symlink(tags_to_apply, main_folder,
                                  get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_initial_scan):
    """ Check what happens with a symlink and its target when syscheck monitors it.

    CHECK: Having a symbolic link pointing to a file/folder, modify and delete the file. Check that alerts are
    being raised.

    :param main_folder: Directory that is being pointed at or contains the 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'

    # Add creation if symlink is pointing to a folder
    if tags_to_apply == {'monitored_dir'}:
        create_file(REGULAR, main_folder, file1, content='')
        check_time_travel(scheduled)
        add = wazuh_log_monitor.start(timeout=3,
                                      callback=callback_detect_event).result()
        assert 'added' in add['data']['type'] and file1 in add['data']['path'], \
            f"'added' event not matching"

    # Modify the linked file and expect an event
    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"

    # Delete the linked file and expect an event
    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"
예제 #17
0
def test_duplicate_entries_report(get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_initial_scan):
    """Check if syscheckd ignores duplicate entries, report changes.
       For instance:
           - The second entry should prevail over the first one.
            <directories report_changes="yes">/home/user</directories> (IGNORED)
            <directories report_changes="no">/home/user</directories>
    """
    logger.info('Applying the test configuration')
    check_apply_test({'ossec_conf_duplicate_report'},
                     get_configuration['tags'])
    file = 'hello'
    mode2 = get_configuration['metadata']['fim_mode2']
    scheduled = mode2 == 'scheduled'

    # Check for an event
    logger.info(f'Adding file {os.path.join(testdir1, file)}, content: " "')
    create_file(REGULAR, testdir1, file, content=' ')
    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message=f'Did not receive expected event for file '
        f'{os.path.join(testdir1, file)}').result()

    # Check for a second event
    logger.info(f'Modifying {os.path.join(testdir1, file)} content')
    modify_file_content(testdir1, file)
    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message=f'Did not receive expected event for file '
        f'{os.path.join(testdir1, file)}').result()

    assert not os.path.exists(os.path.join(WAZUH_PATH, 'queue', 'diff', 'local', testdir1[1:], file)), \
        'Error: Diff file created'
예제 #18
0
def test_duplicate_entries_sregex(get_configuration, configure_environment,
                                  restart_syscheckd, wait_for_initial_scan):
    """Check if syscheckd ignores duplicate entries, sregex patterns of restrict.
       For instance:
           - The second entry should prevail over the first one.
            <directories restrict="^good.*$">/home/user</directories> (IGNORED)
            <directories restrict="^he.*$">/home/user</directories>
       In this case, only the filenames that match with this regex '^he.*$'
    """
    logger.info('Applying the test configuration')
    check_apply_test({'ossec_conf_duplicate_sregex'},
                     get_configuration['tags'])
    file = 'hello'
    mode2 = get_configuration['metadata']['fim_mode2']
    scheduled = mode2 == 'scheduled'

    # Check for an event
    logger.info(f'Adding file {os.path.join(testdir1, file)}, content: " "')
    create_file(REGULAR, testdir1, file, content=' ')
    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        logger.info('Checking the event...')
        event = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event).result()
        raise AttributeError(f'Unexpected event {event}')

    # Check for a second event
    logger.info(f'Modifying {os.path.join(testdir1, file)} content')
    modify_file_content(testdir1, file)
    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        logger.info('Checking the event...')
        event = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event).result()
        raise AttributeError(f'Unexpected event {event}')
예제 #19
0
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}"
예제 #20
0
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}"
예제 #21
0
def test_duplicate_entries_complex(get_configuration, configure_environment,
                                   restart_syscheckd, wait_for_initial_scan):
    """Check if syscheckd ignores duplicate entries, complex entries.
       For instance:
           - The second entry should prevail over the first one.
            <directories check_all="no" check_owner="yes" check_inode="yes">/home/user</directories> (IGNORED)
            <directories check_all="no" check_size="yes" check_perm="yes">/home/user</directories>
       In this case, it only check if the permissions or the size of the file changes
    """
    def replace_character(old, new, path):
        f = codecs.open(path, encoding='utf-8')
        content = f.read()
        content.replace(old, new)
        f.close()

    logger.info('Applying the test configuration')
    check_apply_test({'ossec_conf_duplicate_complex'},
                     get_configuration['tags'])
    file = 'hello'
    mode2 = get_configuration['metadata']['fim_mode2']

    scheduled = mode2 == 'scheduled'
    mode2 = "real-time" if mode2 == "realtime" else mode2

    logger.info(
        f'Adding file {os.path.join(testdir1, file)}, content: "testing"')
    create_file(REGULAR, testdir1, file, content='testing')
    file_path = os.path.join(testdir1, file)

    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    logger.info('Checking the event...')
    event1 = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message=f'It was expected that a "Sending FIM event:" '
        f'event would be generated for file {os.path.join(testdir1, file)}'
    ).result()

    # Replace character, change the group and ownership and touch the file
    logger.info(
        f'Replacing a character of {os.path.join(testdir1, file)} content')
    replace_character('i', '1', file_path)
    logger.info(f'Modifying {os.path.join(testdir1, file)}\'s group')
    modify_file_group(testdir1, file)
    logger.info(f'Modifying {os.path.join(testdir1, file)}\'s owner')
    modify_file_owner(testdir1, file)
    logger.info(f'Adding new file {file_path}')
    Path(file_path).touch()

    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    event2 = check_event(previous_mode=mode2, previous_event=event1, file=file)
    assert event2 is None, "Multiple events created"

    # Change the permissions and the size of the file
    logger.info(f'Modifying {os.path.join(testdir1, file)}\'s permissions')
    modify_file_permission(testdir1, file)
    logger.info(f'Modifying {os.path.join(testdir1, file)} content')
    modify_file_content(testdir1, file)

    logger.info(f'Time travel: {scheduled}')
    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    logger.info('Checking the event...')
    event3 = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message=f'Did not receive expected "Sending FIM event:" '
        f'event for file {os.path.join(testdir1, file)}').result()
    validate_event(event3, [CHECK_PERM, CHECK_SIZE], mode=mode2)
예제 #22
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)
예제 #23
0
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)
예제 #24
0
def test_hard_link(path_file, file_name, path_link, link_name, 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.

    When a regular file with one or more hard links pointing to it is modified the event raised will have a field named
    'hard_links' that must contain a list with the path to those hard links. Only modification events for the regular
    file are expected, not for the hard links, even if we modify a hard link.

    Parameters
    ----------
    path_file : str
        The path to the regular file to be created.
    file_name : str
        The name of the regular file to be created.
    path_link : str
        The path to the Hard links to be created.
    link_name : str
        The name of the Hard links to be created.
    num_links : int
        Number of hard links to create. All of them will be pointing to the same regular file.
    """
    def detect_and_validate_event(expected_file, mode, expected_hard_links):
        event_checker.events = event_checker.fetch_events(min_timeout=global_parameters.default_timeout)

        # Check if the event's path is the expected one
        if isinstance(expected_file, list):
            for i in range(0, len(expected_file)):
                try:
                    event_checker.file_list = [expected_file[i]]
                    event_checker.check_events("modified", mode=mode)
                    break
                except AssertionError:
                    if i == len(expected_file)-1:
                        raise
        else:
            event_checker.file_list = [expected_file]
            event_checker.check_events("modified", mode=mode)

        # Validate number of events
        assert len(event_checker.events) == 1, f"More than one 'modified' event was detected."
        event = event_checker.events[0]

        # Validate 'Hard_links' field
        if path_file == path_link:
            expected_hard_links = set(expected_hard_links)
            assert (set(event['data']['hard_links']).intersection(expected_hard_links) == set()), f"The event's hard_links "
            f"field was '{event['data']['hard_links']}' when was expected to be '{expected_hard_links}'"

    is_scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    file_list = [file_name]
    hardlinks_list = list()

    event_checker = EventChecker(wazuh_log_monitor, path_file, file_list)

    # Create the regular file
    create_file(REGULAR, path_file, file_name, content='test content')
    check_time_travel(is_scheduled, monitor=wazuh_log_monitor)
    event_checker.fetch_and_check('added', min_timeout=global_parameters.default_timeout)

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

    # Detect the 'added' events for all the created links
    if path_file == path_link:
        check_time_travel(is_scheduled, monitor=wazuh_log_monitor)
        event_checker.file_list = hardlinks_list
        event_checker.fetch_and_check('added', min_timeout=global_parameters.default_timeout)

    # Modify the regular file
    modify_file_content(path_file, file_name, new_content="modified testregularfile")
    check_time_travel(is_scheduled, monitor=wazuh_log_monitor)

    # Only events for the regular file are expected
    event_checker.file_list = file_list
    detect_and_validate_event(expected_file=file_name,
                              mode=get_configuration['metadata']['fim_mode'],
                              expected_hard_links=hardlinks_list)

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

    if path_file == path_link and not is_scheduled:
        detect_and_validate_event(expected_file=hardlinks_list[0],
                                  mode=get_configuration['metadata']['fim_mode'],
                                  expected_hard_links=[file_name] + hardlinks_list[1:])
    else:
        # If the link is not inside the monitored dir Scheduled run should detect the modification of the file
        # even if we are using Real-time or Whodata.
        check_time_travel(True, monitor=wazuh_log_monitor)
        detect_and_validate_event(expected_file=[file_name] + hardlinks_list,
                                  mode="scheduled",
                                  expected_hard_links=hardlinks_list)