Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does AWSPX false negative on multi policy privesc paths? #47

Open
sethsec opened this issue Jul 14, 2021 · 2 comments
Open

Does AWSPX false negative on multi policy privesc paths? #47

sethsec opened this issue Jul 14, 2021 · 2 comments
Assignees
Labels
enhancement New feature or request

Comments

@sethsec
Copy link

sethsec commented Jul 14, 2021

If i am not mistaken, ASWPX takes a policy-centric approach to evaluating privesc paths as opposed to a principal-centric approach?. Is that right?

For example, I have a role that has two policies applied. One policy allows iam:passRole on resource:, and the other allows ec2:RunInstances on resource:. I can exploit the classic CreateInstanceWithExistingProfile privesc because the role has all the permissions it needs.

However this does not show up in AWSPX, and I'm really just asking if this is expected or unexpected on your end. If this is unexpected (a bug), I'm happy to provide more details on the roles, policies, instance, profiles, etc. that are involved. If expected, I suggest adding this to the FAQ like the note you have about not processing DENY actions.

Thanks!

Also, I gotta say that I really love AWSPX. Between the visualizations and the exploitation guidance, your tool really helped me put some major IAM privesc pieces together when I was ramping up in this area!

@beatro0t
Copy link
Collaborator

Hi @sethsec, that's absolutely fantastic to hear!

Your assumption is spot on! The reason this attack is not identified is because we have yet to add a definition for it. In short, all attacks are defined in a dictionary which get translated to cypher before being run against the graph.:

https://github.com/FSecureLABS/awspx/blob/9f71ef23ab26cc4fc6b61cdfb2e8d6beb7d95742/lib/aws/attacks.py#L10

In theory this dictionary is supposed to make expressing these attacks far simpler by avoiding writing a cypher equivalent. In reality, this is seldom the case and the translation logic itself ends up requiring some updating.

I've been giving this process an bit of overhaul lately to accommodate a bunch of new attacks we know we can't presently support. This is a great example to incorporate so thank you very much for sharing

If you're keen to grab the latest attack logic (absent new definitions and proper testing) you can checkout the develop branch. I'm going to continue fiddling and figure out how to express this attack. I had a quick go at it and it looks like life would be a lot easier if we upgraded to neo4j 4 (but a recall this not being so straight forward so need to take a proper look) so we can make use of existential subqueries (presently commented out). I also need to tinker with translation a bit since this attack isn't your typical create action but affects Generic resources (resources that don't exist already but could) and likely need to add a couple new options for this to work

    "CreateInstanceWithExistingProfile": {

        "Description": "Launch a new EC2 instance that is associated with an existing instance profile:",

        "Options": {
            "CreateAction": True,
            "Transitive": False
        },

        "Commands": [
            "aws ec2 run-instances"
            "   --count 1"
            "   --iam-instance-profile Name=${AWS::Iam::InstanceProfile}"
            "   --instance-type t2.micro"
            "   --image-id $AmiId",
        ],

        "Attack": {

            "Requires": [
                "ec2:RunInstances"
            ],

            "Affects": "AWS::Ec2::Instance",

            "Grants": "AWS::Iam::InstanceProfile",

            # "Cypher": [
            #     "EXISTS{ MATCH (${})-[:D|ACTION{Name:'iam:PassRole'}]->(role:`AWS::Iam::Role`)<-[:TRANSITIVE]-(${AWS::Iam::InstanceProfile}),", 
            #     "   (role)-[:TRUSTS]->(:`AWS::Domain`{Name: 'ec2.amazonaws.com'})", 
            #     "}",
                
            # ]

        }

I'll get back to you properly once I have something that vaguely works and we can take it from there!

@beatro0t beatro0t added the enhancement New feature or request label Jul 15, 2021
@beatro0t beatro0t self-assigned this Jul 15, 2021
@beatro0t
Copy link
Collaborator

Sorry for the delay @sethsec 🙈 I've just pushed a new release that includes neo4j 4 support. This means we can now make use of things like existential subqueries in attack definitions. I still need to do some thorough testing so have excluded additional attacks (such as CreateInstanceWithExistingProfile) from this release.

If you want to test it out yourself, you can add the following definition:


    "CreateInstanceWithProfile": {

        "Description": "Launch a new EC2 instance that is associated with a target instance profile:",

        "Options": {
            "Transitive": True,
            "AffectsGeneric": True
        },

        "Commands": [
            "aws ec2 run-instances"
            "   --count 1"
            "   --iam-instance-profile Name=${AWS::Iam::InstanceProfile}"
            "   --instance-type t2.micro"
            "   --image-id $AmiId",
        ],

        "Attack": {

            "Requires": [
                "ec2:RunInstances"
            ],

            "Affects": "AWS::Ec2::Instance",

            "Grants": "AWS::Iam::InstanceProfile",

            "Cypher": [
                "EXISTS{ MATCH (${})-[:D|ACTION{Name:'iam:PassRole'}]->(role:`AWS::Iam::Role`)<-[:TRANSITIVE]-(${AWS::Iam::InstanceProfile}),",
                "   (role)-[:TRUSTS]->(:`AWS::Domain`{Name: 'ec2.amazonaws.com'})",
                "}",

            ]

        }
    },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants