We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug]: iam_policy_allows_privilege_escalation is raising false positives
### Steps to Reproduce

When looking at the scan results for "Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation" it look like we are getting bad results for it now using Prowler version 3.8.2.


If I run a scan on an AWS IAM policy defined with the below json I get the failure -

_Custom Policy arn:aws:iam::xxxxxxxxxxx:policy/app-user-policy-hertzcp-pprd allows privilege escalation using the following actions: {'iam:CreateAccessKey'}_

The below is the AWS IAM policy json that it scanned and as you can see the policy does not have 'iam:CreateAccessKey' within it :
 
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "es:List*",
                "es:Get*",
                "es:Describe*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "es:*",
            "Resource": "arn:aws:es:us-west-2:xxxxxxxxxxxx:domain/g-clients-infra-pprd/*"
        }
    ]
}
```

When I used prowler version 3.4.1 it did not find/report on the above issue.


Also - 
Prowler version 3.8.2 now reports the below policy as passing for "Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation"  :

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::*:role/xena-role"
        }
    ]
}
```

When a scan using prowler version 3.4.1 was run the above policy was reported as a failure for "Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation". 
I would believe that this policy should still be reported as a failure and that Prowler version 3.8.2 has issues.

### Expected behavior

The first policy should pass and the second policy should fail.

### Actual Result with Screenshots or Logs

[prowler-output-741743798098-20230823103540.csv](https://github.com/prowler-cloud/prowler/files/12421414/prowler-output-741743798098-20230823103540.csv)


### How did you install Prowler?

From pip package (pip install prowler)

### Environment Resource

EKS and ran the scan locally

### OS used

MacOS

### Prowler version

3.8.2

### Pip version

21.1.3

### Context

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py`
Content:
```
1 from re import search
2 
3 from prowler.lib.check.models import Check, Check_Report_AWS
4 from prowler.providers.aws.services.iam.iam_client import iam_client
5 
6 # Does the tool analyze both users and roles, or just one or the other? --> Everything using AttachementCount.
7 # Does the tool take a principal-centric or policy-centric approach? --> Policy-centric approach.
8 # Does the tool handle resource constraints? --> We don't check if the policy affects all resources or not, we check everything.
9 # Does the tool consider the permissions of service roles? --> Just checks policies.
10 # Does the tool handle transitive privesc paths (i.e., attack chains)? --> Not yet.
11 # Does the tool handle the DENY effect as expected? --> Yes, it checks DENY's statements with Action and NotAction.
12 # Does the tool handle NotAction as expected? --> Yes
13 # Does the tool handle Condition constraints? --> Not yet.
14 # Does the tool handle service control policy (SCP) restrictions? --> No, SCP are within Organizations AWS API.
15 
16 # Based on:
17 # - https://bishopfox.com/blog/privilege-escalation-in-aws
18 # - https://github.com/RhinoSecurityLabs/Security-Research/blob/master/tools/aws-pentest-tools/aws_escalate.py
19 # - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/
20 
21 
22 class iam_policy_allows_privilege_escalation(Check):
23     def execute(self) -> Check_Report_AWS:
24         privilege_escalation_policies_combination = {
25             "CreatePolicyVersion": {"iam:CreatePolicyVersion"},
26             "SetDefaultPolicyVersion": {"iam:SetDefaultPolicyVersion"},
27             "iam:PassRole": {"iam:PassRole"},
28             "PassRole+EC2": {
29                 "iam:PassRole",
30                 "ec2:RunInstances",
31             },
32             "PassRole+CreateLambda+Invoke": {
33                 "iam:PassRole",
34                 "lambda:CreateFunction",
35                 "lambda:InvokeFunction",
36             },
37             "PassRole+CreateLambda+ExistingDynamo": {
38                 "iam:PassRole",
39                 "lambda:CreateFunction",
40                 "lambda:CreateEventSourceMapping",
41             },
42             "PassRole+CreateLambda+NewDynamo": {
43                 "iam:PassRole",
44                 "lambda:CreateFunction",
45                 "lambda:CreateEventSourceMapping",
46                 "dynamodb:CreateTable",
47                 "dynamodb:PutItem",
48             },
49             "PassRole+GlueEndpoint": {
50                 "iam:PassRole",
51                 "glue:CreateDevEndpoint",
52                 "glue:GetDevEndpoint",
53             },
54             "PassRole+GlueEndpoints": {
55                 "iam:PassRole",
56                 "glue:CreateDevEndpoint",
57                 "glue:GetDevEndpoints",
58             },
59             "PassRole+CloudFormation": {
60                 "cloudformation:CreateStack",
61                 "cloudformation:DescribeStacks",
62             },
63             "PassRole+DataPipeline": {
64                 "datapipeline:CreatePipeline",
65                 "datapipeline:PutPipelineDefinition",
66                 "datapipeline:ActivatePipeline",
67             },
68             "GlueUpdateDevEndpoint": {"glue:UpdateDevEndpoint"},
69             "GlueUpdateDevEndpoints": {"glue:UpdateDevEndpoint"},
70             "lambda:UpdateFunctionCode": {"lambda:UpdateFunctionCode"},
71             "iam:CreateAccessKey": {"iam:CreateAccessKey"},
72             "iam:CreateLoginProfile": {"iam:CreateLoginProfile"},
73             "iam:UpdateLoginProfile": {"iam:UpdateLoginProfile"},
74             "iam:AttachUserPolicy": {"iam:AttachUserPolicy"},
75             "iam:AttachGroupPolicy": {"iam:AttachGroupPolicy"},
76             "iam:AttachRolePolicy": {"iam:AttachRolePolicy"},
77             "AssumeRole+AttachRolePolicy": {"sts:AssumeRole", "iam:AttachRolePolicy"},
78             "iam:PutGroupPolicy": {"iam:PutGroupPolicy"},
79             "iam:PutRolePolicy": {"iam:PutRolePolicy"},
80             "AssumeRole+PutRolePolicy": {"sts:AssumeRole", "iam:PutRolePolicy"},
81             "iam:PutUserPolicy": {"iam:PutUserPolicy"},
82             "iam:AddUserToGroup": {"iam:AddUserToGroup"},
83             "iam:UpdateAssumeRolePolicy": {"iam:UpdateAssumeRolePolicy"},
84             "AssumeRole+UpdateAssumeRolePolicy": {
85                 "sts:AssumeRole",
86                 "iam:UpdateAssumeRolePolicy",
87             },
88             # TO-DO: We have to handle AssumeRole just if the resource is * and without conditions
89             # "sts:AssumeRole": {"sts:AssumeRole"},
90         }
91 
92         findings = []
93 
94         # Iterate over all the IAM "Customer Managed" policies
95         for policy in iam_client.policies:
96             if policy.type == "Custom":
97                 report = Check_Report_AWS(self.metadata())
98                 report.resource_id = policy.name
99                 report.resource_arn = policy.arn
100                 report.region = iam_client.region
101                 report.resource_tags = policy.tags
102                 report.status = "PASS"
103                 report.status_extended = f"Custom Policy {report.resource_arn} does not allow privilege escalation."
104 
105                 # List of policy actions
106                 allowed_actions = set()
107                 denied_actions = set()
108                 denied_not_actions = set()
109 
110                 # Recover all policy actions
111                 if policy.document:
112                     if not isinstance(policy.document["Statement"], list):
113                         policy_statements = [policy.document["Statement"]]
114                     else:
115                         policy_statements = policy.document["Statement"]
116                     for statements in policy_statements:
117                         # Recover allowed actions
118                         if statements["Effect"] == "Allow":
119                             if "Action" in statements:
120                                 if type(statements["Action"]) is str:
121                                     allowed_actions.add(statements["Action"])
122                                 if type(statements["Action"]) is list:
123                                     allowed_actions.update(statements["Action"])
124 
125                         # Recover denied actions
126                         if statements["Effect"] == "Deny":
127                             if "Action" in statements:
128                                 if type(statements["Action"]) is str:
129                                     denied_actions.add(statements["Action"])
130                                 if type(statements["Action"]) is list:
131                                     denied_actions.update(statements["Action"])
132 
133                             if "NotAction" in statements:
134                                 if type(statements["NotAction"]) is str:
135                                     denied_not_actions.add(statements["NotAction"])
136                                 if type(statements["NotAction"]) is list:
137                                     denied_not_actions.update(statements["NotAction"])
138 
139                     # First, we need to perform a left join with ALLOWED_ACTIONS and DENIED_ACTIONS
140                     left_actions = allowed_actions.difference(denied_actions)
141                     # Then, we need to find the DENIED_NOT_ACTIONS in LEFT_ACTIONS
142                     if denied_not_actions:
143                         privileged_actions = left_actions.intersection(
144                             denied_not_actions
145                         )
146                     # If there is no Denied Not Actions
147                     else:
148                         privileged_actions = left_actions
149 
150                     # Store all the action's combinations
151                     policies_combination = set()
152 
153                     for values in privilege_escalation_policies_combination.values():
154                         for val in values:
155                             val_set = set()
156                             val_set.add(val)
157                             # Look for specific api:action
158                             if privileged_actions.intersection(val_set) == val_set:
159                                 policies_combination.add(val)
160                             # Look for api:*
161                             else:
162                                 for permission in privileged_actions:
163                                     # Here we have to handle if the api-action is admin, so "*"
164                                     api_action = permission.split(":")
165                                     # len() == 2, so api:action
166                                     if len(api_action) == 2:
167                                         api = api_action[0]
168                                         action = api_action[1]
169                                         # Add permissions if the API is present
170                                         if action == "*":
171                                             if search(api, val):
172                                                 policies_combination.add(val)
173 
174                                     # len() == 1, so *
175                                     elif len(api_action) == 1:
176                                         api = api_action[0]
177                                         # Add permissions if the API is present
178                                         if api == "*":
179                                             policies_combination.add(val)
180 
181                     # Check all policies combinations and see if matchs with some combo key
182                     combos = set()
183                     for (
184                         key,
185                         values,
186                     ) in privilege_escalation_policies_combination.items():
187                         intersection = policies_combination.intersection(values)
188                         if intersection == values:
189                             combos.add(key)
190 
191                     if len(combos) != 0:
192                         report.status = "FAIL"
193                         policies_affected = ""
194                         for key in combos:
195                             policies_affected += (
196                                 str(privilege_escalation_policies_combination[key])
197                                 + " "
198                             )
199 
200                         report.status_extended = (
201                             f"Custom Policy {report.resource_arn} allows privilege escalation using the following actions: {policies_affected}".rstrip()
202                             + "."
203                         )
204                 findings.append(report)
205         return findings
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py b/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py
--- a/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py
+++ b/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py
@@ -1,5 +1,3 @@
-from re import search
-
 from prowler.lib.check.models import Check, Check_Report_AWS
 from prowler.providers.aws.services.iam.iam_client import iam_client
 
@@ -168,7 +166,8 @@
                                         action = api_action[1]
                                         # Add permissions if the API is present
                                         if action == "*":
-                                            if search(api, val):
+                                            val_api = val.split(":")[0]
+                                            if api == val_api:
                                                 policies_combination.add(val)
 
                                     # len() == 1, so *

{"golden_diff": "diff --git a/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py b/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py\n--- a/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py\n+++ b/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py\n@@ -1,5 +1,3 @@\n-from re import search\n-\n from prowler.lib.check.models import Check, Check_Report_AWS\n from prowler.providers.aws.services.iam.iam_client import iam_client\n \n@@ -168,7 +166,8 @@\n                                         action = api_action[1]\n                                         # Add permissions if the API is present\n                                         if action == \"*\":\n-                                            if search(api, val):\n+                                            val_api = val.split(\":\")[0]\n+                                            if api == val_api:\n                                                 policies_combination.add(val)\n \n                                     # len() == 1, so *\n", "issue": "[Bug]: iam_policy_allows_privilege_escalation is raising false positives\n### Steps to Reproduce\r\n\r\nWhen looking at the scan results for \"Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation\" it look like we are getting bad results for it now using Prowler version 3.8.2.\r\n\r\n\r\nIf I run a scan on an AWS IAM policy defined with the below json I get the failure -\r\n\r\n_Custom Policy arn:aws:iam::xxxxxxxxxxx:policy/app-user-policy-hertzcp-pprd allows privilege escalation using the following actions: {'iam:CreateAccessKey'}_\r\n\r\nThe below is the AWS IAM policy json that it scanned and as you can see the policy does not have 'iam:CreateAccessKey' within it :\r\n \r\n```\r\n{\r\n    \"Version\": \"2012-10-17\",\r\n    \"Statement\": [\r\n        {\r\n            \"Sid\": \"\",\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": [\r\n                \"es:List*\",\r\n                \"es:Get*\",\r\n                \"es:Describe*\"\r\n            ],\r\n            \"Resource\": \"*\"\r\n        },\r\n        {\r\n            \"Sid\": \"\",\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": \"es:*\",\r\n            \"Resource\": \"arn:aws:es:us-west-2:xxxxxxxxxxxx:domain/g-clients-infra-pprd/*\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\nWhen I used prowler version 3.4.1 it did not find/report on the above issue.\r\n\r\n\r\nAlso - \r\nProwler version 3.8.2 now reports the below policy as passing for \"Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation\"  :\r\n\r\n```\r\n{\r\n    \"Version\": \"2012-10-17\",\r\n    \"Statement\": [\r\n        {\r\n            \"Sid\": \"\",\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": \"sts:AssumeRole\",\r\n            \"Resource\": \"arn:aws:iam::*:role/xena-role\"\r\n        }\r\n    ]\r\n}\r\n```\r\n\r\nWhen a scan using prowler version 3.4.1 was run the above policy was reported as a failure for \"Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation\". \r\nI would believe that this policy should still be reported as a failure and that Prowler version 3.8.2 has issues.\r\n\r\n### Expected behavior\r\n\r\nThe first policy should pass and the second policy should fail.\r\n\r\n### Actual Result with Screenshots or Logs\r\n\r\n[prowler-output-741743798098-20230823103540.csv](https://github.com/prowler-cloud/prowler/files/12421414/prowler-output-741743798098-20230823103540.csv)\r\n\r\n\r\n### How did you install Prowler?\r\n\r\nFrom pip package (pip install prowler)\r\n\r\n### Environment Resource\r\n\r\nEKS and ran the scan locally\r\n\r\n### OS used\r\n\r\nMacOS\r\n\r\n### Prowler version\r\n\r\n3.8.2\r\n\r\n### Pip version\r\n\r\n21.1.3\r\n\r\n### Context\r\n\r\n_No response_\n", "before_files": [{"content": "from re import search\n\nfrom prowler.lib.check.models import Check, Check_Report_AWS\nfrom prowler.providers.aws.services.iam.iam_client import iam_client\n\n# Does the tool analyze both users and roles, or just one or the other? --> Everything using AttachementCount.\n# Does the tool take a principal-centric or policy-centric approach? --> Policy-centric approach.\n# Does the tool handle resource constraints? --> We don't check if the policy affects all resources or not, we check everything.\n# Does the tool consider the permissions of service roles? --> Just checks policies.\n# Does the tool handle transitive privesc paths (i.e., attack chains)? --> Not yet.\n# Does the tool handle the DENY effect as expected? --> Yes, it checks DENY's statements with Action and NotAction.\n# Does the tool handle NotAction as expected? --> Yes\n# Does the tool handle Condition constraints? --> Not yet.\n# Does the tool handle service control policy (SCP) restrictions? --> No, SCP are within Organizations AWS API.\n\n# Based on:\n# - https://bishopfox.com/blog/privilege-escalation-in-aws\n# - https://github.com/RhinoSecurityLabs/Security-Research/blob/master/tools/aws-pentest-tools/aws_escalate.py\n# - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/\n\n\nclass iam_policy_allows_privilege_escalation(Check):\n    def execute(self) -> Check_Report_AWS:\n        privilege_escalation_policies_combination = {\n            \"CreatePolicyVersion\": {\"iam:CreatePolicyVersion\"},\n            \"SetDefaultPolicyVersion\": {\"iam:SetDefaultPolicyVersion\"},\n            \"iam:PassRole\": {\"iam:PassRole\"},\n            \"PassRole+EC2\": {\n                \"iam:PassRole\",\n                \"ec2:RunInstances\",\n            },\n            \"PassRole+CreateLambda+Invoke\": {\n                \"iam:PassRole\",\n                \"lambda:CreateFunction\",\n                \"lambda:InvokeFunction\",\n            },\n            \"PassRole+CreateLambda+ExistingDynamo\": {\n                \"iam:PassRole\",\n                \"lambda:CreateFunction\",\n                \"lambda:CreateEventSourceMapping\",\n            },\n            \"PassRole+CreateLambda+NewDynamo\": {\n                \"iam:PassRole\",\n                \"lambda:CreateFunction\",\n                \"lambda:CreateEventSourceMapping\",\n                \"dynamodb:CreateTable\",\n                \"dynamodb:PutItem\",\n            },\n            \"PassRole+GlueEndpoint\": {\n                \"iam:PassRole\",\n                \"glue:CreateDevEndpoint\",\n                \"glue:GetDevEndpoint\",\n            },\n            \"PassRole+GlueEndpoints\": {\n                \"iam:PassRole\",\n                \"glue:CreateDevEndpoint\",\n                \"glue:GetDevEndpoints\",\n            },\n            \"PassRole+CloudFormation\": {\n                \"cloudformation:CreateStack\",\n                \"cloudformation:DescribeStacks\",\n            },\n            \"PassRole+DataPipeline\": {\n                \"datapipeline:CreatePipeline\",\n                \"datapipeline:PutPipelineDefinition\",\n                \"datapipeline:ActivatePipeline\",\n            },\n            \"GlueUpdateDevEndpoint\": {\"glue:UpdateDevEndpoint\"},\n            \"GlueUpdateDevEndpoints\": {\"glue:UpdateDevEndpoint\"},\n            \"lambda:UpdateFunctionCode\": {\"lambda:UpdateFunctionCode\"},\n            \"iam:CreateAccessKey\": {\"iam:CreateAccessKey\"},\n            \"iam:CreateLoginProfile\": {\"iam:CreateLoginProfile\"},\n            \"iam:UpdateLoginProfile\": {\"iam:UpdateLoginProfile\"},\n            \"iam:AttachUserPolicy\": {\"iam:AttachUserPolicy\"},\n            \"iam:AttachGroupPolicy\": {\"iam:AttachGroupPolicy\"},\n            \"iam:AttachRolePolicy\": {\"iam:AttachRolePolicy\"},\n            \"AssumeRole+AttachRolePolicy\": {\"sts:AssumeRole\", \"iam:AttachRolePolicy\"},\n            \"iam:PutGroupPolicy\": {\"iam:PutGroupPolicy\"},\n            \"iam:PutRolePolicy\": {\"iam:PutRolePolicy\"},\n            \"AssumeRole+PutRolePolicy\": {\"sts:AssumeRole\", \"iam:PutRolePolicy\"},\n            \"iam:PutUserPolicy\": {\"iam:PutUserPolicy\"},\n            \"iam:AddUserToGroup\": {\"iam:AddUserToGroup\"},\n            \"iam:UpdateAssumeRolePolicy\": {\"iam:UpdateAssumeRolePolicy\"},\n            \"AssumeRole+UpdateAssumeRolePolicy\": {\n                \"sts:AssumeRole\",\n                \"iam:UpdateAssumeRolePolicy\",\n            },\n            # TO-DO: We have to handle AssumeRole just if the resource is * and without conditions\n            # \"sts:AssumeRole\": {\"sts:AssumeRole\"},\n        }\n\n        findings = []\n\n        # Iterate over all the IAM \"Customer Managed\" policies\n        for policy in iam_client.policies:\n            if policy.type == \"Custom\":\n                report = Check_Report_AWS(self.metadata())\n                report.resource_id = policy.name\n                report.resource_arn = policy.arn\n                report.region = iam_client.region\n                report.resource_tags = policy.tags\n                report.status = \"PASS\"\n                report.status_extended = f\"Custom Policy {report.resource_arn} does not allow privilege escalation.\"\n\n                # List of policy actions\n                allowed_actions = set()\n                denied_actions = set()\n                denied_not_actions = set()\n\n                # Recover all policy actions\n                if policy.document:\n                    if not isinstance(policy.document[\"Statement\"], list):\n                        policy_statements = [policy.document[\"Statement\"]]\n                    else:\n                        policy_statements = policy.document[\"Statement\"]\n                    for statements in policy_statements:\n                        # Recover allowed actions\n                        if statements[\"Effect\"] == \"Allow\":\n                            if \"Action\" in statements:\n                                if type(statements[\"Action\"]) is str:\n                                    allowed_actions.add(statements[\"Action\"])\n                                if type(statements[\"Action\"]) is list:\n                                    allowed_actions.update(statements[\"Action\"])\n\n                        # Recover denied actions\n                        if statements[\"Effect\"] == \"Deny\":\n                            if \"Action\" in statements:\n                                if type(statements[\"Action\"]) is str:\n                                    denied_actions.add(statements[\"Action\"])\n                                if type(statements[\"Action\"]) is list:\n                                    denied_actions.update(statements[\"Action\"])\n\n                            if \"NotAction\" in statements:\n                                if type(statements[\"NotAction\"]) is str:\n                                    denied_not_actions.add(statements[\"NotAction\"])\n                                if type(statements[\"NotAction\"]) is list:\n                                    denied_not_actions.update(statements[\"NotAction\"])\n\n                    # First, we need to perform a left join with ALLOWED_ACTIONS and DENIED_ACTIONS\n                    left_actions = allowed_actions.difference(denied_actions)\n                    # Then, we need to find the DENIED_NOT_ACTIONS in LEFT_ACTIONS\n                    if denied_not_actions:\n                        privileged_actions = left_actions.intersection(\n                            denied_not_actions\n                        )\n                    # If there is no Denied Not Actions\n                    else:\n                        privileged_actions = left_actions\n\n                    # Store all the action's combinations\n                    policies_combination = set()\n\n                    for values in privilege_escalation_policies_combination.values():\n                        for val in values:\n                            val_set = set()\n                            val_set.add(val)\n                            # Look for specific api:action\n                            if privileged_actions.intersection(val_set) == val_set:\n                                policies_combination.add(val)\n                            # Look for api:*\n                            else:\n                                for permission in privileged_actions:\n                                    # Here we have to handle if the api-action is admin, so \"*\"\n                                    api_action = permission.split(\":\")\n                                    # len() == 2, so api:action\n                                    if len(api_action) == 2:\n                                        api = api_action[0]\n                                        action = api_action[1]\n                                        # Add permissions if the API is present\n                                        if action == \"*\":\n                                            if search(api, val):\n                                                policies_combination.add(val)\n\n                                    # len() == 1, so *\n                                    elif len(api_action) == 1:\n                                        api = api_action[0]\n                                        # Add permissions if the API is present\n                                        if api == \"*\":\n                                            policies_combination.add(val)\n\n                    # Check all policies combinations and see if matchs with some combo key\n                    combos = set()\n                    for (\n                        key,\n                        values,\n                    ) in privilege_escalation_policies_combination.items():\n                        intersection = policies_combination.intersection(values)\n                        if intersection == values:\n                            combos.add(key)\n\n                    if len(combos) != 0:\n                        report.status = \"FAIL\"\n                        policies_affected = \"\"\n                        for key in combos:\n                            policies_affected += (\n                                str(privilege_escalation_policies_combination[key])\n                                + \" \"\n                            )\n\n                        report.status_extended = (\n                            f\"Custom Policy {report.resource_arn} allows privilege escalation using the following actions: {policies_affected}\".rstrip()\n                            + \".\"\n                        )\n                findings.append(report)\n        return findings\n", "path": "prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py"}], "after_files": [{"content": "from prowler.lib.check.models import Check, Check_Report_AWS\nfrom prowler.providers.aws.services.iam.iam_client import iam_client\n\n# Does the tool analyze both users and roles, or just one or the other? --> Everything using AttachementCount.\n# Does the tool take a principal-centric or policy-centric approach? --> Policy-centric approach.\n# Does the tool handle resource constraints? --> We don't check if the policy affects all resources or not, we check everything.\n# Does the tool consider the permissions of service roles? --> Just checks policies.\n# Does the tool handle transitive privesc paths (i.e., attack chains)? --> Not yet.\n# Does the tool handle the DENY effect as expected? --> Yes, it checks DENY's statements with Action and NotAction.\n# Does the tool handle NotAction as expected? --> Yes\n# Does the tool handle Condition constraints? --> Not yet.\n# Does the tool handle service control policy (SCP) restrictions? --> No, SCP are within Organizations AWS API.\n\n# Based on:\n# - https://bishopfox.com/blog/privilege-escalation-in-aws\n# - https://github.com/RhinoSecurityLabs/Security-Research/blob/master/tools/aws-pentest-tools/aws_escalate.py\n# - https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/\n\n\nclass iam_policy_allows_privilege_escalation(Check):\n    def execute(self) -> Check_Report_AWS:\n        privilege_escalation_policies_combination = {\n            \"CreatePolicyVersion\": {\"iam:CreatePolicyVersion\"},\n            \"SetDefaultPolicyVersion\": {\"iam:SetDefaultPolicyVersion\"},\n            \"iam:PassRole\": {\"iam:PassRole\"},\n            \"PassRole+EC2\": {\n                \"iam:PassRole\",\n                \"ec2:RunInstances\",\n            },\n            \"PassRole+CreateLambda+Invoke\": {\n                \"iam:PassRole\",\n                \"lambda:CreateFunction\",\n                \"lambda:InvokeFunction\",\n            },\n            \"PassRole+CreateLambda+ExistingDynamo\": {\n                \"iam:PassRole\",\n                \"lambda:CreateFunction\",\n                \"lambda:CreateEventSourceMapping\",\n            },\n            \"PassRole+CreateLambda+NewDynamo\": {\n                \"iam:PassRole\",\n                \"lambda:CreateFunction\",\n                \"lambda:CreateEventSourceMapping\",\n                \"dynamodb:CreateTable\",\n                \"dynamodb:PutItem\",\n            },\n            \"PassRole+GlueEndpoint\": {\n                \"iam:PassRole\",\n                \"glue:CreateDevEndpoint\",\n                \"glue:GetDevEndpoint\",\n            },\n            \"PassRole+GlueEndpoints\": {\n                \"iam:PassRole\",\n                \"glue:CreateDevEndpoint\",\n                \"glue:GetDevEndpoints\",\n            },\n            \"PassRole+CloudFormation\": {\n                \"cloudformation:CreateStack\",\n                \"cloudformation:DescribeStacks\",\n            },\n            \"PassRole+DataPipeline\": {\n                \"datapipeline:CreatePipeline\",\n                \"datapipeline:PutPipelineDefinition\",\n                \"datapipeline:ActivatePipeline\",\n            },\n            \"GlueUpdateDevEndpoint\": {\"glue:UpdateDevEndpoint\"},\n            \"GlueUpdateDevEndpoints\": {\"glue:UpdateDevEndpoint\"},\n            \"lambda:UpdateFunctionCode\": {\"lambda:UpdateFunctionCode\"},\n            \"iam:CreateAccessKey\": {\"iam:CreateAccessKey\"},\n            \"iam:CreateLoginProfile\": {\"iam:CreateLoginProfile\"},\n            \"iam:UpdateLoginProfile\": {\"iam:UpdateLoginProfile\"},\n            \"iam:AttachUserPolicy\": {\"iam:AttachUserPolicy\"},\n            \"iam:AttachGroupPolicy\": {\"iam:AttachGroupPolicy\"},\n            \"iam:AttachRolePolicy\": {\"iam:AttachRolePolicy\"},\n            \"AssumeRole+AttachRolePolicy\": {\"sts:AssumeRole\", \"iam:AttachRolePolicy\"},\n            \"iam:PutGroupPolicy\": {\"iam:PutGroupPolicy\"},\n            \"iam:PutRolePolicy\": {\"iam:PutRolePolicy\"},\n            \"AssumeRole+PutRolePolicy\": {\"sts:AssumeRole\", \"iam:PutRolePolicy\"},\n            \"iam:PutUserPolicy\": {\"iam:PutUserPolicy\"},\n            \"iam:AddUserToGroup\": {\"iam:AddUserToGroup\"},\n            \"iam:UpdateAssumeRolePolicy\": {\"iam:UpdateAssumeRolePolicy\"},\n            \"AssumeRole+UpdateAssumeRolePolicy\": {\n                \"sts:AssumeRole\",\n                \"iam:UpdateAssumeRolePolicy\",\n            },\n            # TO-DO: We have to handle AssumeRole just if the resource is * and without conditions\n            # \"sts:AssumeRole\": {\"sts:AssumeRole\"},\n        }\n\n        findings = []\n\n        # Iterate over all the IAM \"Customer Managed\" policies\n        for policy in iam_client.policies:\n            if policy.type == \"Custom\":\n                report = Check_Report_AWS(self.metadata())\n                report.resource_id = policy.name\n                report.resource_arn = policy.arn\n                report.region = iam_client.region\n                report.resource_tags = policy.tags\n                report.status = \"PASS\"\n                report.status_extended = f\"Custom Policy {report.resource_arn} does not allow privilege escalation.\"\n\n                # List of policy actions\n                allowed_actions = set()\n                denied_actions = set()\n                denied_not_actions = set()\n\n                # Recover all policy actions\n                if policy.document:\n                    if not isinstance(policy.document[\"Statement\"], list):\n                        policy_statements = [policy.document[\"Statement\"]]\n                    else:\n                        policy_statements = policy.document[\"Statement\"]\n                    for statements in policy_statements:\n                        # Recover allowed actions\n                        if statements[\"Effect\"] == \"Allow\":\n                            if \"Action\" in statements:\n                                if type(statements[\"Action\"]) is str:\n                                    allowed_actions.add(statements[\"Action\"])\n                                if type(statements[\"Action\"]) is list:\n                                    allowed_actions.update(statements[\"Action\"])\n\n                        # Recover denied actions\n                        if statements[\"Effect\"] == \"Deny\":\n                            if \"Action\" in statements:\n                                if type(statements[\"Action\"]) is str:\n                                    denied_actions.add(statements[\"Action\"])\n                                if type(statements[\"Action\"]) is list:\n                                    denied_actions.update(statements[\"Action\"])\n\n                            if \"NotAction\" in statements:\n                                if type(statements[\"NotAction\"]) is str:\n                                    denied_not_actions.add(statements[\"NotAction\"])\n                                if type(statements[\"NotAction\"]) is list:\n                                    denied_not_actions.update(statements[\"NotAction\"])\n\n                    # First, we need to perform a left join with ALLOWED_ACTIONS and DENIED_ACTIONS\n                    left_actions = allowed_actions.difference(denied_actions)\n                    # Then, we need to find the DENIED_NOT_ACTIONS in LEFT_ACTIONS\n                    if denied_not_actions:\n                        privileged_actions = left_actions.intersection(\n                            denied_not_actions\n                        )\n                    # If there is no Denied Not Actions\n                    else:\n                        privileged_actions = left_actions\n\n                    # Store all the action's combinations\n                    policies_combination = set()\n\n                    for values in privilege_escalation_policies_combination.values():\n                        for val in values:\n                            val_set = set()\n                            val_set.add(val)\n                            # Look for specific api:action\n                            if privileged_actions.intersection(val_set) == val_set:\n                                policies_combination.add(val)\n                            # Look for api:*\n                            else:\n                                for permission in privileged_actions:\n                                    # Here we have to handle if the api-action is admin, so \"*\"\n                                    api_action = permission.split(\":\")\n                                    # len() == 2, so api:action\n                                    if len(api_action) == 2:\n                                        api = api_action[0]\n                                        action = api_action[1]\n                                        # Add permissions if the API is present\n                                        if action == \"*\":\n                                            val_api = val.split(\":\")[0]\n                                            if api == val_api:\n                                                policies_combination.add(val)\n\n                                    # len() == 1, so *\n                                    elif len(api_action) == 1:\n                                        api = api_action[0]\n                                        # Add permissions if the API is present\n                                        if api == \"*\":\n                                            policies_combination.add(val)\n\n                    # Check all policies combinations and see if matchs with some combo key\n                    combos = set()\n                    for (\n                        key,\n                        values,\n                    ) in privilege_escalation_policies_combination.items():\n                        intersection = policies_combination.intersection(values)\n                        if intersection == values:\n                            combos.add(key)\n\n                    if len(combos) != 0:\n                        report.status = \"FAIL\"\n                        policies_affected = \"\"\n                        for key in combos:\n                            policies_affected += (\n                                str(privilege_escalation_policies_combination[key])\n                                + \" \"\n                            )\n\n                        report.status_extended = (\n                            f\"Custom Policy {report.resource_arn} allows privilege escalation using the following actions: {policies_affected}\".rstrip()\n                            + \".\"\n                        )\n                findings.append(report)\n        return findings\n", "path": "prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py"}]}