Understanding Suspicious Updates to AWS Managed Policies

by

As you stand knee deep in the water watching waves form, you set your sights on the perfect one to ride into shore. "This is it!", you think. "It'll carry me to shore and I'll have fun along the way". You swim out, think you have your timing perfect, and all of a sudden the wave consumes you. It puts you through a spin cycle like you're in a washing machine and all you want to do is escape from the riptide. 

That feeling of getting caught in the riptide describes the current environment of a security professional. Log4j has every team scrambling to identify if their organization is impacted and if they are, remediate those findings. 

As such the security team at JupiterOne is on high alert to protect our customers and employees. We were on top of the recent suspicious update to an AWS managed policy, AWSServiceRoleForSupport, on December 22nd that was dangerous and unable to defend against. The update included the addition of the `s3:getObject` permission to this policy. The core issue of this change is that the AWSServiceRoleForSupport role is automatically created for you when you create an AWS account, you cannot remove the role, and the role has wildcard (*) access to the resources it has permissions for. With the addition of this permission, the AWSServiceRoleForSupport role can retrieve any unencrypted file in any of your buckets and you have no control over this. You read that correctly. Any unencrypted file. Any bucket. If you have S3 buckets and CloudTrail data events enabled, take a moment to review your CloudTrail data events to review for any suspicious behavior. 

When events like these happen, wouldn't it be great if it were easy for you to know about them and how they impact your own organization? This is one of the many instances where leveraging a CAASM provider like JupiterOne provides significant value over trying to create and manage your own. Events like these can produce automated alerts, bringing awareness to your team at the snap of your fingers. In fact, this is exactly how JupiterOne itself was able to identify that this happened within seconds of the change being implemented.

Let me show you how...

It starts with a JupiterOne alert. As a security team, we are able to continuously monitor all changes to AWS managed policies with JupiterOne alerts. When one of them changes, we get a slack message so that we know we should then spend time reviewing what changed and how it impacts our organization. 

Here's the slack message we received when the policy changed:

1-j1-alert

Because we have the alert automated, it now becomes simple to know that there was a change. No more setting up RSS feeds and deploying monitoring infrastructure - having the JupiterOne AWS integration and setting up an alert is all we need! Knowing that there was a change is only one part of the equation though. It's critical for our security team to understand what this change means to our organization. Thankfully for us, clicking on the link in the slack alert takes us right into the platform where we can begin to identify what changed.

When we land in JupiterOne, we're met with the policy that was mentioned in our slack alert.

2-alert-query-policy-table

Now that we're in JupiterOne, what we're looking for is what specifically changed. We can discover this by adding a RETURN statement to our JupiterOne query that includes properties on the relationship.

Now our JupiterOne query looks something like this:

FIND aws_iam_policy
  WITH vendorManaged=true
  AND updatedOn > date(your_teams_last_reviewed_date)
  AND accountId = 'your_aws_account_id'
  THAT ALLOWS >> as allow_relationship * as impacted_service
WHERE allow_relationship._beginOn > date(your_teams_last_reviewed_date)
RETURN impacted_service.name, allow_relationship.actions

This query translates to: We're looking for an AWS managed IAM policy that was last updated after our last review date and is in a specific AWS account that allows some permission that was altered after our last review date.

3-alert-query-table

Wow! Now we know exactly what permissions each service has and as a security team, we'll review and discuss each one together. This is when we stumbled upon the aforementioned, notorious permission `s3:getObject`. Unable to do anything to remediate this issue, we closely monitored our CloudTrail data events for any suspicious activity and we encourage you to do the same!

How do I get this working for my own organization?

We have great alert documentation that I suggest you utilize to set up an alert for this specific example. When you're ready to create the alert, we have created a template you can use to seamlessly add this to your own organization.

What if I could've done something?

This type of behavior where you feel like the carpet is being pulled out from underneath your feet happens all the time with AWS managed policies. In general, we advise against using them; but, we know that sometimes they are applied to roles for convenience. The reason this is dangerous is because it leaves your infrastructure in an unpredictable state. One moment your AWS managed policy could have a specific read permission, the next it does not! We should strive towards a world where software is predictable and securable, not the opposite and using AWS managed policies does not help us get there.

Imagine this scenario: You're the security professional at an organization where you have hundreds of developers pushing thousands of commits, and it just so happens that in one of those commits a developer includes an AWS managed policy. Reasonably, the security team doesn't have the bandwidth to monitor every pull request and as a result, this change ends up in your deployed infrastructure. 

As a security team, it is advantageous for us to know when AWS managed policies are used, how they can be used, and all of the different services they can impact in our environment. Discovering all of these insights is easy with JupiterOne and it's how the security team at JupiterOne ensures we have tight, least-privileged IAM management. 

Let's build a JupiterOne query together to show you how easy solving this difficult problem with JupiterOne is.

How about we start with something basic?

FIND aws_iam_policy
WITH vendorManaged=true
RETURN TREE


Find all AWS policies that are managed by the vendor (i.e. AWS managed policies).

4-vendor-policies

Great! We have a starting point. But, wait. Policies themselves aren't dangerous. It is when they are assigned to a role and someone either is assigned or assumed that role! Can we see that in the graph? Absolutely. 

Because of how the query language works, we'll alter the query to begin with a role so we can easily traverse the graph.

FIND aws_iam_role
THAT ASSIGNED >> aws_iam_policy
WITH vendorManaged=true
RETURN TREE


5-iam-roles

Sweet. Now we have a… oh my. What is that? There is a role called `ADangerousRole` in our environment and it has `AdministratorAccess`. This is not good at all. If someone uses that role, we are in big trouble. How can we discover how someone can get into that role? Let's modify the query a bit.

FIND *
WITH (name !='iam' and _class != 'Service')
  THAT RELATES TO >> aws_iam_role
  WITH name='ADangerousRole'
THAT ASSIGNED >> aws_iam_policy
WITH vendorManaged=true
RETURN TREE


We need to traverse "backwards" once more in our query to identify how someone can utilize this role. We do this by adding a wildcard (*) after our FIND to search for any entity and a WITH clause to exclude the IAM service because we're not interested in that entity for this scenario. We'll use `THAT RELATES TO` in order to find any relationship this wildcard entity might have with this role.

6-attack-vectors

Oh no. We have two roles that can assume the role of `ADangerousRole`. Now that we understand how this role can be utilized, we need to understand what the AWS managed policy does to determine our complete blast radius. In other words, what services does this role have access to?

FIND *
WITH (name !='iam' and _class != 'Service')
  THAT RELATES TO >> aws_iam_role
WITH name='ADangerousRole'
 THAT ASSIGNED >> aws_iam_policy
WITH vendorManaged=true
 THAT ALLOWS >> *
RETURN TREE

We'll add a THAT ALLOWS >> * clause to the end of the query in order to give all of us the services impacted by this policy.

7-policy-allows

This is really not good. Our dangerous role is assigned the AdministratorAccess AWS managed policy and it has full control over our production account. We need to raise this as a concern to our organization, triage this, and ultimately remediate it so we no longer have this control in our environment. Because we have all of these data points and their relationships, we can easily start triaging this and all other instances of this using the table view and slightly adjusted query with aliases and an organized return statement like so:

FIND *
WITH (name !='iam' and _class != 'Service')
AS entrypoint
  THAT RELATES TO >> aws_iam_role
  AS vulnerable_role
THAT ASSIGNED >> aws_iam_policy
WITH vendorManaged=true
AS managed_policy
THAT ALLOWS >> AS allow_relationship *
RETURN
  entrypoint.name as Entrypoint,
  vulnerable_role.name as ‘Vulnerable Role',
  managed_policy.name as ‘Managed Policy Name',
  count(allow_relationship) as ‘Number Of Relationships'

That gives us a nice looking table to easily triage these issues:

8-remediation-table

Conclusion

This is just one of many use-cases the security team at JupiterOne has for using JupiterOne. It enables us to stay ahead of these ostensibly tiny issues that can creep up on you if you aren't paying attention. Don't let AWS managed policies scare you. With JupiterOne, you're easily able to know more, fear less, and never get caught in the riptide. 

Related Articles

  

 The 3 Biggest Challenges of Cyber Asset Management and How to Solve Them
December 14, 2021   

2021-12-15 CAASM Definitive Guide - JupiterOne

 The Definitive Guide to Cyber Asset Attack Surface Management (CAASM)
December 13, 2021
   

CAASM Build vs Buy - Featured Image

 

 
The Debate: Should You Build or Buy CAASM?
December 21, 2021   

2021-12-27 Log4j Dashboard - JupiterOne - Featured Image

 Log4Shell Remediation Visibility with JupiterOne and Log4Shell_Sentinel

December 21, 2021

Chasen Bettinger
Chasen Bettinger

Chasen is a Senior Security Automation Engineer at JupiterOne. His background is in building production-ready, cloud-native applications across a myriad of different industries. Whether it's defining requirements or writing tests, Chasen is always ready to jump in and get the job done. Outside of work, you can find him watching Formula 1 or reading a book.

Keep Reading

Introducing Continuous Controls Monitoring (CCM) | JupiterOne
November 7, 2024
Blog
Introducing Continuous Controls Monitoring (CCM)

CCM delivers real-time visibility, proactive risk management, and streamlined compliance for security.

Now Available: JupiterOne’s Public Postman Workspace | JupiterOne
October 31, 2024
Blog
Now Available: JupiterOne’s Public Postman Workspace

Explore JupiterOne’s Public Postman Workspace to streamline your workflows and enhance your security operations.

Prioritizing Exploitable Vulnerabilities to Protect Your Business Critical Assets | JupiterOne
October 16, 2024
Blog
Prioritizing Exploitable Vulnerabilities to Protect Your Business Critical Assets

Vulnerability scanners flood teams with alerts, but CTEM helps prioritize based on exploitability and business impact, ensuring focus on the most critical threats.

15 Mar 2022
Blog
One line headline, one line headline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiut.

15 Mar 2022
Blog
One line headline, one line headline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiut.

15 Mar 2022
Blog
One line headline, one line headline

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiut.