diff --git a/lib/check/check.py b/lib/check/check.py index 481ea5cd..3de5311f 100644 --- a/lib/check/check.py +++ b/lib/check/check.py @@ -8,6 +8,12 @@ from lib.logger import logger from lib.outputs import report +# Exclude checks to run +def exclude_checks_to_run(checks_to_execute, excluded_checks): + for check in excluded_checks: + checks_to_execute.discard(check) + return checks_to_execute + # Parse checks from file def parse_checks_from_file(checks_file): checks_to_execute = set() @@ -27,7 +33,7 @@ def parse_checks_from_file(checks_file): def load_checks_to_execute(checks_file, check_list, provider): checks_to_execute = set() - # LOADER + # Handle if there are checks passed using -c/--checks if check_list: for check_name in check_list: @@ -35,11 +41,8 @@ def load_checks_to_execute(checks_file, check_list, provider): # Handle if there are checks passed using -C/--checks-file elif checks_file: - # check if file exists or path - # check permissions to read try: checks_to_execute = parse_checks_from_file(checks_file) - except Exception as e: logger.error(f"{checks_file}: {e.__class__.__name__}") @@ -52,7 +55,7 @@ def load_checks_to_execute(checks_file, check_list, provider): # Format: "providers.{provider}.services.{service}.{check_name}.{check_name}" check_name = check_module.split(".")[-1] checks_to_execute.add(check_name) - print(checks_to_execute) + return checks_to_execute diff --git a/lib/check/check_test.py b/lib/check/check_test.py index 9bafe921..968e7284 100644 --- a/lib/check/check_test.py +++ b/lib/check/check_test.py @@ -1,6 +1,6 @@ import os -from lib.check.check import parse_checks_from_file +from lib.check.check import exclude_checks_to_run, parse_checks_from_file class Test_Check: @@ -15,15 +15,13 @@ class Test_Check: # for test in test_cases: # assert importlib.import_module(test["input"]).__name__ == test["expected"] - def test_parse_checks_from_file(checks_file): + def test_parse_checks_from_file(self): test_cases = [ { - "name": "Test valid check path", "input": f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/checklistA.txt", "expected": {"check12", "check11", "extra72", "check13"}, }, { - "name": "Test valid check path", "input": f"{os.path.dirname(os.path.realpath(__file__))}/fixtures/checklistB.txt", "expected": { "extra72", @@ -37,3 +35,27 @@ class Test_Check: ] for test in test_cases: assert parse_checks_from_file(test["input"]) == test["expected"] + + def test_exclude_checks_to_run(self): + test_cases = [ + { + "input": { + "check_list": {"check12", "check11", "extra72", "check13"}, + "excluded_checks": {"check12", "check13"}, + }, + "expected": {"check11", "extra72"}, + }, + { + "input": { + "check_list": {"check112", "check11", "extra72", "check13"}, + "excluded_checks": {"check12", "check13", "check14"}, + }, + "expected": {"check112", "check11", "extra72"}, + }, + ] + for test in test_cases: + check_list = test["input"]["check_list"] + excluded_checks = test["input"]["excluded_checks"] + assert ( + exclude_checks_to_run(check_list, excluded_checks) == test["expected"] + ) diff --git a/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials.py b/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials.py index 3f602006..2d62c088 100644 --- a/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials.py +++ b/providers/aws/services/iam/iam_disable_30_days_credentials/iam_disable_30_days_credentials.py @@ -1,6 +1,6 @@ from datetime import datetime -from lib.check import Check, Check_Report +from lib.check.check import Check, Check_Report from providers.aws.services.iam.iam_service import iam_client maximum_expiration_days = 30 diff --git a/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py b/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py index a58229b9..afd79e97 100644 --- a/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py +++ b/providers/aws/services/iam/iam_disable_90_days_credentials/iam_disable_90_days_credentials.py @@ -1,6 +1,6 @@ from datetime import datetime -from lib.check import Check, Check_Report +from lib.check.check import Check, Check_Report from providers.aws.services.iam.iam_service import iam_client maximum_expiration_days = 90 diff --git a/prowler.py b/prowler.py index 1d41ae56..89e023c4 100644 --- a/prowler.py +++ b/prowler.py @@ -4,7 +4,12 @@ import argparse from lib.banner import print_banner, print_version -from lib.check.check import import_check, load_checks_to_execute, run_check +from lib.check.check import ( + exclude_checks_to_run, + import_check, + load_checks_to_execute, + run_check, +) from lib.logger import logger, logging_levels from providers.aws.aws_provider import Input_Data, provider_set_session @@ -19,6 +24,7 @@ if __name__ == "__main__": group.add_argument("-c", "--checks", nargs="+", help="List of checks") group.add_argument("-C", "--checks-file", nargs="?", help="List of checks") + parser.add_argument("-e", "--excluded-checks", nargs="+", help="Checks to exclude") parser.add_argument( "-b", "--no-banner", action="store_false", help="Hide Prowler Banner" ) @@ -72,6 +78,7 @@ if __name__ == "__main__": provider = args.provider checks = args.checks + excluded_checks = args.excluded_checks checks_file = args.checks_file # Role assumption input options tests @@ -119,6 +126,11 @@ if __name__ == "__main__": logger.debug("Loading checks") checks_to_execute = load_checks_to_execute(checks_file, checks, provider) + # Exclude checks if -e + if excluded_checks: + checks_to_execute = exclude_checks_to_run(checks_to_execute, excluded_checks) + + # Execute checks for check_name in checks_to_execute: # Recover service from check name