GCP - AppEngine Privesc

Support HackTricks

App Engine

Für weitere Informationen über App Engine siehe:

GCP - App Engine Enum

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 gcloud cli zu deployen. Vielleicht könnten die get und list Berechtigungen vermeidet werden.

Du kannst Python-Codebeispiele unter https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine finden.

Standardmäßig wird der Name des App-Dienstes default sein, und es kann nur 1 Instanz mit demselben Namen geben. Um dies zu ändern und eine zweite App zu erstellen, ändere im app.yaml den Wert des Root-Schlüssels 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, wenn es nicht funktioniert, rufe deploy another of times an und warte einige Minuten.

Es ist möglich, das zu verwendende Service-Konto anzugeben, aber standardmäßig wird das App Engine-Standard-SA verwendet.

Die URL der Anwendung ist etwas wie https://<proj-name>.oa.r.appspot.com/ oder https://<service_name>-dot-<proj-name>.oa.r.appspot.com

Aktualisiere gleichwertige Berechtigungen

Möglicherweise hast du genügend Berechtigungen, um eine AppEngine zu aktualisieren, aber nicht, um eine neue zu erstellen. In diesem Fall ist dies, wie du die aktuelle App Engine aktualisieren könntest:

# 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 Sie bereits ein AppEngine kompromittiert haben und Sie die Berechtigung appengine.applications.update sowie actAs über das Dienstkonto haben, könnten Sie das von AppEngine verwendete Dienstkonto mit folgendem Befehl ä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 über SSH in App Engine-Instanzen vom Typ flexible (nicht standard) einzuloggen. Einige der list und get Berechtigungen könnten wirklich nicht benötigt werden.

gcloud app instances ssh --service <app-name> --version <version-id> <ID>

appengine.applications.update, appengine.operations.get

Ich denke, das ändert nur den Hintergrund-SA, den Google verwenden wird, um die Anwendungen einzurichten, daher denke ich nicht, dass man dies ausnutzen kann, um das Dienstkonto zu stehlen.

gcloud app update --service-account=<sa_email>

appengine.versions.getFileContents, appengine.versions.update

Nicht sicher, wie man diese Berechtigungen verwendet oder ob sie nützlich sind (beachten Sie, dass bei einer Codeänderung eine neue Version erstellt wird, also weiß ich nicht, ob Sie nur den Code oder die IAM-Rolle von einem aktualisieren können, aber ich nehme an, dass Sie das sollten, vielleicht indem Sie den Code im Bucket ändern??).

Schreibzugriff auf die Buckets

Wie erwähnt, generieren die App Engine-Versionen einige Daten in einem Bucket mit dem Formatname: staging.<project-id>.appspot.com. Beachten Sie, dass es nicht möglich ist, diesen Bucket im Voraus zu übernehmen, da GCP-Benutzer nicht autorisiert sind, Buckets mit dem Domänennamen appspot.com zu erstellen.

Mit Lese- und Schreibzugriff auf diesen Bucket ist es jedoch möglich, die Berechtigungen auf den SA, der an der App Engine-Version angehängt ist, zu eskalieren, indem man den Bucket überwacht und jedes Mal, wenn eine Änderung vorgenommen wird, den Code so schnell wie möglich ändert. Auf diese Weise wird der Container, der aus diesem Code erstellt wird, den hintertürigen Code ausführen.

Für weitere Informationen und eine PoC überprüfen Sie die relevanten Informationen von dieser Seite:

GCP - Storage Privesc

Schreibzugriff auf das Artifact Registry

Obwohl App Engine Docker-Images im Artifact Registry erstellt, wurde getestet, dass selbst wenn Sie das Image in diesem Dienst ändern und die App Engine-Instanz entfernen (sodass eine neue bereitgestellt wird), der ausgeführte Code sich nicht ändert. Es könnte möglich sein, dass durch die Durchführung eines Race Condition-Angriffs, wie bei den Buckets, es möglich sein könnte, den ausgeführten Code zu überschreiben, aber das wurde nicht getestet.

Support HackTricks

Last updated