prowler-cloud / prowler

Prowler is an Open Source Security tool for AWS, Azure, GCP and Kubernetes to do security assessments, audits, incident response, compliance, continuous monitoring, hardening and forensics readiness. Includes CIS, NIST 800, NIST CSF, CISA, FedRAMP, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, Well-Architected Security, ENS and more
https://prowler.com
Apache License 2.0
10.78k stars 1.54k forks source link

[Bug]: iam_policy_allows_privilege_escalation passes when it should fail - regarding `iam:PassRole` #2636

Closed ernievd closed 1 year ago

ernievd commented 1 year ago

Steps to Reproduce

I run a prowler scan to check my AWS IAM policies. I run the following command - prowler aws -p ernie -c iam_policy_allows_privilege_escalation .

My AWS policy is as follows -

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::11223344:role/ecs",
        }
    ]
}

The scan fails with the message - Custom Policy arn:aws:iam::421474263769:policy/ernie-test-account-admin-minimized allows privilege escalation using the following actions: {'iam:PassRole'}

Strangely, if I update the same IAM policy to be the following and I run the same exact prowler scan then the scan will pass on the policy. I think that prowler has a bug because it should not pass with the addition of "Action": "account:GetAccountInformation"-

{
    "Statement": [
        {
            "Action": "iam:PassRole",
            "Effect": "Allow",
            "Resource": "arn:aws:iam::11223344:role/ecs"
        },
        {
            "Action": "account:GetAccountInformation",
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}

Also, I want to get the original policy without the "Action": "account:GetAccountInformation" addition to pass. From my research, If I update the policy with the condition show below I would think that it would then pass the prowler scan, however it still fails with the message - Custom Policy arn:aws:iam::421474263769:policy/ernie-test-account-admin-minimized allows privilege escalation using the following actions: {'iam:PassRole'} :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::11223344:role/ecs",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "ecs.amazonaws.com",
                    "aws:SourceAccount": "11223344"
                }
            }
        }
    ]
}

Expected behavior

The prowler scan should fail with the following policy - which it does :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::11223344:role/ecs",
        }
    ]
}

The prowler scan should fail with the following policy - which it does NOT :

{
    "Statement": [
        {
            "Action": "iam:PassRole",
            "Effect": "Allow",
            "Resource": "arn:aws:iam::11223344:role/ecs"
        },
        {
            "Action": "account:GetAccountInformation",
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}

I think that the prowler scan should pass with the following policy - which it still fails :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::11223344:role/ecs",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "ecs.amazonaws.com",
                    "aws:SourceAccount": "11223344"
                }
            }
        }
    ]
}

Actual Result with Screenshots or Logs

2023-07-28T09:50:18.064060;prowler-aws-iam_policy_allows_privilege_escalation-XXXX-us-east-1-ernie-test-account-admin-minimized;aws;iam_policy_allows_privilege_escalation;Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation;Software and Configuration Checks,Industry and Regulatory Standards,CIS AWS Foundations Benchmark;FAIL;Custom Policy arn:aws:iam::XXXX:policy/ernie-test-account-admin-minimized allows privilege escalation using the following actions: {'iam:PassRole'};iam;;high;AwsIamPolicy;;;Ensure no Customer Managed IAM policies allow actions that may lead into Privilege Escalation;Users with some IAM permissions are allowed to elevate their privileges up to administrator rights.;;Grant usage permission on a per-resource basis and applying least privilege principle.;https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege;;;;;AWS-Well-Architected-Framework-Security-Pillar: SEC02-BP06 | ENS-RD2022: op.acc.4.aws.iam.1, op.acc.4.aws.iam.2, op.exp.8.r4.aws.ct.8;;;;CAF Security Epic: IAM;ernie;XXXX;;;;;;us-east-1;ernie-test-account-admin-minimized;arn:aws:iam::XXXX:policy/ernie-test-account-admin-minimized

How did you install Prowler?

From brew (brew install prowler)

Environment Resource

  1. Workstation

OS used

  1. MacOS

Prowler version

Prowler 3.6.1

Pip version

I do not have pip installed

Context

Besides pointing out the bug I think I found, I am also hoping you can suggest a way to get the scan to pass using the policy shown below. Or is using iam:passRole just to much of a risk and it will always fail with using it and we have to accept that.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::11223344:role/ecs",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "ecs.amazonaws.com",
                    "aws:SourceAccount": "11223344"
                }
            }
        }
    ]
}
Fennerr commented 1 year ago

Privilege escalation is highly dependent on the context. If the ecs role has more permissions than what the user has, and they can control what the ecs task does (what is running in the docker container), then this does introduce a priv esc vector.

The code for the check can be found here https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/aws/services/iam/iam_policy_allows_privilege_escalation/iam_policy_allows_privilege_escalation.py

As much as i love prowler, this is a very rudimentary check, and it just looks for possible actions that might result in a privilege escalation path.

I highly recommend pmapper https://github.com/nccgroup/PMapper

It does a better job at determining priv esc paths by creating a graph of all the principals and policies within an account, and then determining if there are paths to admin principals. Check out the wrongadmin and privesc * preset queries

Fennerr commented 1 year ago

But nice catch, it does seem like there is a bug with the check with what you have detailed about it passing if you have 2 statements in the policy

Fennerr commented 1 year ago

For another example on how this check falls short, take a look at these priv esc paths https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/

Some would require that you can update a policy that is applied to your principal, others might require that you can create a resource AND pass a role to it. This check only checks for if you have one of the relevant permissions, not if you have the correct combination to exploit a certain path (ie can you update your own policy, or can you update an iam policy that isnt attached to anything)

jfagoagas commented 1 year ago

The check iam_policy_allows_privilege_escalation is not accurate and we need to modify their logic, so right now this check can produce false positives/negatives.

I think this PR is related too https://github.com/prowler-cloud/prowler/issues/2220

Fennerr commented 1 year ago

@jfagoagas it's related, but there also seems to be bug that @ernievd has found with the logic (it doesnt pick up on the iam:PassRole action when there is multiple statements in the policy)

ernievd commented 1 year ago

The below policy also fails theiam_policy_allows_privilege_escalation test.

Is this failing because of the bug mentioned above or should this indeed pass? If it is a failure can you give an example of how to update this to make it properly pass?

Sorry but unfamiliar with some of this.

{
    "Statement": [
        {
            "Sid": "AssumeGantryRoles",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::112233445566:role/gantry-qa-company-specificrole"
        }
    ],
    "Version": "2012-10-17"
}
jfagoagas commented 1 year ago

Hi @ernievd @roisec I'm working on a fix right now. Could you please check it again with the branch PRWLR-1969-aws-iam-policy-allows-privilege-escalation-check-are-not-accurate-2220?

Thanks!

ernievd commented 1 year ago

I installed an ran it. It came up as version 3.7.2 It appears as if is is not outputting everything it finds in the files. It states that there are 6 passed and 3 failed yet the logs only shows one record. And before i only had the one failure from what i showed above and now it is showing multiple failures. I am not sure what should be a pass or a fail myself.

Should this pass of fail -


{
    "Statement": [
        {
            "Sid": "AssumeGantryRoles",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::112233445566:role/gantry-qa-company-specificrole"
        }
    ],
    "Version": "2012-10-17"
}

prowler-output-421474263769-20230801075613.csv

Fennerr commented 1 year ago

@ernievd in terms of the logic in it's current state, the check will fail if any of the following actions exist within this array:

privilege_escalation_iam_actions = {
            "iam:AttachGroupPolicy",
            "iam:SetDefaultPolicyVersion2",
            "iam:AddUserToGroup",
            "iam:AttachRolePolicy",
            "iam:AttachUserPolicy",
            "iam:CreateAccessKey",
            "iam:CreatePolicyVersion",
            "iam:CreateLoginProfile",
            "iam:PassRole",
            "iam:PutGroupPolicy",
            "iam:PutRolePolicy",
            "iam:PutUserPolicy",
            "iam:SetDefaultPolicyVersion",
            "iam:UpdateAssumeRolePolicy",
            "iam:UpdateLoginProfile",
            "iam:*",
            "sts:AssumeRole",
            "sts:*",
            "ec2:RunInstances",
            "ec2:*",
            "lambda:CreateEventSourceMapping",
            "lambda:CreateFunction",
            "lambda:InvokeFunction",
            "lambda:UpdateFunctionCode",
            "lambda:*",
            "dynamodb:CreateTable",
            "dynamodb:PutItem",
            "dynamodb:*",
            "glue:CreateDevEndpoint",
            "glue:GetDevEndpoint",
            "glue:GetDevEndpoints",
            "glue:UpdateDevEndpoint",
            "glue:*",
            "cloudformation:CreateStack",
            "cloudformation:DescribeStacks",
            "cloudformation:*",
            "datapipeline:CreatePipeline",
            "datapipeline:PutPipelineDefinition",
            "datapipeline:ActivatePipeline",
            "datapipeline:*",
        }

As @jfagoagas mentioned:

The check iam_policy_allows_privilege_escalation is not accurate and we need to modify their logic, so right now this check can produce false positives/negatives.

jfagoagas commented 1 year ago

@Fennerr this only applies for the latest version, there is a fix in this branch PRWLR-1969-aws-iam-policy-allows-privilege-escalation-check-are-not-accurate-2220.

Pleaase @ernievd @Fennerr give it a look if you get a chance. Thanks!

ernievd commented 1 year ago

Not sure what i am doing wrong - I changed to the branch you specify yet it comes up as version 3.7.2

Also, now when I run it i get an error. See attached screenshot

Screenshot 2023-08-01 at 10 33 45 AM
jfagoagas commented 1 year ago

Not sure what i am doing wrong - I changed to the branch you specify yet it comes up as version 3.7.2

Also, now when I run it i get an error.

That's strange but surely it's related with your environment and dependencies because it's saying that you don't have the colorama module. Did you follow the Github install explained here https://docs.prowler.cloud/en/latest/#installation?

ernievd commented 1 year ago

I followed the from github instructions after I cloned and switched to the branch you mentioned - https://github.com/prowler-cloud/prowler/#from-github

I did get it to work but had to jump through some hoops - see image. It still states on 3.7.2 yet you can see i am on the branch you specified and also only gives the utput for one finding whne it states there should be 10 - see attached log.

Screenshot 2023-08-01 at 10 58 04 AM

/Users/vanduyer/prowler/test-branch-prowler-install/prowler/output/prowler-output-421474263769-20230801105608.csv

jfagoagas commented 1 year ago

That's good but per your screenshot Prowler is generating 9 findings for this check, 3 FAIL and 6 PASS, can you execute it with the --verbose option to see the results?

ernievd commented 1 year ago

I added --verbose yet it looks the same - I only see one output yet it reports 3 failed and 6 passed.

Should it be stating version 3.7.2 withe the branch you had me use?

Screenshot 2023-08-01 at 12 07 31 PM

prowler-output-421474263769-20230801120517.csv

jfagoagas commented 1 year ago

Hi @ernievd, could you execute it again? We had a bug in the outputs library, now the check should work as expected.

ernievd commented 1 year ago

I assume in the same branch?

jfagoagas commented 1 year ago

I assume in the same branch?

Yes!

ernievd commented 1 year ago

So it does seem to have everything in the logs.

Can you explain to me why this policy fails and a suggestion on how to fix it - or is this not a real failure? Still learning about all this stuff!

{
    "Statement": [
        {
            "Sid": "AssumeGantryRoles",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::421474263769:instance-profile/ernie-allow-es-write-to-restore-role"
        }
    ],
    "Version": "2012-10-17"
}

Fails for - Custom Policy arn:aws:iam::421474263769:policy/ernie-test-account-admin-minimized allows privilege escalation using the following actions: {'sts:AssumeRole'}

prowler-output-421474263769-20230802081744.csv

jfagoagas commented 1 year ago

Hi @ernievd, in this case your policy could allow a Principal to privilege escalation since you can assume a role in your account and maybe that role has more privileges than the ones assigned to the Principal. In this case a more manual solution will be needed because it'll be necessary to check what are the permissions allowed in the role that can be assumed.

ernievd commented 1 year ago

could you give an example?

jfagoagas commented 1 year ago

I think it depends on your environment, sometimes some Prowler's FAILS are not accurate based on how your environment is built. For those scenarios you can use the Allowlist feature, see more here in the Prowler documentation https://docs.prowler.cloud/en/latest/tutorials/allowlist/.