diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 3161f5cd2f..e05172e495 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Certificate authentication for M365 provider [(#8404)](https://github.com/prowler-cloud/prowler/pull/8404) - `vm_sufficient_daily_backup_retention_period` check for Azure provider [(#8200)](https://github.com/prowler-cloud/prowler/pull/8200) - `vm_jit_access_enabled` check for Azure provider [(#8202)](https://github.com/prowler-cloud/prowler/pull/8202) +- Bedrock AgentCore privilege escalation combination for AWS provider [(#8526)](https://github.com/prowler-cloud/prowler/pull/8526) ### Changed - Refine kisa isms-p compliance mapping [(#8479)](https://github.com/prowler-cloud/prowler/pull/8479) diff --git a/prowler/providers/aws/services/iam/lib/privilege_escalation.py b/prowler/providers/aws/services/iam/lib/privilege_escalation.py index 76245ce2c9..a9541f9d48 100644 --- a/prowler/providers/aws/services/iam/lib/privilege_escalation.py +++ b/prowler/providers/aws/services/iam/lib/privilege_escalation.py @@ -86,6 +86,12 @@ privilege_escalation_policies_combination = { "sts:AssumeRole", "iam:UpdateAssumeRolePolicy", }, + # AgentCore privilege escalation patterns + "PassRole+AgentCoreCreateInterpreter+InvokeInterpreter": { + "iam:PassRole", + "bedrock-agentcore:CreateCodeInterpreter", + "bedrock-agentcore:InvokeCodeInterpreter", + }, # TO-DO: We have to handle AssumeRole just if the resource is * and without conditions # "sts:AssumeRole": {"sts:AssumeRole"}, } diff --git a/tests/providers/aws/services/iam/iam_inline_policy_allows_privilege_escalation/iam_inline_policy_allows_privilege_escalation_test.py b/tests/providers/aws/services/iam/iam_inline_policy_allows_privilege_escalation/iam_inline_policy_allows_privilege_escalation_test.py index 2463dbd34f..84f697c39e 100644 --- a/tests/providers/aws/services/iam/iam_inline_policy_allows_privilege_escalation/iam_inline_policy_allows_privilege_escalation_test.py +++ b/tests/providers/aws/services/iam/iam_inline_policy_allows_privilege_escalation/iam_inline_policy_allows_privilege_escalation_test.py @@ -1219,3 +1219,75 @@ class Test_iam_inline_policy_allows_privilege_escalation: f"Inline Policy '{policy_name}' attached to role {role_arn} allows privilege escalation using the following actions:", finding.status_extended, ) + + @mock_aws + def test_iam_inline_role_policy_allows_privilege_escalation_agentcore(self): + """Test detection of AWS Bedrock AgentCore privilege escalation in inline role policy.""" + iam_client = client("iam", region_name=AWS_REGION_US_EAST_1) + # Create IAM Role + role_name = "agentcore_test_role" + role_arn = iam_client.create_role( + RoleName=role_name, + AssumeRolePolicyDocument=dumps(ADMINISTRATOR_ROLE_ASSUME_ROLE_POLICY), + )["Role"]["Arn"] + + # Put Role Policy with AgentCore privilege escalation permissions + policy_name = "agentcore_policy" + policy_document = { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:PassRole", + "bedrock-agentcore:CreateCodeInterpreter", + "bedrock-agentcore:InvokeCodeInterpreter", + ], + "Resource": "*", + } + ], + } + _ = iam_client.put_role_policy( + RoleName=role_name, + PolicyName=policy_name, + PolicyDocument=dumps(policy_document), + ) + + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + from prowler.providers.aws.services.iam.iam_service import IAM + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), + mock.patch( + "prowler.providers.aws.services.iam.iam_inline_policy_allows_privilege_escalation.iam_inline_policy_allows_privilege_escalation.iam_client", + new=IAM(aws_provider), + ), + ): + # Test Check + from prowler.providers.aws.services.iam.iam_inline_policy_allows_privilege_escalation.iam_inline_policy_allows_privilege_escalation import ( + iam_inline_policy_allows_privilege_escalation, + ) + + check = iam_inline_policy_allows_privilege_escalation() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert result[0].resource_id == f"{role_name}/{policy_name}" + assert result[0].resource_arn == role_arn + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [] + + assert search( + f"Inline policy {policy_name} attached to role {role_name} allows privilege escalation using the following actions: ", + result[0].status_extended, + ) + assert search("iam:PassRole", result[0].status_extended) + assert search( + "bedrock-agentcore:CreateCodeInterpreter", result[0].status_extended + ) + assert search( + "bedrock-agentcore:InvokeCodeInterpreter", result[0].status_extended + ) diff --git a/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py b/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py index d1a636a009..94f397d04b 100644 --- a/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py +++ b/tests/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation_test.py @@ -915,6 +915,71 @@ class Test_iam_policy_allows_privilege_escalation: ]: assert search(permission, finding.status_extended) + @mock_aws + def test_iam_policy_allows_privilege_escalation_agentcore_passrole_create_invoke( + self, + ): + """Test detection of AWS Bedrock AgentCore privilege escalation pattern.""" + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + iam_client = client("iam", region_name=AWS_REGION_US_EAST_1) + policy_name = "agentcore_privilege_escalation_policy" + policy_document = { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "iam:PassRole", + "bedrock-agentcore:CreateCodeInterpreter", + "bedrock-agentcore:InvokeCodeInterpreter", + ], + "Resource": "*", + } + ], + } + + policy_arn = iam_client.create_policy( + PolicyName=policy_name, PolicyDocument=dumps(policy_document) + )["Policy"]["Arn"] + + from prowler.providers.aws.services.iam.iam_service import IAM + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=aws_provider, + ), + mock.patch( + "prowler.providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation.iam_client", + new=IAM(aws_provider), + ), + ): + # Test Check + from prowler.providers.aws.services.iam.iam_policy_allows_privilege_escalation.iam_policy_allows_privilege_escalation import ( + iam_policy_allows_privilege_escalation, + ) + + check = iam_policy_allows_privilege_escalation() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert result[0].resource_id == policy_name + assert result[0].resource_arn == policy_arn + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [] + + assert search( + f"Custom Policy {policy_arn} allows privilege escalation using the following actions: ", + result[0].status_extended, + ) + assert search("iam:PassRole", result[0].status_extended) + assert search( + "bedrock-agentcore:CreateCodeInterpreter", result[0].status_extended + ) + assert search( + "bedrock-agentcore:InvokeCodeInterpreter", result[0].status_extended + ) + @mock_aws def test_iam_policy_allows_privilege_escalation_iam_put( self,