Skip to content

Commit

Permalink
Merge pull request #4270 from wazuh/3693-registry-wildcards
Browse files Browse the repository at this point in the history
Add FIM Registry Wildcards IT support
  • Loading branch information
vikman90 committed Jul 18, 2023
2 parents 67b1c7a + 83ca604 commit 8027793
Show file tree
Hide file tree
Showing 9 changed files with 467 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file.
Wazuh commit: TBD \
Release report: TBD

### Added

- Add IT tests FIM registry monitoring using wildcards. ([#4270](https://github.com/wazuh/wazuh-qa/pull/4270)) \- (Framework + Tests)
- Update schema database version ([#4128](https://github.com/wazuh/wazuh-qa/pull/4128)) \- (Tests)

## [4.5.1] - TBD
Expand Down
2 changes: 1 addition & 1 deletion deps/wazuh_testing/wazuh_testing/modules/fim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2022, Wazuh Inc.
# Copyright (C) 2015-2023, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

Expand Down
66 changes: 62 additions & 4 deletions deps/wazuh_testing/wazuh_testing/modules/fim/event_monitor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2022, Wazuh Inc.
# Copyright (C) 2015-2023, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

Expand All @@ -7,7 +7,7 @@

from sys import platform
from datetime import datetime
from wazuh_testing import LOG_FILE_PATH, logger, T_60
from wazuh_testing import LOG_FILE_PATH, logger, T_60, T_30
from wazuh_testing.tools.monitoring import FileMonitor, generate_monitoring_callback


Expand Down Expand Up @@ -43,15 +43,14 @@
CB_SYNC_INTERVAL_RESET = r".*Previous sync was successful. Sync interval is reset to: '(\d+)s'"
CB_IGNORING_DUE_TO_SREGEX = r".*?Ignoring path '(.*)' due to sregex '(.*)'.*"
CB_IGNORING_DUE_TO_PATTERN = r".*?Ignoring path '(.*)' due to pattern '(.*)'.*"
CB_MAXIMUM_FILE_SIZE = r'.*Maximum file size limit to generate diff information configured to \'(\d+) KB\'.*'
CB_AGENT_CONNECT = r'.* Connected to the server .*'
CB_REALTIME_WHODATA_ENGINE_STARTED = r'.*File integrity monitoring (real-time Whodata) engine started.*'
CB_DISK_QUOTA_LIMIT_CONFIGURED_VALUE = r'.*Maximum disk quota size limit configured to \'(\d+) KB\'.*'
CB_FILE_EXCEEDS_DISK_QUOTA = r'.*The (.*) of the file size \'(.*)\' exceeds the disk_quota.*'
CB_FILE_SIZE_LIMIT_REACHED = r'.*File \'(.*)\' is too big for configured maximum size to perform diff operation\.'
CB_DIFF_FOLDER_DELETED = r'.*Folder \'(.*)\' has been deleted.*'
CB_FIM_PATH_CONVERTED = r".*fim_adjust_path.*Convert '(.*) to '(.*)' to process the FIM events."
CB_STARTING_WINDOWS_AUDIT = r'.*state_checker.*(Starting check of Windows Audit Policies and SACLs)'
CB_FIM_WILDCARD_EXPANDING = r".*Expanding entry '.*' to '(.*)' to monitor FIM events."
CB_SWITCHING_DIRECTORIES_TO_REALTIME = r'.*state_checker.*(Audit policy change detected.\
Switching directories to realtime)'
CB_RECIEVED_EVENT_4719 = r'.*win_whodata.*(Event 4719).*Switching directories to realtime'
Expand Down Expand Up @@ -227,6 +226,18 @@ def callback_detect_file_integrity_event(line):
return None


def callback_key_event(line):
""" Callback that detects if a line contains a registry integrity event for a registry_key
Args:
line (String): string line to be checked by callback in File_Monitor.
"""
event = callback_detect_event(line)
if event is None or event['data']['attributes']['type'] != 'registry_key':
return None

return event


def callback_value_event(line):
event = callback_detect_event(line)

Expand Down Expand Up @@ -489,6 +500,53 @@ def detect_whodata_start(file_monitor, timeout=T_60):
error_message=ERR_MSG_WHODATA_ENGINE_EVENT)


def get_messages(callback, timeout=T_30):
"""Look for as many synchronization events as possible.
This function will look for the synchronization messages until a Timeout is raised or 'max_events' is reached.
Args:
callback (str): Callback to be used to detect the event.
timeout (int): Timeout that will be used to get the dbsync_no_data message.
Returns:
A list with all the events in json format.
"""
wazuh_log_monitor = FileMonitor(LOG_FILE_PATH)
events = []
for _ in range(0, MAX_EVENTS_VALUE):
event = None
try:
event = wazuh_log_monitor.start(timeout=timeout, accum_results=1,
callback=callback,
error_message=f"Did not receive expected {callback} event").result()
except TimeoutError:
break
if event is not None:
events.append(event)
return events


def check_registry_crud_event(callback, path, timeout=T_30, type='added', arch='x32', value_name=None):
"""Get all events matching the callback and validate the type, path and architecture of event
Args:
callback (str): Callback to be used to detect the event.
path (str): path to be checked
timeout (int): Timeout that will be used to try and get the expected messages
type (str): type of event to be checked
arch (str): architecture of the event to be checked
value_name (str): name of the value to be checked
"""
events = get_messages(callback=callback, timeout=timeout)
for event in events:
if event['data']['type'] == type and arch in event['data']['arch'] and event['data']['path'] == path:
if value_name is not None:
if 'value_name' in event and event['data']['value_name'] == value_name:
return event
else:
return event

return None


def detect_windows_sacl_configured(file_monitor, file='.*'):
"""Detects when windows permision checks have been configured for a given file.
Expand Down
36 changes: 34 additions & 2 deletions deps/wazuh_testing/wazuh_testing/modules/fim/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2022, Wazuh Inc.
# Copyright (C) 2015-2023, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

Expand Down Expand Up @@ -213,7 +213,8 @@ def modify_registry(key, subkey, arch):
logger.info(f"Modifying registry key {print_arch}{os.path.join(fim.registry_class_name[key], subkey)}")

modify_key_perms(key, subkey, arch, win32sec.LookupAccountName(None, f"{platform.node()}\\{os.getlogin()}")[0])
modify_registry_owner(key, subkey, arch, win32sec.LookupAccountName(None, f"{platform.node()}\\{os.getlogin()}")[0])
modify_registry_owner(key, subkey, arch,
win32sec.LookupAccountName(None, f"{platform.node()}\\{os.getlogin()}")[0])
modify_registry_key_mtime(key, subkey, arch)


Expand Down Expand Up @@ -298,6 +299,14 @@ def calculate_registry_diff_paths(reg_key, reg_subkey, arch, value_name):


def transform_registry_list(value_list=['test_value'], value_type=fim.REG_SZ, callback=ev.callback_value_event):
"""Transform a list of registry values into a dictionary.
Args:
value list (List): list of string value names
value type (str): type of registry value that is expected.
Callback (object): Callback to pair with the value to be monitored.
Returns:
Dict: dictionary with the values and the corresponding callbacks to monitor them.
"""
if sys.platform == 'win32':
if value_type in [win32con.REG_SZ, win32con.REG_MULTI_SZ]:
value_default_content = ''
Expand All @@ -319,6 +328,29 @@ def transform_registry_list(value_list=['test_value'], value_type=fim.REG_SZ, ca
return aux_dict


def transform_registry_key_list(key_list=['test_key'], callback=ev.callback_key_event):
"""Transform a list of registry keys into a dictionary.
Args:
key_list list (List): list of strings with the key names names
Callback (object): Callback to pair with the key to be monitored.
Returns:
Dict: dictionary with the keys and the corresponding callbacks to monitor them.
"""
if sys.platform == 'win32':
aux_dict = {}
if isinstance(key_list, list):
for elem in key_list:
aux_dict[elem] = ('', callback)

elif isinstance(key_list, dict):
for key, elem in key_list.items():
aux_dict[key] = (elem, callback)
else:
raise ValueError('It can only be a list or dictionary')

return aux_dict


def set_check_options(options):
""" Return set of check options. If options given is none, it will return check_all"""
options_set = fim.REQUIRED_REG_VALUE_ATTRIBUTES[fim.CHECK_ALL]
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/test_fim/test_registry/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2021, Wazuh Inc.
# Copyright (C) 2015-2023, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- sections:
- section: syscheck
elements:
- disabled:
value: 'no'
- frequency:
value: FREQUENCY
- windows_registry:
value: WINDOWS_REGISTRY
attributes:
- arch: both

- section: sca
elements:
- enabled:
value: 'no'
- section: rootcheck
elements:
- disabled:
value: 'yes'
- section: wodle
attributes:
- name: syscollector
elements:
- disabled:
value: 'yes'
- section: active-response
elements:
- disabled:
value: 'yes'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
- name: Test key with question mark wildcard (Scheduled)
description: Test path with single question mark wildcard in scheduled mode
configuration_parameters:
FREQUENCY: 2
WINDOWS_REGISTRY: HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMA?
metadata:
fim_mode: scheduled

- name: Test key with single asterisk wildcard (Scheduled)
description: Test path with single asterisk wildcard in scheduled mode
configuration_parameters:
FREQUENCY: 2
WINDOWS_REGISTRY: HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\*
metadata:
fim_mode: scheduled

- name: Test key with asterisk+question mark (Scheduled)
description: Test path with multiple asterisks and question mark wildcards combined in scheduled mode
configuration_parameters:
FREQUENCY: 2
WINDOWS_REGISTRY: HKEY_LOCAL_MACHINE\*\*\PointerClas?
metadata:
fim_mode: scheduled
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
- name: Test value with question mark wildcard (Scheduled)
description: Test path with single question mark wildcard
configuration_parameters:
FREQUENCY: 2
WINDOWS_REGISTRY: HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\PointerClas?
metadata:
fim_mode: scheduled

- name: Test value with single asterisk wildcard (Scheduled)
description: Test path with single asterisk wildcard in scheduled mode
configuration_parameters:
FREQUENCY: 2
WINDOWS_REGISTRY: HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\*
metadata:
fim_mode: scheduled

- name: Test3 value with asterisk+question mark (Scheduled)
description: Test path with multiple asterisks and question mark wildcards combined in scheduled mode
configuration_parameters:
FREQUENCY: 2
WINDOWS_REGISTRY: HKEY_LOCAL_MACHINE\*\*\PointerClas?
metadata:
fim_mode: scheduled

0 comments on commit 8027793

Please sign in to comment.