As IAM is taking its place as the main security mechanism in the cloud, we hear about more security issues related to it. Often, they are related to a wrong use of this mechanism (IAM). Using generic permissions, too broad permissions or an overly-trusting cloud provider can leave our infrastructure and data vulnerable to unwanted actions and leakage.
The trivial example would be using the Admin permissions. In accounts protected by Solvo, scans show that 89% of Admin permissions are used with no real need, and can easily be replaced with a well-configured permission, enabling access to only the necessary assets and actions.
AWS Security and Permission Audits
If you want to do a good audit or clean-up of your security permissions, don’t settle for removing only admin permission. There are plenty of other, less trivial but just as risky permissions that are often granted in AWS accounts. Here are a few examples of those permissions, why they are risky and how to check if they are granted unintentionally in your account.
To do that, we used Solvo’s IAMagnifier. You can use the free version of the tool right here and audit your account the same way we did.
AssumeRole is one of the core ideas behind the IAM mechanism. It lets identities inside or outside our organization use Roles to access different resources. It saves us from managing long lists of users and identities, setting their usernames and passwords, invoking or revoking them, and keeping track of dynamic changes like new team members, new 3rd parties we’re using etc.
AssumeRole enables us to give access, and hopefully restrict or remove it easily. This action belongs to STS – the Security Token Service, from which we ask for these temporary credentials. We obviously want to be aware and restrict who can assume a role, and thus to prevent the impersonation (or imassetation, pretending to be a specific asset with different permission).
By using Solvo we can tell there are two external accounts (starting with 01 and 91) that can assume a role in this account. For this example, let’s look at the account starting with 01. It has a Developer role that has an Administrator policy attached. This means that while the external account can assume the Developer role, this IAM architecture enables it to assume any other role, while it’s under the Developer role. One of the reasons why IAM is so difficult to understand, is those hidden permissions.
In a similar way we can identify other cloud assets with different roles and policies, enabling them to assume roles freely.
This powerful permission means that whoever has it, can assign permissions to other entities in the account. This is actually a “Best Practice” for offensive hackers, for privilege escalation. We should use it to make sure principals are only granting specific permissions, and also to make sure that high privileges are denied from attachment.
In this Solvo assessment, we can see that several AWS services in our Demo account can pass role, by using AWS managed policies. Generally speaking, using a service-linked role is a good practice, but we need to make sure what’s inside and who got assigned with it.
In this example, the inner two service-linked roles can actually pass the “iam:*” which is quite risky. The top and bottom roles are not connected to the “iam:*” node, but instead are connected directly to the relevant role, and this proves a more tight security configuration, just the way we like it to be. Let’s look at another example:
In this example, you can see that several lambda functions can pass roles. On the top side of the map, there are 8 Lambda functions connected through different service-roles to the DynamoDBFullAccess managed policy, followed by an “iam:*” node. That means that by using this AWS managed permission, you are actually enabling the sensitive action in your account. Managed policies are like a box of chocolate.
Both AWS managed policies we see on the screen (AdministratorAccess and AmazonDynamoDBFullAccess) lead us to a node that shows “iam:*” which means that by using these policies, we have enabled, under certain conditions, to passRole.
If you want to get access to an S3 Bucket, and you’re not a Root user (hopefully you’re not), you need the PutBucketPolicy permission. Since S3 bucket is a very popular storage service for PII and other crown jewels, you probably don’t want different entities in your account to be able to make changes to bucket policies, and by that exposing them to data leakage or manipulation.
In this Solvo query, we looked for entities that can run the S3:PutBucketPolicy action. We can see an external account, an ECS and a Lambda function have permissions for PutBucketPolicy coming from admin policies attached to their roles. If this is good or bad, it’s up for the application owner to say if these entities need such a permission, but the IAMagnifier makes it easy to review and look for this kind of action, and easily detect the unnecessary actions.
One other thing we learn from the map is that there’s an Anonymous entity that has access to a specific bucket. If the Anonymous node scares you, that’s only because it means that the principal that has access to the Bucket is actually “*” everyone. So you are right to be scared.
CloudTrail is the API logging service of AWS. We also look at it as a mandatory security tool. Enabling us to monitor, detect anomalies and investigate different events. You should also know that it is a hacking best practice to meddle, manipulate and delete logs of different monitoring and security products, to make the life of the security and IR engineers a little harder.
Of course, as a hacker you don’t want to stop logging altogether because that might set some alarms, but taking out specific logs that have to do with the nasty stuff that you’re doing might be a “better” idea. This is exactly what the PutEvenSelectors permission lets us do. And you don’t want to enable that.
In this Solvo query we see that a Lambda Function and an ECS task have admin access using an AWS managed policy. In addition to that, another account is entitled to the PutEventSelectors action through two different paths. One is a Developer role, that has a customer managed policy that contains “Resource:*”, in addition to an Administrator role, that has an AWS managed Admin policy attached (needless to say it has the “Resource:*”).
So in this case, both the AWS managed policy and the customer managed one, enabled us to run a risky action and that’s why we can add event selectors on CloudTrail and help hackers cover their traces.
The SSM, or the AWS System Manager, enables you to query and modify different aspects of your infrastructure. The GetParameters action allows you to retrieve different pieces of information about our cloud infrastructure and configuration, and this information may contain API keys and other secrets that are stored as parameters. Again, a classic reconnaissance action.
In this Solvo query above we can actually see a very interesting scenario. There are 4 Lambda functions that have access to 5 different parameters. Note that two of the Lambdas (in the highlighted paths below) have access to ssm:*, which contains those 5 parameters (and all other parameters we have).
That excessive permissions was granted by AWS managed policy and by an inline policy that were not least-privileged.
On the other hand, see below another highlighted route from the same query, showing a Lambda function using a Solvo policy.
You can see how it looks, when the policy is well configured, and grants access only to the necessary parameters.
To sum up, we always aspire for a least-privileged cloud account, but some excessive actions are riskier than others. In this blog we described a few of the actions that are sometimes necessary to run, but always with the right IAM policy, that will make sure it’s only used for what you intended.
If you want to check your account, and easily detect risky actions and which assets are at risk, get FREE IAMagnifier access right here.