Rhino Labs recently released a tool for scanning Google Cloud Storage (GCS) buckets, called GCPBruteBucket. The tool gives users an easy way to search for publicly exposed buckets being hosted by Google Cloud Platform (GCP). Netskope Threat Research Labs used this tool to scan a subset of the Majestic Million for not just exposed buckets, but buckets that would allow anonymous users to change permissions. Buckets which allow anonymous changes by any unauthenticated user could have any of the following happen: the original data could be deleted or modified, inappropriate content could be uploaded to the bucket, or the bucket could be deleted at any time by someone outside of the organization. Given the potential consequences, it’s important to know more about this threat and how to stop it.
In this post, we are going to cover what the misconfiguration looks like and a potential attack that will exploit it. We will cover some ways to mitigate against this in GCP and, ultimately, how Netskope will protect you from attacks based on the misconfiguration.
GCS Bucket Scanning Results
We scanned for thousands of names, and found a little over 10,000 valid bucket names in GCP. Of the buckets found, approximately 3% were publicly exposed. Approximately 5% of those were vulnerable to privilege escalation. In this context, public exposure refers to permissions being granted to ‘allUsers’ or ‘allAuthenticatedUsers’.
The ‘allUsers’ group contains unauthenticated, completely anonymous users, so this group exposes your bucket to anyone on the Internet. The ‘allAuthenticatedUsers’ group contains only users that are some kind of Google User (but don’t have to be a member of your organization). This means that anyone with a Gmail account could access content in your bucket.
Not all of the publicly available buckets are the result of a misconfiguration. As you can see in the chart above, approximately 25% of the buckets exposed were hosting web content. The other 75% were likely publicly exposed by mistake. When hosting web content, it’s expected that the bucket will allow read-only access to ‘allUsers’. The focus of our effort was to find buckets that allow anonymous users to change the permissions. This is problematic because if anyone can change the bucket permissions, they could escalate their privileges within the bucket.
Potential Data Exfiltration and Ransom
If a user is able to promote themselves to ownership level of the bucket, then they could do the following:
- Copy data out of your bucket to an attacker-owned bucket.
- Delete all of your data, and then delete your bucket.
- Create a new bucket with the same name in the attacker’s project, and give read / write permissions for files to everyone. The attacker could grant ‘Storage Object Creator’ and ‘Storage Object Viewer’ roles to the ‘allUsers’ group to accomplish this.
- Copy the data from the backup bucket to the new bucket in the attacker’s project.
Now, the attacker’s bucket with the same name is fully available for your users to upload data into. If your users or partners are automatically uploading data to your bucket by the name, they will not even notice that anything has changed. From there, the attacker could cut-off access to the data and hold it for ransom. See the diagram below:
Mitigating Controls in GCP
There are some mitigating controls available in GCP, which we should examine:
- Organization Policies
- VPC Service Controls
- Encryption of Storage Objects
Let’s discuss each control, and how it could be used to mitigate against data exposure or destruction.
Organization Policies
Organization Policies allow you to implement guard rails around your organization’s resources through constraints. There are only certain services and certain states that are available, and you can read more about them here.
The constraint that is most relevant to this misconfiguration is called “Domain restricted sharing.” If you place your storage buckets with sensitive data under a certain project or folder, you can then apply this constraint at the project or folder level to specify that no IAM permissions be granted to anyone outside of your organization. If you are a GSuite customer, you can grant access to the GSuite ID for your domain. This will prevent any user who has not authenticated to your GSuite domain from being granted IAM permissions to any resources in your project.
The issues with using this constraint are:
- It prevents the IAM permissions being changed, so anything that’s already misconfigured when you apply this constraint will remain that way.
- If your buckets are not already organized and segmented by projects (or folders) such that public and private buckets are clearly separated, then this will not be something you can implement.