Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SCA Test support #3566

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9ac489e
feat(#3046): add new sca module to framework
Deblintrake09 Oct 17, 2022
7956d89
feat(#3046): add new test_sca IT suite folder
Deblintrake09 Oct 17, 2022
5881428
feat(#3046): add new fixtures for configuration
Deblintrake09 Oct 17, 2022
af13393
Merge branch 'master' into 3406-sca-pcre2-support
Deblintrake09 Nov 3, 2022
5c52975
feat(#3406): add sca ruleset path
Deblintrake09 Nov 4, 2022
9540bb5
feat(#3406): add sca module callbacks and evm
Deblintrake09 Nov 4, 2022
144d80e
feat(#3406): remove innecesary variables
Deblintrake09 Nov 4, 2022
8e2c4c3
style(#3406): fix style and documentation
Deblintrake09 Nov 4, 2022
1823220
feat(#3406): add fixtures for configuration
Deblintrake09 Nov 4, 2022
50f8e58
feat(#3406): add new module test_scan_results
Deblintrake09 Nov 4, 2022
e31856d
style(#3406): fix spacing and documentation
Deblintrake09 Nov 4, 2022
40cafaa
fix(#3406): fix truncated logs on agent
Deblintrake09 Nov 9, 2022
506a471
docs(#3406): update changelog.md
Deblintrake09 Nov 9, 2022
58aeae8
style(#3046): fixed yaml files spacing and quotes
Deblintrake09 Nov 10, 2022
a7568fe
style(#3406): applied requested changes
Deblintrake09 Nov 16, 2022
e97101f
refactor(#3406): remove unnecesary file
Deblintrake09 Nov 16, 2022
de98b84
docs(#3505): apply requested change
Deblintrake09 Nov 16, 2022
e817ac4
style(#3406): improve test cases ids
Deblintrake09 Nov 18, 2022
79aff5a
docs(#3406): improve error message
Deblintrake09 Nov 18, 2022
a02efb0
refactor(#3406): move variables
Deblintrake09 Nov 18, 2022
bc61a49
refactor(#3406): update fixtures used
Deblintrake09 Nov 18, 2022
7b5a7dd
refactor(#3406): move variables to event_monitor
Deblintrake09 Nov 23, 2022
de6653c
docs(#3406): update docu and test names
Deblintrake09 Nov 23, 2022
d25d892
refactor(#3406): refactor tests
Deblintrake09 Nov 23, 2022
2716b37
style(#3406): fix indentation
Deblintrake09 Nov 23, 2022
6cab08c
style(#3406): fix minor styling
Deblintrake09 Nov 24, 2022
4ac0883
Merge branch 'master' into 3406-sca-pcre2-support
Deblintrake09 Nov 24, 2022
1c52eff
docs(#3505): update test cases names
Deblintrake09 Nov 25, 2022
8995e5b
fix(#3406): Fixed case names
Deblintrake09 Nov 25, 2022
f189306
feat(#3506): add fixture
Deblintrake09 Dec 6, 2022
a4bb632
feat(#3506): add new test module
Deblintrake09 Dec 6, 2022
b0d8426
docs(#3506): updated comments and docu
Deblintrake09 Dec 8, 2022
65a576b
style(#3506): fix SCA checks length
Deblintrake09 Dec 12, 2022
17e085f
merge(#3653): merge PR #3653 from wazuh/3506-sca-support
damarisg Dec 13, 2022
98c8837
merge(#3406): merge 4.5 into dev branch
Deblintrake09 Mar 8, 2023
b91cb9d
docs(#3406): Fix copyright date
Deblintrake09 Mar 8, 2023
d008bba
feat(#3406): remove duplicated fixture
Deblintrake09 Apr 11, 2023
ec21694
refactor(#3406): rename function variables
Deblintrake09 Apr 11, 2023
1e2362c
refactor(#3406): rename vars and delete dups vars
Deblintrake09 Apr 14, 2023
32a84af
merge(3406): '4.5' into 3406-sca-pcre2-support
Deblintrake09 Apr 14, 2023
26578aa
fix(#3406): fix local_internal_options
Deblintrake09 Apr 14, 2023
0e0bb37
docu(#3406): update documentation date
Deblintrake09 Apr 17, 2023
e9332ea
Merge branch '4.5' into 3406-sca-pcre2-support
Deblintrake09 May 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Release report: TBD

### Added

- New 'SCA' test suite and framework. ([#3566](https://github.com/wazuh/wazuh-qa/pull/3566)) \- (Framework + Tests)
- Add 'Force reconnect' feature to agent_simulator tool. ([#3111](https://github.com/wazuh/wazuh-qa/pull/3111)) \- (Tools)

### Changed
Expand Down
2 changes: 1 addition & 1 deletion deps/wazuh_testing/wazuh_testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
WAZUH_PATH = os.path.join("/var", "ossec")
LOG_FILE_PATH = os.path.join(WAZUH_PATH, 'logs', 'ossec.log')


WAZUH_CONF_PATH = os.path.join(WAZUH_PATH, 'etc', 'ossec.conf')
WAZUH_LOGS_PATH = os.path.join(WAZUH_PATH, 'logs')
CLIENT_KEYS_PATH = os.path.join(WAZUH_PATH, 'etc' if platform.system() == 'Linux' else '', 'client.keys')
Expand All @@ -39,6 +38,7 @@
API_JSON_LOG_FILE_PATH = os.path.join(WAZUH_PATH, 'logs', 'api.json')
API_LOG_FOLDER = os.path.join(WAZUH_PATH, 'logs', 'api')
WAZUH_TESTING_PATH = os.path.dirname(os.path.abspath(__file__))
CIS_RULESET_PATH = os.path.join(WAZUH_PATH, 'ruleset', 'sca')

# Daemons
LOGCOLLECTOR_DAEMON = 'wazuh-logcollector'
Expand Down
27 changes: 27 additions & 0 deletions deps/wazuh_testing/wazuh_testing/modules/sca/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (C) 2015-2022, Wazuh Inc.
Deblintrake09 marked this conversation as resolved.
Show resolved Hide resolved
# 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

# Variables
TEMP_FILE_PATH = '/tmp'


# Callback Messages
CB_SCA_ENABLED = r".*sca.*INFO: (Module started.)"
CB_SCA_DISABLED = r".*sca.*INFO: (Module disabled). Exiting."
CB_SCA_SCAN_STARTED = r".*sca.*INFO: (Starting Security Configuration Assessment scan)."
CB_SCA_SCAN_ENDED = r".*sca.*INFO: Security Configuration Assessment scan finished. Duration: (\d+) seconds."
CB_SCA_OSREGEX_ENGINE = r".*sca.*DEBUG: SCA will use '(.*)' engine to check the rules."
CB_POLICY_EVALUATION_FINISHED = r".*sca.*INFO: Evaluation finished for policy '(.*)'."
CB_SCAN_DB_DUMP_FINISHED = r".*sca.*DEBUG: Finished dumping scan results to SCA DB for policy '(.*)'.*"
CB_SCAN_RULE_RESULT = r".*sca.*wm_sca_hash_integrity.*DEBUG: ID: (\d+); Result: '(.*)'"
CB_SCA_SCAN_EVENT = r".*sca_send_alert.*Sending event: (.*)"


# Error Messages
ERR_MSG_REGEX_ENGINE = "Did not receive the expected 'SCA will use '.*' engine to check the rules' event"
ERR_MSG_ID_RESULTS = 'Expected sca_has_integrity Result events not found'
damarisg marked this conversation as resolved.
Show resolved Hide resolved
ERR_MSG_SCA_SUMMARY = 'Expected SCA Scan Summary type event not found.'

# Setting Local_internal_option file
SCA_DEFAULT_LOCAL_INTERNAL_OPTIONS = {'wazuh_modules.debug': '2'}
damarisg marked this conversation as resolved.
Show resolved Hide resolved
121 changes: 121 additions & 0 deletions deps/wazuh_testing/wazuh_testing/modules/sca/event_monitor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Copyright (C) 2015-2022, 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

import re
import json

from wazuh_testing import T_60, T_10, T_20
from wazuh_testing.tools import LOG_FILE_PATH
from wazuh_testing.modules import sca
from wazuh_testing.tools.monitoring import FileMonitor, generate_monitoring_callback


# Callbacks
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def callback_scan_id_result(line):
damarisg marked this conversation as resolved.
Show resolved Hide resolved
'''Callback that returns the ID an result of a SCA check
Args:
line (str): line string to check for match.
'''
match = re.match(sca.CB_SCAN_RULE_RESULT, line)
if match:
return [match.group(1), match.group(2)]


def callback_detect_sca_scan_summary(line):
damarisg marked this conversation as resolved.
Show resolved Hide resolved
'''Callback that return the json from a SCA summary event.
Args:
line (str): line string to check for match.
'''
match = re.match(sca.CB_SCA_SCAN_EVENT, line)
if match:
if json.loads(match.group(1))['type'] == 'summary':
return json.loads(match.group(1))


# Event checkers
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def check_sca_event(file_monitor=None, callback='.*', error_message=None, update_position=False,
timeout=T_60, accum_results=1, file_to_monitor=LOG_FILE_PATH):
"""Check if a sca event occurs

Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
callback (str): log regex to check in Wazuh log
error_message (str): error message to show in case of expected event does not occur
update_position (boolean): filter configuration parameter to search in Wazuh log
timeout (str): timeout to check the event in Wazuh log
accum_results (int): Accumulation of matches.
file_to_monitor (str): Path of the file where to check for the expected events
"""
file_monitor = FileMonitor(file_to_monitor) if file_monitor is None else file_monitor
error_message = f"Could not find this event in {file_to_monitor}: {callback}" if error_message is None else \
damarisg marked this conversation as resolved.
Show resolved Hide resolved
error_message
damarisg marked this conversation as resolved.
Show resolved Hide resolved

file_monitor.start(timeout=timeout, update_position=update_position, accum_results=accum_results,
callback=generate_monitoring_callback(callback), error_message=error_message)


def check_sca_enabled(file_monitor=None):
"""Check if the sca module is enabled
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
"""
check_sca_event(callback=sca.CB_SCA_ENABLED, timeout=T_10, file_monitor=file_monitor)


def check_sca_disabled(file_monitor=None):
"""Check if the sca module is disabled
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
"""
check_sca_event(callback=sca.CB_SCA_DISABLED, timeout=T_10, file_monitor=file_monitor)


def check_sca_scan_started(file_monitor=None):
"""Check if the sca scan has started
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
"""
check_sca_event(callback=sca.CB_SCA_SCAN_STARTED, timeout=T_10, file_monitor=file_monitor)


def check_sca_scan_ended(file_monitor=None):
"""Check if the sca scan has ended
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
"""
check_sca_event(callback=sca.CB_SCA_SCAN_ENDED, timeout=T_10, file_monitor=file_monitor)


def check_scan_regex_engine(file_monitor=None):
damarisg marked this conversation as resolved.
Show resolved Hide resolved
"""Check returns the regex engine used on a SCA scan.
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
"""
file_monitor = FileMonitor(LOG_FILE_PATH) if file_monitor is None else file_monitor
engine = file_monitor.start(callback=generate_monitoring_callback(sca.CB_SCA_OSREGEX_ENGINE), timeout=T_10,
error_message=sca.ERR_MSG_REGEX_ENGINE, update_position=False).result()
return engine


def get_sca_scan_rule_id_results(file_monitor=None, results_num=1):
"""Check the expected ammount of check results have been recieved
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
results_num (int): Ammount of rule check results that should be recieved.
"""
file_monitor = FileMonitor(LOG_FILE_PATH) if file_monitor is None else file_monitor
results = file_monitor.start(callback=callback_scan_id_result, timeout=T_20, accum_results=results_num,
error_message=sca.ERR_MSG_ID_RESULTS).result()
return results


def get_sca_scan_summary(file_monitor=None):
"""Get the scan summary event
Args:
file_monitor (FileMonitor): FileMonitor object to monitor the file content.
"""
file_monitor = FileMonitor(LOG_FILE_PATH) if file_monitor is None else file_monitor
results = file_monitor.start(callback=callback_detect_sca_scan_summary, timeout=T_20,
error_message=sca.ERR_MSG_SCA_SUMMARY).result()
return results
24 changes: 24 additions & 0 deletions deps/wazuh_testing/wazuh_testing/tools/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,30 @@ def remove_file(file_path):
delete_path_recursively(file_path)


def copy_files_in_folder(folder, target_folder='/tmp', files_to_move=None):
juliamagan marked this conversation as resolved.
Show resolved Hide resolved
"""Copy files from a folder to target folder

Args:
folder (str): directory path from where to copy files.
target_folder (str): directory path where files will be copied to.
files_to_move (list): List with files to move copy from a folder.
"""
file_list = []
if os.path.isdir(folder):
if files_to_move is None:
for file in os.listdir(folder):
file_list.append(file)
copy(os.path.join(folder, file), target_folder)
remove_file(os.path.join(folder, file))
else:
for file in files_to_move:
if os.path.isfile(os.path.join(folder, file)):
file_list.append(file)
copy(os.path.join(folder, file), target_folder)
remove_file(os.path.join(folder, file))
return file_list


damarisg marked this conversation as resolved.
Show resolved Hide resolved
def validate_json_file(file_path):
try:
with open(file_path) as file:
Expand Down
66 changes: 65 additions & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1018,9 +1018,73 @@ def set_wazuh_configuration(configuration):


@pytest.fixture(scope='function')
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def set_wazuh_configuration_with_local_internal_options(configuration, set_wazuh_configuration,
set_local_internal_options, local_internal_options):
"""Set wazuh configuration

Args:
configuration (dict): Configuration template data to write in the ossec.conf.
local_internal_options(dict): Object containing the local_internal_options_values to be configured.
set_wazuh_configuration (fixture): Set the wazuh configuration according to the configuration data.
set_local_internal_options (fixture): Set the local_internal_options.conf file.
"""
yield


@pytest.fixture(scope='function')
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def set_local_internal_options(local_internal_options):
"""Fixture to configure the local internal options file.

Args:
local_internal_options(dict): Object containing the local_internal_options_values to be configured.
"""

# Backup the old local internal options
backup_local_internal_options = conf.get_wazuh_local_internal_options()

# Set the new local internal options configuration
conf.set_wazuh_local_internal_options(conf.create_local_internal_options(local_internal_options))

yield

# Backup the old local internal options cofiguration
conf.set_wazuh_local_internal_options(backup_local_internal_options)


@pytest.fixture(scope='function')
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def configure_local_internal_options_function(request):
juliamagan marked this conversation as resolved.
Show resolved Hide resolved
"""Fixture to configure the local internal options file.

It uses the test variable local_internal_options. This should be
a dictionary wich keys and values corresponds to the internal option configuration, For example:
local_internal_options = {'monitord.rotate_log': '0', 'syscheck.debug': '0' }
"""
try:
local_internal_options = getattr(request.module, 'local_internal_options')
print("LOCAL_INTERNAL_OPTIONS" + str(local_internal_options))
damarisg marked this conversation as resolved.
Show resolved Hide resolved
except AttributeError as local_internal_configuration_not_set:
logger.debug('local_internal_options is not set')
damarisg marked this conversation as resolved.
Show resolved Hide resolved
raise local_internal_configuration_not_set

backup_local_internal_options = conf.get_local_internal_options_dict()

logger.debug(f"Set local_internal_option to {str(local_internal_options)}")
conf.set_local_internal_options_dict(local_internal_options)

yield

logger.debug(f"Restore local_internal_option to {str(backup_local_internal_options)}")
conf.set_local_internal_options_dict(backup_local_internal_options)


@pytest.fixture()
def truncate_monitored_files():
"""Truncate all the log files and json alerts files before and after the test execution"""
log_files = [LOG_FILE_PATH, ALERT_FILE_PATH]

if 'agent' in get_service():
log_files = [LOG_FILE_PATH]
else:
log_files = [LOG_FILE_PATH, ALERT_FILE_PATH]

for log_file in log_files:
truncate_file(log_file)
Expand Down
38 changes: 38 additions & 0 deletions tests/integration/test_sca/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import os
import pytest

from wazuh_testing import LOG_FILE_PATH, CIS_RULESET_PATH
from wazuh_testing.modules import sca
from wazuh_testing.modules.sca import event_monitor as evm
from wazuh_testing.tools.file import copy, delete_file, copy_files_in_folder
from wazuh_testing.tools.monitoring import FileMonitor


# Variables
TEST_DATA_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data')


# Fixtures
@pytest.fixture(scope='function')
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def wait_for_sca_enabled():
'''
Wait for the sca module to start.
'''
wazuh_monitor = FileMonitor(LOG_FILE_PATH)
evm.check_sca_enabled(wazuh_monitor)
damarisg marked this conversation as resolved.
Show resolved Hide resolved


@pytest.fixture(scope='function')
damarisg marked this conversation as resolved.
Show resolved Hide resolved
def prepare_cis_policies_file(metadata):
'''
Copies policy file from named by metadata into agent's ruleset path. Deletes file after test.
Args:
metadata (dict): contains the test metadata. Must contain policy_file key with file name.
'''
files_to_restore = copy_files_in_folder(folder=CIS_RULESET_PATH, target_folder=sca.TEMP_FILE_PATH)
filename = metadata['policy_file']
filepath = os.path.join(TEST_DATA_PATH, 'policies', filename)
copy(filepath, CIS_RULESET_PATH)
yield
copy_files_in_folder(folder=sca.TEMP_FILE_PATH, target_folder=CIS_RULESET_PATH, files_to_move=files_to_restore)
damarisg marked this conversation as resolved.
Show resolved Hide resolved
delete_file(os.path.join(CIS_RULESET_PATH, filename))
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- sections:
- section: sca
elements:
- enabled:
value: ENABLED
- scan_on_start:
value: 'yes'
- interval:
value: INTERVAL
- policies:
elements:
- policy:
value: POLICY_FILE

- section: rootcheck
elements:
- disabled:
value: 'yes'

- section: syscheck
elements:
- disabled:
value: 'yes'

- section: wodle
attributes:
- name: syscollector
elements:
- disabled:
value: 'yes'
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- sections:
- section: sca
elements:
- enabled:
value: ENABLED
- scan_on_start:
value: 'yes'
- interval:
value: INTERVAL
- policies:
elements:
- policy:
value: POLICY_FILE

- section: rootcheck
elements:
- disabled:
value: 'yes'

- section: syscheck
elements:
- disabled:
value: 'yes'

- section: wodle
attributes:
- name: syscollector
elements:
- disabled:
value: 'yes'
damarisg marked this conversation as resolved.
Show resolved Hide resolved
Loading