예제 #1
0
def test_report_changes_after_restart(get_configuration, configure_environment,
                                      restart_syscheckd, wait_for_fim_start):
    """
    Check if diff directories are removed after disabling report_changes and Wazuh is restarted.
    """
    check_apply_test({'test_delete_after_restart'}, get_configuration['tags'])
    value_name = 'random_value'

    folder_path_key1, diff_file_key_1 = calculate_registry_diff_paths(
        key, sub_key_1, KEY_WOW64_64KEY, value_name)
    folder_path_key2, diff_file_key_2 = calculate_registry_diff_paths(
        key, sub_key_1, KEY_WOW64_64KEY, value_name)

    # Open key
    key1_h = create_registry(registry_parser[key], sub_key_1, KEY_WOW64_64KEY)
    key2_h = create_registry(registry_parser[key], sub_key_2, KEY_WOW64_64KEY)

    # Modify the registry
    modify_registry_value(key1_h, value_name, REG_SZ, "some_content")
    modify_registry_value(key2_h, value_name, REG_SZ, "some_content")

    # Travel to future
    check_time_travel(True, monitor=wazuh_log_monitor)

    assert os.path.exists(
        diff_file_key_1), f'{diff_file_key_1} does not exists'
    assert os.path.exists(
        diff_file_key_2), f'{diff_file_key_2} does not exists'

    reload_new_conf('no', test_regs[0], test_regs[1])

    assert not os.path.exists(
        folder_path_key1), f'{folder_path_key1} does exists'
    assert not os.path.exists(
        folder_path_key2), f'{folder_path_key2} does exists'
def extra_configuration_before_yield():
    # Create 3000 files before restarting Wazuh to make sure the integrity scan will not finish before testing
    for testdir in test_directories:
        for file, reg in zip(file_list, subkey_list):
            create_file(REGULAR, testdir, file, content='Sample content')
            create_registry(registry_parser[key],
                            os.path.join(key, 'SOFTWARE', reg),
                            KEY_WOW64_64KEY)
예제 #3
0
def test_disk_quota_values(key, subkey, arch, value_name, tags_to_apply, size,
                           get_configuration, configure_environment,
                           restart_syscheckd, wait_for_fim_start):
    """
    Check that no events are sent when the disk_quota exceeded

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    size : int
        Size of the content to write in value
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    value_content = generate_string(size, '0')
    values = {value_name: value_content}

    _, diff_file = calculate_registry_diff_paths(key, subkey, arch, value_name)

    def report_changes_validator_no_diff(event):
        """Validate content_changes attribute exists in the event"""
        assert event['data'].get(
            'content_changes') is None, 'content_changes isn\'t empty'

    def report_changes_validator_diff(event):
        """Validate content_changes attribute exists in the event"""
        assert os.path.exists(diff_file), '{diff_file} does not exist'
        assert event['data'].get(
            'content_changes') is not None, 'content_changes is empty'

    if size > size_limit_configured:
        callback_test = report_changes_validator_no_diff
    else:
        callback_test = report_changes_validator_diff

    create_registry(registry_parser[key], subkey, arch)

    registry_value_cud(
        key,
        subkey,
        wazuh_log_monitor,
        arch=arch,
        value_list=values,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True,
        validators_after_update=[callback_test])

    delete_registry(registry_parser[key], subkey, arch)
    check_time_travel(True, monitor=wazuh_log_monitor)
def extra_configuration_before_yield():
    key_h = create_registry(registry_parser[key], sub_key_1, arch)

    modify_registry_value(key_h, "value1", REG_SZ, "some content")
    modify_registry_value(key_h, "value2", REG_MULTI_SZ,
                          "some content\0second string\0")
    modify_registry_value(key_h, "value3", REG_DWORD, 1234)
def test_new_key(get_configuration, configure_environment, restart_syscheckd,
                 wait_for_fim_start):
    """
    Check that a new monitored key generates events after the next scheduled scan.
    """

    create_registry(registry_parser[key], sub_key_1, arch)

    check_time_travel(True, monitor=wazuh_log_monitor)

    registry_value_cud(
        key,
        sub_key_1,
        wazuh_log_monitor,
        arch=arch,
        time_travel=get_configuration['metadata']['fim_mode'] == 'scheduled',
        min_timeout=global_parameters.default_timeout,
        triggers_event=True)
예제 #6
0
def extra_configuration_before_yield():
    """Generate registry entries to fill database"""
    reg1_handle = create_registry(registry_parser[KEY], sub_key_1, KEY_WOW64_64KEY)
    reg1_handle = RegOpenKeyEx(registry_parser[KEY], sub_key_1, 0, KEY_ALL_ACCESS | KEY_WOW64_64KEY)

    for i in range(0, NUM_REGS):
        modify_registry_value(reg1_handle, f'value_{i}', REG_SZ, 'added')

    RegCloseKey(reg1_handle)
def test_events_while_integrity_scan(tags_to_apply, get_configuration,
                                     configure_environment, restart_syscheckd):
    """Check that events are being generated while a synchronization is being performed simultaneously.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    folder = testdir1 if get_configuration['metadata'][
        'fim_mode'] == 'realtime' else testdir2
    key_h = create_registry(registry_parser[key], subkey, KEY_WOW64_64KEY)

    # Wait for whodata to start and the synchronization check. Since they are different threads, we cannot expect
    # them to come in order every time
    if get_configuration['metadata']['fim_mode'] == 'whodata':
        value_1 = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout * 2,
            callback=callback_integrity_or_whodata,
            error_message='Did not receive expected "File integrity monitoring '
            'real-time Whodata engine started" or "Initializing '
            'FIM Integrity Synchronization check"').result()

        value_2 = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout * 2,
            callback=callback_integrity_or_whodata,
            error_message='Did not receive expected "File integrity monitoring '
            'real-time Whodata engine started" or "Initializing FIM '
            'Integrity Synchronization check"').result()
        assert value_1 != value_2, "callback_integrity_or_whodata detected the same message twice"

    else:
        # Check the integrity scan has begun
        wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout * 3,
            callback=callback_integrity_synchronization_check,
            error_message='Did not receive expected '
            '"Initializing FIM Integrity Synchronization check" event')

    # Create a file and a registry value. Assert syscheckd detects it while doing the integrity scan
    file_name = 'file'
    create_file(REGULAR, folder, file_name, content='')
    modify_registry_value(key_h, "test_value", REG_SZ, 'added')

    sending_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()
    assert sending_event['data']['path'] == os.path.join(folder, file_name)

    TimeMachine.travel_to_future(timedelta(hours=13))
    sending_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()
    assert sending_event['data']['path'] == os.path.join(key, subkey)
    assert sending_event['data']['arch'] == '[x64]'
예제 #8
0
def test_file_size_default(key, subkey, arch, value_name, tags_to_apply,
                           get_configuration, configure_environment,
                           restart_syscheckd_each_time):
    """
    Check that no events are sent when the disk_quota exceeded

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    size : int
        Size of the content to write in value
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    mode = get_configuration['metadata']['fim_mode']

    file_size_values = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_diff_size_limit_value,
        accum_results=3,
        error_message='Did not receive expected '
        '"Maximum file size limit to generate diff information '
        'configured to \'... KB\'..." event').result()
    for value in file_size_values:
        if value:
            assert value == str(DEFAULT_SIZE), 'Wrong value for file_size'
        else:
            raise AssertionError('Wrong value for file_size')

    key_h = create_registry(registry_parser[key], subkey, arch)

    modify_registry_value(key_h, "some_value", REG_SZ, "some content")
    check_time_travel(True, monitor=wazuh_log_monitor)
    events = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        accum_results=2,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    for ev in events:
        validate_registry_value_event(ev, mode=mode)
예제 #9
0
def test_wait_until_baseline(key, subkey, arch, value_type, content,
                             get_configuration, configure_environment,
                             restart_syscheckd_each_time):
    """
    Check if events are appearing after the baseline
    The message 'File integrity monitoring scan ended' informs about the end of the first scan,
    which generates the baseline
    """

    key_handle = create_registry(registry_parser[key], subkey, arch)

    modify_registry_value(key_handle, "value_name", value_type, content)

    wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event_before_end_scan,
        error_message='Did not receive expected event before end the scan')
예제 #10
0
    def perform_and_validate_events(func, content='added', is_delete=False):
        for reg in subkeys:
            key_handle = create_registry(registry_parser[root_key], reg,
                                         KEY_WOW64_32KEY)
            if not is_delete:
                func(key_handle, 'test_value', REG_SZ, content)
            else:
                func(key_handle, 'test_value')
            RegCloseKey(key_handle)

        check_time_travel(True, monitor=log_monitor)

        events = log_monitor.start(
            timeout=timeout,
            callback=callback_value_event,
            accum_results=num_entries,
            error_message=
            'Did not receive expected "Sending FIM event: ..." event').result(
            )

        for ev in events:
            validate_registry_value_event(ev)
예제 #11
0
def test_registry_sync_after_restart(key_name, value_name, tags_to_apply,
                                     get_configuration, configure_environment,
                                     restart_syscheckd, wait_for_fim_start):
    """
    Test to check that FIM synchronizes the registry DB when a modification is performed while the agent is down.

    Params:
        key_name (str): Name of the subkey that will be created in the test.
        value_name (str): Name of the value that will be created in the test. If
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.
    Raises:
        TimeoutError: If an expected event couldn't be captured.
        ValueError: If a path or value are not in the sync event.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    key_path = os.path.join(subkey, key_name)
    value_path = os.path.join(key, key_path, value_name)

    # wait until the sync is done.
    get_sync_msgs(sync_interval)
    # stops syscheckd
    control_service('stop')

    key_handle = fim.create_registry(fim.registry_parser[key], key_path,
                                     fim.KEY_WOW64_64KEY)
    fim.modify_registry_value(key_handle, value_name, fim.REG_SZ,
                              'This is a test with syscheckd down.')
    control_service('start')

    events = get_sync_msgs(sync_interval + 15)

    assert find_value_in_event_list(
        os.path.join(key, key_path), value_name,
        events) is not None, f"No sync event was found for {value_path}"
예제 #12
0
def configure_syscheck_environment(time_sleep):
    # Create every needed directory
    for n in range(n_windows_registry):
        t_dir = f'{testreg}{n}'
        create_registry(registry_parser[KEY], f'{testreg}{n}', KEY_WOW64_64KEY)
        reg_list.append(t_dir)

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

    reg_key = 'reg_key'
    reg_value = 'value_name'

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

    logger.debug(f'Waiting {SCAN_WAIT} seconds for baseline scan to finish.')
    time.sleep(120)

    logger.debug('Creating registries...')
    for registry in reg_list:
        key_h = create_registry(registry_parser[KEY],
                                os.path.join(registry, reg_key),
                                KEY_WOW64_64KEY)
        modify_registry_value(key_h, reg_value, REG_SZ, 'added')

    TimeMachine.travel_to_future(timedelta(hours=13))

    logger.debug(f'Waiting {SCAN_WAIT} seconds for scan to finish.')
    time.sleep(SCAN_WAIT)

    logger.debug('Modifying registries...')
    for registry in reg_list:
        modify_key_perms(
            registry_parser[KEY], os.path.join(registry, reg_key),
            KEY_WOW64_64KEY,
            LookupAccountName(None, f"{platform.node()}\\{os.getlogin()}")[0])
        modify_registry_owner(
            registry_parser[KEY], os.path.join(registry, reg_key),
            KEY_WOW64_64KEY,
            LookupAccountName(None, f"{platform.node()}\\{os.getlogin()}")[0])
        key_h = RegOpenKeyEx(registry_parser[KEY],
                             os.path.join(registry, reg_key), 0,
                             KEY_ALL_ACCESS | KEY_WOW64_64KEY)
        modify_registry_value(key_h, reg_value, REG_SZ, 'modified')

    TimeMachine.travel_to_future(timedelta(hours=13))

    logger.debug(f'Waiting {SCAN_WAIT} seconds for scan to finish.')
    time.sleep(SCAN_WAIT)

    logger.debug('Deleting registries...')
    for registry in reg_list:
        delete_registry(registry_parser[KEY], os.path.join(registry, reg_key),
                        KEY_WOW64_64KEY)

    TimeMachine.travel_to_future(timedelta(hours=13))

    logger.debug(f'Waiting {SCAN_WAIT} seconds for scan to finish.')
    time.sleep(SCAN_WAIT)
예제 #13
0
def test_restrict_value(key, subkey, arch, value_name, triggers_event,
                        tags_to_apply, get_configuration,
                        configure_environment, restart_syscheckd,
                        wait_for_fim_start):
    """
    Check the only registry values detected are those matching the restrict regex

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        path of the registry.
    arch : str
        Architecture of the registry.
    value_name : str
        Name of the value that will be created
    triggers_event : bool
        True if an event must be generated, False otherwise.
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    # This shouldn't create an alert because the key is already created
    key_h = create_registry(registry_parser[key], subkey, arch)
    # Create values
    modify_registry_value(key_h, value_name, REG_SZ, "added")
    # Go ahead in time to let syscheck perform a new scan
    check_time_travel(get_configuration['metadata']['fim_mode'] == 'scheduled',
                      monitor=wazuh_log_monitor)

    event = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        accum_results=2 if triggers_event else 1).result()

    if triggers_event:
        assert event[0]['data']['type'] == 'modified', 'Key event not modified'
        assert event[0]['data']['path'] == os.path.join(
            key, subkey), 'Key event wrong path'
        assert event[0]['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Key event arch not equal'

        assert event[1]['data']['type'] == 'added', 'Event type not equal'
        assert event[1]['data']['path'] == os.path.join(
            key, subkey), 'Event path not equal'
        assert event[1]['data'][
            'value_name'] == value_name, 'Value name not equal'
        assert event[1]['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Value event arch not equal'
    else:
        assert event['data']['type'] == 'modified', 'Key event not modified'
        assert event['data']['path'] == os.path.join(
            key, subkey), 'Key event wrong path'
        assert event['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Key event arch not equal'

        while True:
            ignored_value = wazuh_log_monitor.start(
                timeout=global_parameters.default_timeout,
                callback=callback_restricted,
                error_message='Did not receive expected '
                '"Sending FIM event: ..." event').result()
            if ignored_value == value_name:
                break

    delete_registry_value(key_h, value_name)
    # Go ahead in time to let syscheck perform a new scan
    check_time_travel(get_configuration['metadata']['fim_mode'] == 'scheduled',
                      monitor=wazuh_log_monitor)
    event = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        accum_results=2 if triggers_event else 1).result()

    if triggers_event:
        assert event[0]['data']['type'] == 'modified', 'Key event not modified'
        assert event[0]['data']['path'] == os.path.join(
            key, subkey), 'Key event wrong path'
        assert event[0]['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Key event arch not equal'

        assert event[1]['data']['type'] == 'deleted', 'Event type not equal'
        assert event[1]['data']['path'] == os.path.join(
            key, subkey), 'Event path not equal'
        assert event[1]['data'][
            'value_name'] == value_name, 'Value name not equal'
        assert event[1]['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Value event arch not equal'
    else:
        # After deleting the value, we don't expect any message of the value because it's not in the DB
        assert event['data']['type'] == 'modified', 'Key event not modified'
        assert event['data']['path'] == os.path.join(
            key, subkey), 'Key event wrong path'
        assert event['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Key event arch not equal'
예제 #14
0
def test_restrict_key(key, subkey, test_subkey, arch, triggers_event,
                      tags_to_apply, get_configuration, configure_environment,
                      restart_syscheckd, wait_for_fim_start):
    """
    Check the only registry keys detected are those matching the restrict regex

    Parameters
    ----------
    key : str
        Root key (HKEY_*)
    subkey : str
        Path of the registry.
    test_subkey : str
        Name of the key that will be used for the test
    arch : str
        Architecture of the registry.
    triggers_event : bool
        True if an event must be generated, False otherwise.
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    test_key = os.path.join(subkey, test_subkey)
    create_registry(registry_parser[key], test_key, arch)

    # Go ahead in time to let syscheck perform a new scan
    check_time_travel(get_configuration['metadata']['fim_mode'] == 'scheduled',
                      monitor=wazuh_log_monitor)

    if triggers_event:
        event = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event,
            accum_results=1).result()
        assert event['data']['type'] == 'added', 'Event type not equal'
        assert event['data']['path'] == os.path.join(
            key, test_key), 'Event path not equal'
        assert event['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Arch not equal'

    else:
        while True:
            ignored_key = wazuh_log_monitor.start(
                timeout=global_parameters.default_timeout,
                callback=callback_restricted,
                error_message='Did not receive expected '
                '"Sending FIM event: ..." event').result()
            if ignored_key == os.path.join(key, subkey):
                break

    delete_registry(registry_parser[key], test_key, arch)
    # Go ahead in time to let syscheck perform a new scan
    check_time_travel(get_configuration['metadata']['fim_mode'] == 'scheduled',
                      monitor=wazuh_log_monitor)

    if triggers_event:
        event = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event,
            accum_results=1).result()

        assert event['data']['type'] == 'deleted', 'key event not equal'
        assert event['data']['path'] == os.path.join(
            key, test_key), 'Key event wrong path'
        assert event['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Key arch not equal'
예제 #15
0
def test_windows_registry(arch_list, tag, tags_to_apply, get_configuration,
                          configure_environment, restart_syscheckd,
                          wait_for_initial_scan):
    """Check the correct monitoring of Windows Registries.

    This test creates a new registry in windows, adds a value, modifies
    it and then deletes the registry. It verifies that syscheck correctly monitors
    certain events while applying different settings.

    Parameters
    ----------
    arch_list : list
        Selected architectures.
    tag : str
        Name of the tag to look for in the event.
    tags_to_apply : set
         Run test if matches with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Check that configuration is applying to the correct test
    if ((tag
         and 'tags' not in get_configuration['metadata']['attribute'].keys())
            or
        (len(arch_list) > 1
         and 'arch' not in get_configuration['metadata']['attribute'].keys())):
        pytest.skip("Does not apply to this config file")

    # Check that windows_registry does not trigger alerts for new keys
    create_registry(winreg.HKEY_LOCAL_MACHINE, sub_key,
                    winreg.KEY_WOW64_32KEY | winreg.KEY_WRITE)
    check_time_travel(time_travel=True,
                      interval=timedelta(seconds=frequency),
                      monitor=wazuh_log_monitor)
    with pytest.raises(TimeoutError):
        wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event,
            error_message=
            'Did not receive expected "Sending FIM event: ..." event',
            accum_results=len(arch_list))

    # Check that windows_registry trigger alerts when adding an entry
    modify_registry(winreg.HKEY_LOCAL_MACHINE, sub_key, 'test_add')
    check_time_travel(time_travel=True,
                      interval=timedelta(seconds=frequency),
                      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',
        accum_results=len(arch_list)).result()
    if not isinstance(event, list):
        event = [event]
    for i, arch in enumerate(arch_list):
        assert event[i]['data']['type'] == 'added', f'Event type not equal'

    # Check that windows_registry trigger alerts when modifying existing entries
    # and check arch and tag values match with the ones in event
    modify_registry(winreg.HKEY_LOCAL_MACHINE, sub_key, 'test_modify')
    check_time_travel(time_travel=True,
                      interval=timedelta(seconds=frequency),
                      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',
        accum_results=len(arch_list)).result()
    if not isinstance(event, list):
        event = [event]
    for i, arch in enumerate(arch_list):
        assert event[i]['data']['type'] == 'modified', f'Event type not equal'
        if arch:
            assert arch in event[i]['data'][
                'path'], f'Architecture is not correct'
        if tag:
            assert event[i]['data']['tags'] == tag, f'{tag} not found in event'

    # Check that windows_registry trigger alerts when deleting a key
    delete_registry(winreg.HKEY_LOCAL_MACHINE, sub_key, winreg.KEY_WOW64_32KEY)
    check_time_travel(time_travel=True,
                      interval=timedelta(seconds=frequency),
                      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',
        accum_results=len(arch_list)).result()
    if not isinstance(event, list):
        event = [event]
    for i, arch in enumerate(arch_list):
        assert event[i]['data'][
            'type'] == 'deleted', f'{event[i]["data"]["type"]} type not equal to deleted'
예제 #16
0
def test_ignore_registry_key(root_key, registry, arch, subkey, triggers_event,
                             tags_to_apply, get_configuration,
                             configure_environment, restart_syscheckd,
                             wait_for_fim_start):
    """
    Check registry keys are ignored according to configuration.

    Parameters
    ----------
    root_key : str
        Root key (HKEY_*)
    registry : str
        path of the registry where the test will be executed.
    arch : str
        Architecture of the registry.
    subkey : str
        Name of the key that will be created.
    triggers_event : bool
        True if an event must be generated, False otherwise.
    tags_to_apply : set
        Run test if match with a configuration identifier, skip otherwise.
    """
    check_apply_test(tags_to_apply, get_configuration['tags'])
    scheduled = get_configuration['metadata']['fim_mode'] == 'scheduled'
    # Create registry
    create_registry(registry_parser[root_key], os.path.join(registry, subkey),
                    arch)
    # Go ahead in time to let syscheck perform a new scan
    check_time_travel(scheduled, monitor=wazuh_log_monitor)

    if triggers_event:
        event = wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=callback_detect_event,
            error_message='Did not receive expected '
            '"Sending FIM event: ..." event',
            accum_results=2).result()

        assert event[0]['data']['type'] == 'added', 'Wrong event type.'
        assert event[0]['data']['path'] == os.path.join(
            root_key, registry, subkey), 'Wrong key path.'
        assert event[0]['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Wrong key arch.'

        assert event[1]['data'][
            'type'] == 'modified', 'Parent key event type not equal'
        assert event[1]['data']['path'] == os.path.join(
            root_key, registry), 'Wrong parent key path.'
        assert event[1]['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Parent key arch not equal.'
    else:
        # The ignore event is generated before the event of the parent key.
        while True:  # Look for the ignore event of the created key
            ignored_key = wazuh_log_monitor.start(
                timeout=global_parameters.default_timeout,
                callback=callback_ignore).result()
            if ignored_key == "{} {}".format(
                    '[x64]' if arch == KEY_WOW64_64KEY else '[x32]',
                    os.path.join(root_key, registry, subkey)):
                break

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

        assert event['data'][
            'type'] == 'modified', 'Parent key event type not equal'
        assert event['data']['path'] == os.path.join(
            root_key, registry), 'Wrong parent key path.'
        assert event['data'][
            'arch'] == '[x32]' if arch == KEY_WOW64_32KEY else '[x64]', 'Parent key arch not equal.'
예제 #17
0
def configure_environment(get_configuration, request):
    """Configure a custom environment for testing. Restart Wazuh is needed for applying the configuration."""

    # Save current configuration
    backup_config = conf.get_wazuh_conf()

    # Configuration for testing
    test_config = conf.set_section_wazuh_conf(get_configuration.get('sections'))

    # Create test directories
    if hasattr(request.module, 'test_directories'):
        test_directories = getattr(request.module, 'test_directories')
        for test_dir in test_directories:
            os.makedirs(test_dir, exist_ok=True, mode=0o777)

    # Create test registry keys
    if sys.platform == 'win32':
        if hasattr(request.module, 'test_regs'):
            test_regs = getattr(request.module, 'test_regs')

            for reg in test_regs:
                match = re.match(r"(^HKEY_[a-zA-Z_]+)\\+(.+$)", reg)
                create_registry(registry_parser[match.group(1)], match.group(2), KEY_WOW64_32KEY)
                create_registry(registry_parser[match.group(1)], match.group(2), KEY_WOW64_64KEY)

    # Set new configuration
    conf.write_wazuh_conf(test_config)

    # Change Windows Date format to ensure TimeMachine will work properly
    if sys.platform == 'win32':
        subprocess.call('reg add "HKCU\\Control Panel\\International" /f /v sShortDate /t REG_SZ /d "dd/MM/yyyy" >nul',
                        shell=True)

    # Call extra functions before yield
    if hasattr(request.module, 'extra_configuration_before_yield'):
        func = getattr(request.module, 'extra_configuration_before_yield')
        func()

    # Set current configuration
    global_parameters.current_configuration = get_configuration

    yield

    TimeMachine.time_rollback()

    # Remove created folders (parents)
    if sys.platform == 'win32' and not hasattr(request.module, 'no_restart_windows_after_configuration_set'):
        control_service('stop')

    if hasattr(request.module, 'test_directories'):
        for test_dir in test_directories:
            shutil.rmtree(test_dir, ignore_errors=True)

    if sys.platform == 'win32':
        if hasattr(request.module, 'test_regs'):
            for reg in test_regs:
                match = re.match(r"(^HKEY_[a-zA-Z_]+)\\+(.+$)", reg)
                delete_registry(registry_parser[match.group(1)], match.group(2), KEY_WOW64_32KEY)
                delete_registry(registry_parser[match.group(1)], match.group(2), KEY_WOW64_64KEY)

    if sys.platform == 'win32' and not hasattr(request.module, 'no_restart_windows_after_configuration_set'):
        control_service('start')

    # Restore previous configuration
    conf.write_wazuh_conf(backup_config)

    # Call extra functions after yield
    if hasattr(request.module, 'extra_configuration_after_yield'):
        func = getattr(request.module, 'extra_configuration_after_yield')
        func()

    if hasattr(request.module, 'force_restart_after_restoring'):
        if getattr(request.module, 'force_restart_after_restoring'):
            control_service('restart')
예제 #18
0
def test_registry_responses(key_name, value_name, tags_to_apply,
                            get_configuration, configure_environment,
                            restart_syscheckd, wait_for_fim_start):
    """Test to check that the fields in synchronization events are decoded properly by the agent.
    Params:
        key_name (str): Name of the subkey that will be created in the test.
        value_name (str): Name of the value that will be created in the test. If
        tags_to_apply (set): Run test if matches with a configuration identifier, skip otherwise.
        get_configuration (fixture): Gets the current configuration of the test.
        configure_environment (fixture): Configure the environment for the execution of the test.
        restart_syscheckd (fixture): Restarts syscheck.
        wait_for_fim_start (fixture): Waits until the first FIM scan is completed.
    Raises:
        TimeoutError: If an expected event couldn't be captured.
        ValueError: If a path or value are not in the sync event.
    """
    if key_name is None and value_name is None:
        pytest.skip('key_name and value_name are None. Skipping')

    check_apply_test(tags_to_apply, get_configuration['tags'])

    # Wait for subkey sync messages only when it's expected
    if key_name is not None:
        fim.create_registry(fim.registry_parser[key],
                            os.path.join(subkey, key_name),
                            fim.KEY_WOW64_64KEY)
        fim.check_time_travel(True, monitor=wazuh_log_monitor)
        wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=fim.callback_detect_end_scan,
            error_message='Did not receive expected "end_scan" event').result(
            )

        events = get_sync_msgs(sync_interval + 15)
        # Parent key sync event
        assert find_path_in_event_list(
            test_regs[0],
            events) is not None, f"No sync event was found for {test_regs[0]}"

        # Subkey sync event
        subkey_path = os.path.join(test_regs[0], key_name)
        assert find_path_in_event_list(
            subkey_path,
            events) is not None, f'No sync event was found for {subkey_path}'

    if value_name is not None:
        if key_name is not None:
            key_path = os.path.join(subkey, key_name)
        else:
            key_path = subkey

        value_path = os.path.join(key, key_path, value_name)

        key_handle = fim.RegOpenKeyEx(fim.registry_parser[key], key_path, 0,
                                      fim.KEY_ALL_ACCESS | fim.KEY_WOW64_64KEY)

        fim.modify_registry_value(key_handle, value_name, fim.REG_SZ,
                                  'This is a test')
        fim.check_time_travel(True, monitor=wazuh_log_monitor)

        wazuh_log_monitor.start(
            timeout=global_parameters.default_timeout,
            callback=fim.callback_detect_end_scan,
            error_message='Did not receive expected "end_scan" event').result(
            )

        events = get_sync_msgs(sync_interval + 15)

        assert find_value_in_event_list(
            os.path.join(key, key_path), value_name,
            events) is not None, f"No sync event was found for {value_path}"
예제 #19
0
def extra_configuration_before_yield():
    create_registry(registry_parser[key], sub_key_1, arch)
예제 #20
0
def test_delete_registry(key, subkey, arch, value_list, get_configuration,
                         configure_environment, restart_syscheckd,
                         wait_for_fim_start):
    """
    Check if syscheckd detects 'deleted' events from the values contained
    in a registry key that is being deleted.

    Parameters
    ----------
    key : str
        Root key where the sub key will be created (HKEY_LOCAL_MACHINE, etc)
    subkey : str
        Path of the registry subkey
    arch : int
        Arch of the registry subkey
    value_list : list
        Names of the values.
    """

    mode = get_configuration['metadata']['fim_mode']
    scheduled = mode == 'scheduled'

    key_h = create_registry(registry_parser[key], subkey, arch)

    # Create values inside subkey
    modify_registry_value(key_h, value_list[0], REG_SZ, "some content")
    modify_registry_value(key_h, value_list[1], REG_MULTI_SZ,
                          "some content\0second string\0")
    modify_registry_value(key_h, value_list[2], REG_DWORD, 1234)

    check_time_travel(scheduled, monitor=wazuh_log_monitor)
    events = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        accum_results=len(value_list) + 1,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event').result()
    for ev in events:
        validate_registry_value_event(ev, mode=mode)

    # Remove registry
    delete_registry(registry_parser[key], subkey, arch)
    check_time_travel(scheduled, monitor=wazuh_log_monitor)

    # Expect deleted events
    event_list = wazuh_log_monitor.start(
        timeout=global_parameters.default_timeout,
        callback=callback_detect_event,
        error_message='Did not receive expected '
        '"Sending FIM event: ..." event',
        accum_results=len(value_list) + 1).result()
    counter_type = Counter([event['data']['type'] for event in event_list])

    for ev in events:
        validate_registry_value_event(ev, mode=mode)

    assert counter_type['deleted'] == len(
        value_list
    ) + 1, f'Number of "deleted" events should be {len(value_list) + 1}'

    name_list = set([event['data']['value_name'] for event in event_list[1:]])
    for value in value_list:
        assert value in name_list, f'Value {value} not found within the events'
def extra_configuration_before_yield():
    for reg, rl in rl_dict.items():
        path = str(reg)
        for n in range(int(rl)):
            path = os.path.join(path, '' + str(n + 1))
        create_registry(registry_parser[key], path, KEY_WOW64_64KEY)