diff --git a/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/__init__.py b/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled.metadata.json b/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled.metadata.json new file mode 100644 index 0000000000..1b7c40eef1 --- /dev/null +++ b/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled.metadata.json @@ -0,0 +1,32 @@ +{ + "Provider": "aws", + "CheckID": "guardduty_eks_runtime_monitoring_enabled", + "CheckTitle": "GuardDuty EKS Runtime Monitoring should be enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], + "ServiceName": "guardduty", + "SubServiceName": "", + "ResourceIdTemplate": "arn:aws:guardduty:{region}:{account-id}:detector/{detector-id}", + "Severity": "medium", + "ResourceType": "AwsGuardDutyDetector", + "Description": "This control checks whether GuardDuty EKS Runtime Monitoring with automated agent management is enabled. For a standalone account, the control fails if GuardDuty EKS Runtime Monitoring with automated agent management is disabled in the account. In a multi-account environment, the control fails if the delegated GuardDuty administrator account and all member accounts don't have EKS Runtime Monitoring with automated agent management enabled.", + "Risk": "Without EKS Runtime Monitoring in GuardDuty, your Amazon EKS clusters may lack necessary protection against potential threats that can compromise container security, leading to unmonitored security risks.", + "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/guardduty-eks-protection-runtime-enabled.html", + "Remediation": { + "Code": { + "CLI": "aws guardduty update-organization-configuration --detector-id --eks-runtime-monitoring-configuration Enable=true --auto-enable", + "NativeIaC": "", + "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/guardduty-controls.html#guardduty-7", + "Terraform": "" + }, + "Recommendation": { + "Text": "Enable GuardDuty EKS Runtime Monitoring with automated agent management to protect EKS clusters.", + "Url": "https://docs.aws.amazon.com/guardduty/latest/ug/runtime-monitoring-configuration.html" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled.py b/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled.py new file mode 100644 index 0000000000..2abad2e01f --- /dev/null +++ b/prowler/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled.py @@ -0,0 +1,21 @@ +from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.guardduty.guardduty_client import guardduty_client + + +class guardduty_eks_runtime_monitoring_enabled(Check): + def execute(self): + findings = [] + for detector in guardduty_client.detectors: + if detector.status: + report = Check_Report_AWS(self.metadata()) + report.region = detector.region + report.resource_id = detector.id + report.resource_arn = detector.arn + report.resource_tags = detector.tags + report.status = "FAIL" + report.status_extended = f"GuardDuty detector {detector.id} does not have EKS Runtime Monitoring enabled." + if detector.eks_runtime_monitoring: + report.status = "PASS" + report.status_extended = f"GuardDuty detector {detector.id} has EKS Runtime Monitoring enabled." + findings.append(report) + return findings diff --git a/prowler/providers/aws/services/guardduty/guardduty_service.py b/prowler/providers/aws/services/guardduty/guardduty_service.py index 5669ecfec6..c83833cef2 100644 --- a/prowler/providers/aws/services/guardduty/guardduty_service.py +++ b/prowler/providers/aws/services/guardduty/guardduty_service.py @@ -99,6 +99,11 @@ class GuardDuty(AWSService): and feat.get("Status", "DISABLED") == "ENABLED" ): detector.lambda_protection = True + elif ( + feat.get("Name", "") == "EKS_RUNTIME_MONITORING" + and feat.get("Status", "DISABLED") == "ENABLED" + ): + detector.eks_runtime_monitoring = True except Exception as error: logger.error( @@ -223,5 +228,6 @@ class Detector(BaseModel): s3_protection: bool = False rds_protection: bool = False eks_audit_log_protection: bool = False + eks_runtime_monitoring: bool = False lambda_protection: bool = False ec2_malware_protection: bool = False diff --git a/tests/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled_test.py b/tests/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled_test.py new file mode 100644 index 0000000000..845dba57ce --- /dev/null +++ b/tests/providers/aws/services/guardduty/guardduty_eks_runtime_monitoring_enabled/guardduty_eks_runtime_monitoring_enabled_test.py @@ -0,0 +1,152 @@ +from unittest import mock + +from boto3 import client +from moto import mock_aws + +from prowler.providers.aws.services.guardduty.guardduty_service import GuardDuty +from tests.providers.aws.utils import ( + AWS_ACCOUNT_NUMBER, + AWS_REGION_US_EAST_1, + set_mocked_aws_provider, +) + + +class Test_guardduty_eks_runtime_monitoring_enabled: + @mock_aws + def test_no_detectors(self): + client("guardduty", region_name=AWS_REGION_US_EAST_1) + + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled.guardduty_client", + new=GuardDuty(aws_provider), + ): + + from prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled import ( + guardduty_eks_runtime_monitoring_enabled, + ) + + check = guardduty_eks_runtime_monitoring_enabled() + result = check.execute() + + assert len(result) == 0 + + @mock_aws + def test_detector_disabled(self): + guardduty_client = client("guardduty", region_name=AWS_REGION_US_EAST_1) + guardduty_client.create_detector( + Enable=False, + DataSources={ + "S3Logs": {"Enable": True}, + "Kubernetes": {"AuditLogs": {"Enable": True}}, + }, + Features=[{"Name": "EKS_RUNTIME_MONITORING", "Status": "ENABLED"}], + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled.guardduty_client", + new=GuardDuty(aws_provider), + ): + + from prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled import ( + guardduty_eks_runtime_monitoring_enabled, + ) + + check = guardduty_eks_runtime_monitoring_enabled() + result = check.execute() + + assert len(result) == 0 + + @mock_aws + def test_detector_enabled_eks_runtime_monitoring_disabled(self): + guardduty_client = client("guardduty", region_name=AWS_REGION_US_EAST_1) + response = guardduty_client.create_detector( + Enable=True, + DataSources={ + "S3Logs": {"Enable": True}, + "Kubernetes": {"AuditLogs": {"Enable": True}}, + }, + Features=[{"Name": "EKS_RUNTIME_MONITORING", "Status": "DISABLED"}], + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled.guardduty_client", + new=GuardDuty(aws_provider), + ): + + from prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled import ( + guardduty_eks_runtime_monitoring_enabled, + ) + + check = guardduty_eks_runtime_monitoring_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == f"GuardDuty detector {response['DetectorId']} does not have EKS Runtime Monitoring enabled." + ) + assert result[0].resource_id == response["DetectorId"] + assert result[0].region == AWS_REGION_US_EAST_1 + assert ( + result[0].resource_arn + == f"arn:aws:guardduty:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:detector/{response['DetectorId']}" + ) + assert result[0].resource_tags == [] + + @mock_aws + def test_detector_enabled_eks_runtime_monitoring_enabled(self): + guardduty_client = client("guardduty", region_name=AWS_REGION_US_EAST_1) + response = guardduty_client.create_detector( + Enable=True, + DataSources={ + "S3Logs": {"Enable": True}, + "Kubernetes": {"AuditLogs": {"Enable": True}}, + }, + Features=[{"Name": "EKS_RUNTIME_MONITORING", "Status": "ENABLED"}], + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), mock.patch( + "prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled.guardduty_client", + new=GuardDuty(aws_provider), + ): + from prowler.providers.aws.services.guardduty.guardduty_eks_runtime_monitoring_enabled.guardduty_eks_runtime_monitoring_enabled import ( + guardduty_eks_runtime_monitoring_enabled, + ) + + check = guardduty_eks_runtime_monitoring_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"GuardDuty detector {response['DetectorId']} has EKS Runtime Monitoring enabled." + ) + assert result[0].resource_id == response["DetectorId"] + assert result[0].region == AWS_REGION_US_EAST_1 + assert ( + result[0].resource_arn + == f"arn:aws:guardduty:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:detector/{response['DetectorId']}" + ) + assert result[0].resource_tags == [] diff --git a/tests/providers/aws/services/guardduty/guardduty_service_test.py b/tests/providers/aws/services/guardduty/guardduty_service_test.py index 532020f083..e6d51a05a1 100644 --- a/tests/providers/aws/services/guardduty/guardduty_service_test.py +++ b/tests/providers/aws/services/guardduty/guardduty_service_test.py @@ -115,7 +115,10 @@ class Test_GuardDuty_Service: "S3Logs": {"Enable": True}, "Kubernetes": {"AuditLogs": {"Enable": True}}, }, - Features=[{"Name": "LAMBDA_NETWORK_LOGS", "Status": "ENABLED"}], + Features=[ + {"Name": "LAMBDA_NETWORK_LOGS", "Status": "ENABLED"}, + {"Name": "EKS_RUNTIME_MONITORING", "Status": "ENABLED"}, + ], ) aws_provider = set_mocked_aws_provider() @@ -134,6 +137,7 @@ class Test_GuardDuty_Service: assert guardduty.detectors[0].s3_protection assert not guardduty.detectors[0].rds_protection assert guardduty.detectors[0].eks_audit_log_protection + assert guardduty.detectors[0].eks_runtime_monitoring assert guardduty.detectors[0].lambda_protection assert not guardduty.detectors[0].ec2_malware_protection assert guardduty.detectors[0].region == AWS_REGION_EU_WEST_1