diff --git a/docs/tutorials/configuration_file.md b/docs/tutorials/configuration_file.md index df150c0ad4..87872af14e 100644 --- a/docs/tutorials/configuration_file.md +++ b/docs/tutorials/configuration_file.md @@ -33,7 +33,12 @@ The following list includes all the AWS checks with configurable variables that | `drs_job_exist` | `mute_non_default_regions` | Boolean | | `guardduty_is_enabled` | `mute_non_default_regions` | Boolean | | `securityhub_enabled` | `mute_non_default_regions` | Boolean | - +| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_entropy` | Integer | +| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_minutes` | Integer | +| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_actions` | List of Strings | +| `cloudtrail_threat_detection_enumeration` | `threat_detection_enumeration_entropy` | Integer | +| `cloudtrail_threat_detection_enumeration` | `threat_detection_enumeration_minutes` | Integer | +| `cloudtrail_threat_detection_enumeration` | `threat_detection_enumeration_actions` | List of Strings | ## Azure ### Configurable Checks @@ -148,6 +153,159 @@ aws: # trustedadvisor_premium_support_plan_subscribed verify_premium_support_plans: True + # AWS CloudTrail Configuration + # aws.cloudtrail_threat_detection_privilege_escalation + threat_detection_privilege_escalation_entropy: 0.7 # Percentage of actions found to decide if it is an privilege_escalation attack event, by default is 0.7 (70%) + threat_detection_privilege_escalation_minutes: 1440 # Past minutes to search from now for privilege_escalation attacks, by default is 1440 minutes (24 hours) + threat_detection_privilege_escalation_actions: [ + "AddPermission", + "AddRoleToInstanceProfile", + "AddUserToGroup", + "AssociateAccessPolicy", + "AssumeRole", + "AttachGroupPolicy", + "AttachRolePolicy", + "AttachUserPolicy", + "ChangePassword", + "CreateAccessEntry", + "CreateAccessKey", + "CreateDevEndpoint", + "CreateEventSourceMapping", + "CreateFunction", + "CreateGroup", + "CreateJob", + "CreateKeyPair", + "CreateLoginProfile", + "CreatePipeline", + "CreatePolicyVersion", + "CreateRole", + "CreateStack", + "DeleteRolePermissionsBoundary", + "DeleteRolePolicy", + "DeleteUserPermissionsBoundary", + "DeleteUserPolicy", + "DetachRolePolicy", + "DetachUserPolicy", + "GetCredentialsForIdentity", + "GetId", + "GetPolicyVersion", + "GetUserPolicy", + "Invoke", + "ModifyInstanceAttribute", + "PassRole", + "PutGroupPolicy", + "PutPipelineDefinition", + "PutRolePermissionsBoundary", + "PutRolePolicy", + "PutUserPermissionsBoundary", + "PutUserPolicy", + "ReplaceIamInstanceProfileAssociation", + "RunInstances", + "SetDefaultPolicyVersion", + "UpdateAccessKey", + "UpdateAssumeRolePolicy", + "UpdateDevEndpoint", + "UpdateEventSourceMapping", + "UpdateFunctionCode", + "UpdateJob", + "UpdateLoginProfile", +] + # aws.cloudtrail_threat_detection_enumeration + threat_detection_enumeration_entropy: 0.7 # Percentage of actions found to decide if it is an enumeration attack event, by default is 0.7 (70%) + threat_detection_enumeration_minutes: 1440 # Past minutes to search from now for enumeration attacks, by default is 1440 minutes (24 hours) + threat_detection_enumeration_actions: [ + "DescribeAccessEntry", + "DescribeAccountAttributes", + "DescribeAvailabilityZones", + "DescribeBundleTasks", + "DescribeCarrierGateways", + "DescribeClientVpnRoutes", + "DescribeCluster", + "DescribeDhcpOptions", + "DescribeFlowLogs", + "DescribeImages", + "DescribeInstanceAttribute", + "DescribeInstanceInformation", + "DescribeInstanceTypes", + "DescribeInstances", + "DescribeInstances", + "DescribeKeyPairs", + "DescribeLogGroups", + "DescribeLogStreams", + "DescribeOrganization", + "DescribeRegions", + "DescribeSecurityGroups", + "DescribeSnapshotAttribute", + "DescribeSnapshotTierStatus", + "DescribeSubscriptionFilters", + "DescribeTransitGatewayMulticastDomains", + "DescribeVolumes", + "DescribeVolumesModifications", + "DescribeVpcEndpointConnectionNotifications", + "DescribeVpcs", + "GetAccount", + "GetAccountAuthorizationDetails", + "GetAccountSendingEnabled", + "GetBucketAcl", + "GetBucketLogging", + "GetBucketPolicy", + "GetBucketReplication", + "GetBucketVersioning", + "GetCallerIdentity", + "GetCertificate", + "GetConsoleScreenshot", + "GetCostAndUsage", + "GetDetector", + "GetEbsDefaultKmsKeyId", + "GetEbsEncryptionByDefault", + "GetFindings", + "GetFlowLogsIntegrationTemplate", + "GetIdentityVerificationAttributes", + "GetInstances", + "GetIntrospectionSchema", + "GetLaunchTemplateData", + "GetLaunchTemplateData", + "GetLogRecord", + "GetParameters", + "GetPolicyVersion", + "GetPublicAccessBlock", + "GetQueryResults", + "GetRegions", + "GetSMSAttributes", + "GetSMSSandboxAccountStatus", + "GetSendQuota", + "GetTransitGatewayRouteTableAssociations", + "GetUserPolicy", + "HeadObject", + "ListAccessKeys", + "ListAccounts", + "ListAllMyBuckets", + "ListAssociatedAccessPolicies", + "ListAttachedUserPolicies", + "ListClusters", + "ListDetectors", + "ListDomains", + "ListFindings", + "ListHostedZones", + "ListIPSets", + "ListIdentities", + "ListInstanceProfiles", + "ListObjects", + "ListOrganizationalUnitsForParent", + "ListOriginationNumbers", + "ListPolicyVersions", + "ListRoles", + "ListRoles", + "ListRules", + "ListServiceQuotas", + "ListSubscriptions", + "ListTargetsByRule", + "ListTopics", + "ListUsers", + "LookupEvents", + "Search", +] + # Azure Configuration azure: # Azure Network Configuration diff --git a/prowler/__main__.py b/prowler/__main__.py index 712e6ec363..f120b8ed46 100644 --- a/prowler/__main__.py +++ b/prowler/__main__.py @@ -6,7 +6,10 @@ from os import environ from colorama import Fore, Style -from prowler.config.config import get_available_compliance_frameworks +from prowler.config.config import ( + get_available_compliance_frameworks, + threat_detection_checks, +) from prowler.lib.banner import print_banner from prowler.lib.check.check import ( bulk_load_checks_metadata, @@ -170,6 +173,12 @@ def prowler(): if checks_from_resources: checks_to_execute = checks_to_execute.intersection(checks_from_resources) + # Only execute threat detection checks if threat-detection category is set + if "threat-detection" not in categories: + checks_to_execute = [ + check for check in checks_to_execute if check not in threat_detection_checks + ] + # Sort final check list checks_to_execute = sorted(checks_to_execute) diff --git a/prowler/config/config.py b/prowler/config/config.py index 9efa9ad320..f4058c95f3 100644 --- a/prowler/config/config.py +++ b/prowler/config/config.py @@ -27,6 +27,12 @@ valid_severities = ["critical", "high", "medium", "low", "informational"] # Compliance actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__))) +# AWS CloudTrail Threat Detection checks +threat_detection_checks = [ + "cloudtrail_threat_detection_privilege_escalation", + "cloudtrail_threat_detection_enumeration", +] + def get_available_compliance_frameworks(provider=None): available_compliance_frameworks = [] diff --git a/prowler/config/config.yaml b/prowler/config/config.yaml index 23f9e800c1..b786f34675 100644 --- a/prowler/config/config.yaml +++ b/prowler/config/config.yaml @@ -87,6 +87,159 @@ aws: # aws.trustedadvisor_premium_support_plan_subscribed verify_premium_support_plans: True + # AWS CloudTrail Configuration + # aws.cloudtrail_threat_detection_privilege_escalation + threat_detection_privilege_escalation_entropy: 0.7 # Percentage of actions found to decide if it is an privilege_escalation attack event, by default is 0.7 (70%) + threat_detection_privilege_escalation_minutes: 1440 # Past minutes to search from now for privilege_escalation attacks, by default is 1440 minutes (24 hours) + threat_detection_privilege_escalation_actions: [ + "AddPermission", + "AddRoleToInstanceProfile", + "AddUserToGroup", + "AssociateAccessPolicy", + "AssumeRole", + "AttachGroupPolicy", + "AttachRolePolicy", + "AttachUserPolicy", + "ChangePassword", + "CreateAccessEntry", + "CreateAccessKey", + "CreateDevEndpoint", + "CreateEventSourceMapping", + "CreateFunction", + "CreateGroup", + "CreateJob", + "CreateKeyPair", + "CreateLoginProfile", + "CreatePipeline", + "CreatePolicyVersion", + "CreateRole", + "CreateStack", + "DeleteRolePermissionsBoundary", + "DeleteRolePolicy", + "DeleteUserPermissionsBoundary", + "DeleteUserPolicy", + "DetachRolePolicy", + "DetachUserPolicy", + "GetCredentialsForIdentity", + "GetId", + "GetPolicyVersion", + "GetUserPolicy", + "Invoke", + "ModifyInstanceAttribute", + "PassRole", + "PutGroupPolicy", + "PutPipelineDefinition", + "PutRolePermissionsBoundary", + "PutRolePolicy", + "PutUserPermissionsBoundary", + "PutUserPolicy", + "ReplaceIamInstanceProfileAssociation", + "RunInstances", + "SetDefaultPolicyVersion", + "UpdateAccessKey", + "UpdateAssumeRolePolicy", + "UpdateDevEndpoint", + "UpdateEventSourceMapping", + "UpdateFunctionCode", + "UpdateJob", + "UpdateLoginProfile", +] + # aws.cloudtrail_threat_detection_enumeration + threat_detection_enumeration_entropy: 0.7 # Percentage of actions found to decide if it is an enumeration attack event, by default is 0.7 (70%) + threat_detection_enumeration_minutes: 1440 # Past minutes to search from now for enumeration attacks, by default is 1440 minutes (24 hours) + threat_detection_enumeration_actions: [ + "DescribeAccessEntry", + "DescribeAccountAttributes", + "DescribeAvailabilityZones", + "DescribeBundleTasks", + "DescribeCarrierGateways", + "DescribeClientVpnRoutes", + "DescribeCluster", + "DescribeDhcpOptions", + "DescribeFlowLogs", + "DescribeImages", + "DescribeInstanceAttribute", + "DescribeInstanceInformation", + "DescribeInstanceTypes", + "DescribeInstances", + "DescribeInstances", + "DescribeKeyPairs", + "DescribeLogGroups", + "DescribeLogStreams", + "DescribeOrganization", + "DescribeRegions", + "DescribeSecurityGroups", + "DescribeSnapshotAttribute", + "DescribeSnapshotTierStatus", + "DescribeSubscriptionFilters", + "DescribeTransitGatewayMulticastDomains", + "DescribeVolumes", + "DescribeVolumesModifications", + "DescribeVpcEndpointConnectionNotifications", + "DescribeVpcs", + "GetAccount", + "GetAccountAuthorizationDetails", + "GetAccountSendingEnabled", + "GetBucketAcl", + "GetBucketLogging", + "GetBucketPolicy", + "GetBucketReplication", + "GetBucketVersioning", + "GetCallerIdentity", + "GetCertificate", + "GetConsoleScreenshot", + "GetCostAndUsage", + "GetDetector", + "GetEbsDefaultKmsKeyId", + "GetEbsEncryptionByDefault", + "GetFindings", + "GetFlowLogsIntegrationTemplate", + "GetIdentityVerificationAttributes", + "GetInstances", + "GetIntrospectionSchema", + "GetLaunchTemplateData", + "GetLaunchTemplateData", + "GetLogRecord", + "GetParameters", + "GetPolicyVersion", + "GetPublicAccessBlock", + "GetQueryResults", + "GetRegions", + "GetSMSAttributes", + "GetSMSSandboxAccountStatus", + "GetSendQuota", + "GetTransitGatewayRouteTableAssociations", + "GetUserPolicy", + "HeadObject", + "ListAccessKeys", + "ListAccounts", + "ListAllMyBuckets", + "ListAssociatedAccessPolicies", + "ListAttachedUserPolicies", + "ListClusters", + "ListDetectors", + "ListDomains", + "ListFindings", + "ListHostedZones", + "ListIPSets", + "ListIdentities", + "ListInstanceProfiles", + "ListObjects", + "ListOrganizationalUnitsForParent", + "ListOriginationNumbers", + "ListPolicyVersions", + "ListRoles", + "ListRoles", + "ListRules", + "ListServiceQuotas", + "ListSubscriptions", + "ListTargetsByRule", + "ListTopics", + "ListUsers", + "LookupEvents", + "Search", +] + # Azure Configuration azure: # Azure Network Configuration diff --git a/prowler/providers/aws/aws_provider.py b/prowler/providers/aws/aws_provider.py index 8cce88f9ae..3598e91d84 100644 --- a/prowler/providers/aws/aws_provider.py +++ b/prowler/providers/aws/aws_provider.py @@ -496,7 +496,8 @@ class AwsProvider(Provider): f"{Style.BRIGHT}AWS Regions: {Style.RESET_ALL}{Fore.YELLOW}{regions}{Style.RESET_ALL}", f"{Style.BRIGHT}AWS Account: {Style.RESET_ALL}{Fore.YELLOW}{self._identity.account}{Style.RESET_ALL}", f"{Style.BRIGHT}User Id: {Style.RESET_ALL}{Fore.YELLOW}{self._identity.user_id}{Style.RESET_ALL}", - f"{Style.BRIGHT}Caller Identity ARN: {Style.RESET_ALL}{Fore.YELLOW}{self._identity.identity_arn}{Style.RESET_ALL}", + f"{Style.BRIGHT}Caller Identity ARN: {Style.RESET_ALL}", + f"{Fore.YELLOW}{self._identity.identity_arn}{Style.RESET_ALL}", ] # If -A is set, print Assumed Role ARN if ( diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py index 71d2cfc8fc..d912c57865 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_service.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timedelta from typing import Optional from botocore.client import ClientError @@ -173,6 +173,22 @@ class Cloudtrail(AWSService): f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) + def __lookup_events__(self, trail, event_name, minutes): + logger.info("CloudTrail - Lookup Events...") + try: + regional_client = self.regional_clients[trail.region] + response = regional_client.lookup_events( + LookupAttributes=[ + {"AttributeKey": "EventName", "AttributeValue": event_name} + ], + StartTime=datetime.now() - timedelta(minutes=minutes), + ) + return response.get("Events") + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + def __list_tags_for_resource__(self): logger.info("CloudTrail - List Tags...") try: diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/__init__.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json new file mode 100644 index 0000000000..d0b943254a --- /dev/null +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json @@ -0,0 +1,32 @@ +{ + "Provider": "aws", + "CheckID": "cloudtrail_threat_detection_enumeration", + "CheckTitle": "Ensure there are no potential enumeration threats in CloudTrail", + "CheckType": [], + "ServiceName": "cloudtrail", + "SubServiceName": "", + "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "Severity": "critical", + "ResourceType": "AwsCloudTrailTrail", + "Description": "This check ensures that there are no potential enumeration threats in CloudTrail.", + "Risk": "Potential enumeration threats in CloudTrail can lead to unauthorized access to resources.", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "", + "NativeIaC": "", + "Other": "", + "Terraform": "" + }, + "Recommendation": { + "Text": "To remediate this issue, ensure that there are no potential enumeration threats in CloudTrail.", + "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events" + } + }, + "Categories": [ + "threat-detection" + ], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.py new file mode 100644 index 0000000000..505abdd5aa --- /dev/null +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.py @@ -0,0 +1,69 @@ +import json + +from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( + cloudtrail_client, +) + +ENTROPY_THRESHOLD = cloudtrail_client.audit_config.get( + "threat_detection_enumeration_entropy", 0.7 +) +THREAT_DETECTION_MINUTES = cloudtrail_client.audit_config.get( + "threat_detection_enumeration_minutes", 1440 +) +ENUMERATION_ACTIONS = cloudtrail_client.audit_config.get( + "threat_detection_enumeration_actions", [] +) + + +class cloudtrail_threat_detection_enumeration(Check): + def execute(self): + findings = [] + potential_enumeration = {} + found_potential_enumeration = False + multiregion_trail = None + # Check if any trail is multi-region so we only need to check once + for trail in cloudtrail_client.trails.values(): + if trail.is_multiregion: + multiregion_trail = trail + break + trails_to_scan = ( + cloudtrail_client.trails.values() + if not multiregion_trail + else [multiregion_trail] + ) + for trail in trails_to_scan: + for event_name in ENUMERATION_ACTIONS: + for event_log in cloudtrail_client.__lookup_events__( + trail=trail, + event_name=event_name, + minutes=THREAT_DETECTION_MINUTES, + ): + event_log = json.loads(event_log["CloudTrailEvent"]) + if ".amazonaws.com" not in event_log["sourceIPAddress"]: + if event_log["sourceIPAddress"] not in potential_enumeration: + potential_enumeration[event_log["sourceIPAddress"]] = set() + potential_enumeration[event_log["sourceIPAddress"]].add( + event_name + ) + for source_ip, actions in potential_enumeration.items(): + if len(actions) / len(ENUMERATION_ACTIONS) > ENTROPY_THRESHOLD: + found_potential_enumeration = True + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" + report.status_extended = f"Potential enumeration attack detected from source IP {source_ip} with an entropy of {ENTROPY_THRESHOLD}." + findings.append(report) + if not found_potential_enumeration: + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + report.status_extended = "No potential enumeration attack detected." + findings.append(report) + return findings diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/__init__.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json new file mode 100644 index 0000000000..f5237a1948 --- /dev/null +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json @@ -0,0 +1,32 @@ +{ + "Provider": "aws", + "CheckID": "cloudtrail_threat_detection_privilege_escalation", + "CheckTitle": "Ensure there are no potential privilege escalation threats in CloudTrail", + "CheckType": [], + "ServiceName": "cloudtrail", + "SubServiceName": "", + "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "Severity": "critical", + "ResourceType": "AwsCloudTrailTrail", + "Description": "This check ensures that there are no potential privilege escalation threats in CloudTrail.", + "Risk": "Potential privilege escalation threats in CloudTrail can lead to unauthorized access to resources.", + "RelatedUrl": "", + "Remediation": { + "Code": { + "CLI": "", + "NativeIaC": "", + "Other": "", + "Terraform": "" + }, + "Recommendation": { + "Text": "To remediate this issue, ensure that there are no potential privilege escalation threats in CloudTrail.", + "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events" + } + }, + "Categories": [ + "threat-detection" + ], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.py b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.py new file mode 100644 index 0000000000..3a631e5124 --- /dev/null +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.py @@ -0,0 +1,76 @@ +import json + +from prowler.lib.check.models import Check, Check_Report_AWS +from prowler.providers.aws.services.cloudtrail.cloudtrail_client import ( + cloudtrail_client, +) + +ENTROPY_THRESHOLD = cloudtrail_client.audit_config.get( + "threat_detection_privilege_escalation_entropy", 0.7 +) +THREAT_DETECTION_MINUTES = cloudtrail_client.audit_config.get( + "threat_detection_privilege_escalation_minutes", 1440 +) +PRIVILEGE_ESCALATION_ACTIONS = cloudtrail_client.audit_config.get( + "threat_detection_privilege_escalation_actions", [] +) + + +class cloudtrail_threat_detection_privilege_escalation(Check): + def execute(self): + findings = [] + potential_privilege_escalation = {} + found_potential_privilege_escalation = False + multiregion_trail = None + # Check if any trail is multi-region so we only need to check once + for trail in cloudtrail_client.trails.values(): + if trail.is_multiregion: + multiregion_trail = trail + break + trails_to_scan = ( + cloudtrail_client.trails.values() + if not multiregion_trail + else [multiregion_trail] + ) + for trail in trails_to_scan: + for event_name in PRIVILEGE_ESCALATION_ACTIONS: + for event_log in cloudtrail_client.__lookup_events__( + trail=trail, + event_name=event_name, + minutes=THREAT_DETECTION_MINUTES, + ): + event_log = json.loads(event_log["CloudTrailEvent"]) + if ".amazonaws.com" not in event_log["sourceIPAddress"]: + if ( + event_log["sourceIPAddress"] + not in potential_privilege_escalation + ): + potential_privilege_escalation[ + event_log["sourceIPAddress"] + ] = set() + potential_privilege_escalation[ + event_log["sourceIPAddress"] + ].add(event_name) + for source_ip, actions in potential_privilege_escalation.items(): + if len(actions) / len(PRIVILEGE_ESCALATION_ACTIONS) > ENTROPY_THRESHOLD: + found_potential_privilege_escalation = True + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "FAIL" + report.status_extended = f"Potential privilege escalation attack detected from source IP {source_ip} with an entropy of {ENTROPY_THRESHOLD}." + findings.append(report) + if not found_potential_privilege_escalation: + report = Check_Report_AWS(self.metadata()) + report.region = trail.region + report.resource_id = trail.name + report.resource_arn = trail.arn + report.resource_tags = trail.tags + report.status = "PASS" + report.status_extended = ( + "No potential privilege escalation attack detected." + ) + findings.append(report) + return findings