CONTEXT CONTEXT CONTEXT
The more I learn about the cloud, the more excited I get about my journey. Let me paint a picture for you. Imagine getting the opportunity to go through a multitude of trainings. The kind of opportunity that harbors 継続的改善, (Keizoku-Teki Kaizen), continuous improvement. You are given a long list of courses/bootcamps/classes to choose from. All of these courses are categorized by different topics that relate to the Information Technology Industry (Digital Analytics, Agile Value Systems, Cybersecurity, Project Management, and etc). Each course is praised by it's own institute. As you read through the many options on this list, you start to wonder why there is such an abundance? That is neither here nor there. After looking through such a feeble list, only a couple courses catch your eye. Those course's include the Cloud Penetration Testing Boot-camp & Advanced Cloud Security Practitioner course.
BOOM WE GOT A WINNER!
You might ask yourself, "Why these specific courses?" The answer is simple, because they are fun topics to me. In this post, we will focus on Cloud Penetration Testing first and get to Cloud Security later on. The information below will cover information that relates to testing and security in the cloud, but we will focus on AWS in this course. Here's why:
BE A PEST TO TEST, STATS ARE THE BEST
Fun fact: 85% of business worldwide are already making use of cloud technology to store information. This is because cloud computing allows for more agility and flexibility for companies that don't want to have all their data on premise. As more and more services are hosted in the cloud, the need to adequately test their security measures with cloud hosts will increase. Here are a few other statistics that blew my mind:
- 80% of breaches involve privileged credentials
- Cloud based BEC email Scams cost 2.1 BILLION dollars in cost to US Businesses in 2020
- Through 2022, at least 95% of cloud security failures are predicted to be the customer's fault
- 84% of organizations say traditional security solutions don't work in cloud environments
GET TO THE CODE ALREADY!!
Settle your horses. In this post, we will be using CloudGoat. CloudGoat is Rhino Security Labs' "Vulnerable by Design" AWS deployment tool. It allows you to hone your cloud cybersecurity skills by creating and completing several "capture-the-flag" style scenarios. CloudGoat.
We will go through a concept called enumeration. Consider enumeration as “Information Gathering”. This is a process where an attacker establishes an active connection with a victim and try to discover as much attack vectors as possible, which can be used to exploit systems further. In this example, we will be working within AWS. When attacking an AWS cloud environment, its important to use leverage unauthenticated enumeration whenever possible. This kind of IAM recon can help you gain a better understanding of the environment itself, the users and applications that are using the AWS environment, and other information. IAM Roles and other ‘insider knowledge’ is key for any cloud penetration test.
It's possible to enumerate IAM users and roles without any keys (or other inside knowledge) to a target account. This allows for information gathering that can potentially expose who is using the environment, what 3rd party services are being utilized, AWS services utilized, and more. This all happens without any logs (CloudTrail or otherwise) being created in the victim’s account.
There was an old attack method which was used to enumerate the existence of IAM roles. This relied on the Simple Token Server (STS) AssumeRole API. This API allowed for enumeration of IAM roles because it would return an error message if the role existed that was different than the error message if the role did not exist.
When attempting to assume a role that exists, but you didn’t have permissions to assume, the API would return a message like this:
An error occurred (AccessDenied) when calling the 'AssumeRole' operation: User: arn:aws:iam::012345678901:user/MyUser is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::111111111111:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS
This AWS error message is basically saying that the user “MyUser” in the account “012345678901” is not allowed to assume the role “AWSServiceRoleForRDS” in the account “111111111111”. This message revealed that the role existed.
If the role did not exist, then the following error message would be returned instead:
An error occurred (AccessDenied) when calling the AssumeRole operation: Not authorized to perform sts:AssumeRole
Since this research was released, AWS security made a change to the API so that the STS AssumeRole API will return the same error message, regardless of whether the role exists of not. Now, you will see this error message instead:
An error occurred (AccessDenied) when calling the AssumeRole operation: Access denied
However, there is a new attack method that can still enumerate roles in other AWS accounts. This method involves IAM role trust policies. When setting up an IAM role trust policy, you are specifying what AWS resources/services can assume that role and gain temporary credentials. Let’s consider the following IAM role trust policy, which allows the “Test” role from the account ID “216825089941” to assume it.
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::216825089941:role\/Test"},"Action":"sts:AssumeRole"}]}
If we look at the trust relationships tab in the IAM web console, this is what we see:
Now, if we go and delete the “Test” role, then look at the trust relationships page again, we will see something different:
Then, if we hit “Edit trust relationship”, we will see that same value specified as the principal in the trust policy, but if we click “Update Trust Policy”, we will be shown this error message:
So, what happened? We didn’t change the value, but it was changed to an invalid value automatically. This is because when you save the trust policy document of a role, AWS security will find the resource specified in the principal somewhere in AWS to ensure that it exists. If the resource is found, the trust policy will save successfully, but if it is not found, then an error will be thrown, indicating an invalid principal was supplied. When AWS does this on the back-end, it takes the ARN that you supplied (“arn:aws:iam::216825089941:role/Test” for us) and matches it to a unique identifier that correlates to the resource in AWS. Then, when we deleted the “Test” role, AWS was no longer able to match the ARN we specified to an AWS resource, so by default, it will replace the ARN with the unique ID that was associated with that resource originally.
WHY DOES THIS MATTER?
There are potentially multiple reasons that this is done, but the best example is as follows.
Let’s say that a role allows the IAM user “Mike” in account “111111111111” to assume it. Mike is then fired from the company and has his AWS user deleted. Then, a week later, a new, different “Mike” is hired to the company and has an IAM user “Mike” created for him. Because of how AWS originally associates “Mike” to that unique ID (“AROAJUFJY2PBF22P35J4A” in our example above), the new “Mike” that just got hired would not be able to assume that original role, even though he has the same user name.
To allow the new Mike to assume that old role, the trust policy of the old role would need to be updated to allow access to the same ARN as before, but the update allows AWS to re-associate that ARN with the new “Mike” that exists, rather than the old “Mike” that doesn’t exist.
This is helpful in preventing situations where the old “Mike” was supposed to have more access than the new “Mike”, but because they had the same name, the new “Mike” gained additional privileges on accident. Instead, this problem is solved by associating ARNs to unique IDs for IAM resources.
Top comments (0)