GCP - Storage Privesc
Storage
Basic Information:
storage.objects.get
This permission allows you to download files stored inside Cloud Storage.[2] This will potentially allow you to escalate privileges because in some occasions sensitive information is saved there. Moreover, some GCP services stores their information in buckets:
- GCP Composer: When you create a Composer Environment the code of all the DAGs will be saved inside a bucket. These tasks might contain interesting information inside of their code.[6][8]
- GCR (Container Registry): The image of the containers are stored inside buckets, which means that if you can read the buckets you will be able to download the images and search for leaks and/or source code.[15]
storage.objects.setIamPolicy
You can give you permission to abuse any of the previous scenarios of this section.[1][3]
# Add binding
gcloud storage objects add-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>
# Remove binding
gcloud storage objects remove-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>
# Change Policy
gcloud storage objects set-iam-policy gs://<BUCKET_NAME>/<OBJECT_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY
storage.buckets.setIamPolicy
For an example on how to modify permissions with this permission check this page:[1][3]
# Add binding
gcloud storage buckets add-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>
# Remove binding
gcloud storage buckets remove-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>
# Change policy
gcloud storage buckets set-iam-policy gs://<BUCKET_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY
GCP - Public Buckets Privilege Escalation
storage.hmacKeys.create
Cloud Storage's interoperability feature supports HMAC authentication for cross-cloud workflows such as AWS S3. An attacker who can create a key for a more privileged Service Account can use that account's Cloud Storage permissions. User-account HMAC keys are managed through the web console and their secrets remain viewable there; a Service Account key exposes its secret only at creation, while its metadata can be listed later. This makes it important to save the service-account secret immediately.[1][4]
# Create key
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
## If you have TROUBLES creating the HMAC key this was you can also do it contacting the API directly:
PROJECT_ID = '$PROJECT_ID'
TARGET_SERVICE_ACCOUNT = f"storage-sa@{PROJECT_ID}.iam.gserviceaccount.com"
ACCESS_TOKEN = "$CLOUDSDK_AUTH_ACCESS_TOKEN"
import requests
import json
key = requests.post(
f'https://www.googleapis.com/storage/v1/projects/{PROJECT_ID}/hmacKeys',
params={'access_token': ACCESS_TOKEN, 'serviceAccountEmail': TARGET_SERVICE_ACCOUNT}
).json()
#print(json.dumps(key, indent=4))
print(f'ID: {key["metadata"]["accessId"]}')
print(f'Secret: {key["secret"]}')
# Configure gsutil to use the HMAC key
gcloud config set pass_credentials_to_gsutil false
gsutil config -a
# Use it
gsutil ls gs://[BUCKET_NAME]
# Restore
gcloud config set pass_credentials_to_gsutil true
Another exploit script for this method can be found here.[5]
storage.objects.create, storage.objects.delete = Storage Write permissions
In order to create a new object inside a bucket you need storage.objects.create and, according to the docs, you need also storage.objects.delete to modify an existent object.[2]
A very common exploitation of buckets where you can write in cloud is in case the bucket is saving web server files, you might be able to store new code that will be used by the web application.
Composer
Composer is Apache Airflow managed inside GCP.[6] It has several interesting features:
- In the legacy Composer architecture, it runs inside a managed GKE cluster, and Composer executes DAGs on behalf of the environment's service account; code in a DAG therefore runs with that identity's permissions.[6][7]
- The environment bucket stores DAG code, plugins, and data and synchronizes them to Airflow components. If an attacker has read and write permissions over it, they could monitor the bucket and whenever a DAG is created or updated, submit a backdoored version so the Composer environment gets the backdoored version from storage.[7][8][9]
You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs[9]
Cloud Functions
- In the Cloud Functions/Cloud Run functions deployment flow, source code is stored in Cloud Storage and Cloud Build automatically builds a container from it. Therefore, overwriting the code before the new version gets built it's possible to make the cloud function execute arbitrary code when the attacker can write the relevant source or upload bucket.[10][11]
You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions[11]
App Engine
AppEngine versions stage deployment data inside a bucket with the format staging.<project-id>.appspot.com.[12][13] Inside this bucket, it's possible to find a folder called ae that will contain a folder per version of the AppEngine app and inside these folders it'll be possible to find the manifest.json file. This file contains a JSON with all the files that must be used to create the specific version. Moreover, it's possible to find the real names of the files, the URL to them inside the GCP bucket (the files inside the bucket changed their name for their sha1 hash) and the sha1 hash of each file.[13]
Note that it's not possible to pre-takeover this bucket because GCP users aren't authorized to generate buckets using the domain name appspot.com.[13]
However, with read & write access over this bucket, it's possible to escalate privileges to the SA attached to the App Engine version by monitoring the bucket and any time a change is performed (new version), modify the new version as fast as possible. This way, the container that gets created from this code will execute the backdoored code.[12][13]
The mentioned attack can be performed in a lot of different ways, all of them start by monitoring the staging.<project-id>.appspot.com bucket:[13]
- Upload the complete new code of the AppEngine version to a different and available bucket and prepare a
manifest.jsonfile with the new bucket name and sha1 hashes of them. Then, when a new version is created inside the bucket, you just need to modify themanifest.jsonfile and upload the malicious one.[13] - Upload a modified
requirements.txtversion that will use a the malicious dependencies code and update themanifest.jsonfile with the new filename, URL and the hash of it.[13] - Upload a modified
main.pyorapp.yamlfile that will execute the malicious code and update themanifest.jsonfile with the new filename, URL and the hash of it.[13]
You can find a PoC of this attack in the repo: https://github.com/carlospolop/Monitor-Backdoor-AppEngine[13]
GCR
- Google Container Registry stores the images inside buckets, if you can write those buckets you might be able to move laterally to where those buckets are being run.[15]
[!TIP] This service is deprecated and writing to Container Registry is unavailable, so this bucket-based attack no longer applies to new deployments. Artifact Registry, the recommended replacement, does't store images in project Cloud Storage buckets.[15]
References
- [1] Privilege Escalation in Google Cloud Platform – Part 2 (Non-IAM) | Rhino Security Labs
- [2] IAM permissions for Cloud Storage
- [3] Set and manage IAM policies on buckets
- [4] HMAC keys | Cloud Storage
- [5] Cloud Storage HMAC key exploit script
- [6] Environment architecture | Cloud Composer (Gen 1)
- [7] Create Cloud Composer environments
- [8] Data stored in Cloud Storage | Cloud Composer
- [9] Monitor-Backdoor-Composer-DAGs
- [10] Build process overview | Cloud Run functions
- [11] Monitor-Backdoor-Cloud-Functions
- [12] Use Cloud Storage | App Engine standard environment
- [13] Monitor-Backdoor-AppEngine
- [14] Push and pull images | Container Registry
- [15] Transition from Container Registry | Artifact Registry
[!TIP] Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Browse the full HackTricks Training catalog.Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


