Scoutsuite: Cross Account Assume Role Access support missing in Scout2

Created on 3 Jan 2018  Â·  12Comments  Â·  Source: nccgroup/ScoutSuite

I can setup my AWS EC2 instance with the role that has the permissions to assume any role it wants, as described in this post. Specifically, if I have a policy like the following:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "*"
        }
    ]
}

I can run aws cli commands with just the role_arn and external_id. But I cannot run Scout2 with a profile containing just the role_arn and external_id, since it requires the presence of aws_secret_access_key and aws_access_key_id. Some shallow surfing of the source code tells me that this line seems to be the problem. ( This line also seems related )

Scout2 should have similar behavior as aws cli in this case, i.e. it should be okay without aws_secret_access_key.

bug component-provider-aws

All 12 comments

This Line (in the test suite) also assumes the access key is used. I've patched locally to look like this:

        if 'AWS_PROFILE' in os.environ:
            self.profile_name = os.environ['AWS_PROFILE']
        else:
            self.profile_name = 'travislike' if creds['AccessKeyId'] == None else None

But that's horrible. :-)

Thanks !
This seems like a good solution. But I'm using multiple profiles, and would need to keep changing the env_var to match the one I need, hence need Scout2 to generalize well.

The fix needs to go into opinel but it should be an easy one.

I use profiles and roles a lot, but never via environment variables. Can you paste how you'd expect to call the CLI exactly so that I can make sure the call to read_creds() behaves similarly?

I use direnv, so I don't tend to need to fiddle with per-application settings. Highly recommended!

Adding some more details. Pardon me @l01cd3v - I know your question is precise, but I wanted to share all the information I have so that there is no confusion here.

Here is an example of a credentials file that works for both aws cli and Scout2, as expected:

[profile0]
aws_region_name = us-west-2
aws_secret_access_key = asdfegerblahblahblahsomemore
aws_access_key_id = AKIASOMEKEYSTRING
aws_role_arn = arn:aws:iam::11111111111:role/my-awesome-role
aws_external_id = myextID

And by "works", I mean I can run the following commands easily:

  • Scout2 --no-browser --services vpc s3 ec2 iam --profile profile0
  • aws ec2 describe-instances --profile profile0

On the other hand, if my credentials file looks like the following, Scout2 fails (with exit code 42) but aws cli succeeds(using the same commands).

[profile0]
aws_region_name = us-west-2
aws_role_arn = arn:aws:iam::11111111111:role/my-awesome-role
aws_external_id = myextID

The reason cli works is that the ec2 instance where I'm running these commands has a role attached to it with a policy that grants it permissions to assume any role (as described in my initial question).
Thus, I would expect Scout2 to work as well.

Edit: Accidentally hit close and comment instead of just comment.
Edit2: Thanks @brunns for sharing direnv, it seems super-useful!

Scout2 already supports cross account, but support for the external ID was lacking; Also, I believe it failed in your case because the role-based profiles are defined in the .aws/credentials file while the code only looks for these in the .aws/config file.

I created https://github.com/nccgroup/opinel/issues/24 to track changes.

I believe this should work now.

You are correct @l01cd3v . On upgrading opinel, it worked just fine with the external_id; your fix was it. Thanks a lot!

Sorry @l01cd3v , red-herring! I think that this fix wasn't enough. The reason it worked locally with this fix was that I had this line commented out. If I don't provide an AccessKeyId, and uncomment the said line(i.e the way it is), it still doesn't work.

I'll have to spin up a test instance w/ a role that can assume other roles and give it a try.

Just FYI, the check for the access_key_id in Scout2 is legit and will remain no matter what. This is because when you use a role (via ec2 instance or assume-role), you end up receiving a short-lived access_key_id / secret / session_token combo. I need to look into why read_creds won't work in this scenario.

I tried using this and hit a couple of problems.

Sometimes the config is aws_external_id some as external_id. Awscli uses the latter, but scout and anything else that uses opinel uses the former.

(If you do get a working configuration, the temporary credentials can be cached by awscli. This is good behaviour, but can be confusing for two consecutive tests.)

Scout2 has some code to parse cross account roles and it does work but it is not compatible with the awscli.

in ~/.aws/config I have

[yyy]
region=us-west-2
role_arn=arn:aws:iam::123456789012:role/cross_role_test
external_id=666
aws_external_id=666
source_profile=xxx

and in ~/.aws/credentials I have

[xxx]
region=us-west-2
aws_access_key_id=AIHFBAFHBAIHBFIAHFBIA
aws_secret_access_key=aljehrbfaiebrfiaebrfipebr

[zzz]
region=us-west-2
aws_access_key_id=AIHFBAFHBAIHBFIAHFBIA
aws_secret_access_key=aljehrbfaiebrfiaebrfipebr
region=us-west-2
role_arn=arn:aws:iam::123456789012:role/cross_role_test
external_id=666
source_profile=zzz

So the following commands work

aws --profile=zzz  ec2 describe-instances —debug
Scout2 --no-browser --force --services ec2 --profile yyy

but
Scout2 --no-browser --force --services ec2 —profile zzz
goes into a stack death loop and
aws --profile=yyy ec2 describe-instances —debug
doesn’t try the role.
So it is possible to write a config for scout2 but it is incompatible with one for awscli.

Probably a worse issue is that we have no way of passing in these parameters in the environment.
To use this from a script we would need to go back to overwriting the config for each set of credentials, which is not convenient.

I reported a ticket in opinel (https://github.com/nccgroup/opinel/issues/26) and fix in https://github.com/nccgroup/opinel/pull/27.

Currently all the travis tests fail, but I don’t think this is because of my code change.

I would appreciate some pointers about how to get that fix into opinel.

Closing this issue as we no longer rely on opinel for AWS authentication. You should now setup authentication as per usual. If you pass a named profile to scout (--profile argument) then that's what scout will use, otherwise it will use boto's standard evaluation logic (https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html).

See https://github.com/nccgroup/ScoutSuite/issues/9 for change.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

x4v13r64 picture x4v13r64  Â·  8Comments

heydonovan picture heydonovan  Â·  7Comments

imsky picture imsky  Â·  4Comments

alitheg picture alitheg  Â·  8Comments

x4v13r64 picture x4v13r64  Â·  8Comments