GCP - AppEngine Privesc

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

App Engine

Για περισσότερες πληροφορίες σχετικά με το App Engine, δείτε:

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

Αυτές είναι οι απαιτούμενες άδειες για να αναπτύξετε μια εφαρμογή χρησιμοποιώντας το gcloud cli. Ίσως τα get και list να μπορούν να παραληφθούν.

Μπορείτε να βρείτε παραδείγματα κώδικα Python στο https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine

Από προεπιλογή, το όνομα της υπηρεσίας App θα είναι default, και μπορεί να υπάρχει μόνο 1 instance με το ίδιο όνομα.
Για να το αλλάξετε και να δημιουργήσετε μια δεύτερη εφαρμογή, στο app.yaml, αλλάξτε την τιμή του root key σε κάτι σαν service: my-second-app

cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder

Δώστε του τουλάχιστον 10-15 λεπτά. Αν δεν λειτουργήσει, καλέστε deploy another of times και περιμένετε λίγα λεπτά.

Note

Είναι πιθανό να υποδείξετε το Service Account που θα χρησιμοποιηθεί αλλά από προεπιλογή χρησιμοποιείται το App Engine default SA.

Το URL της εφαρμογής είναι κάτι σαν https://<proj-name>.oa.r.appspot.com/ ή https://<service_name>-dot-<proj-name>.oa.r.appspot.com

Ενημέρωση αντίστοιχων δικαιωμάτων

Ενδέχεται να έχετε αρκετά δικαιώματα για να ενημερώσετε ένα AppEngine αλλά όχι για να δημιουργήσετε ένα καινούργιο. Σε αυτήν την περίπτωση, έτσι θα μπορούσατε να ενημερώσετε το τρέχον App Engine:

# 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

Εάν έχετε ήδη παραβιάσει ένα AppEngine και έχετε την άδεια appengine.applications.update και actAs πάνω στον service account που θέλετε να χρησιμοποιήσετε, θα μπορούσατε να τροποποιήσετε τον service account που χρησιμοποιείται από το AppEngine με:

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

Με αυτά τα δικαιώματα, είναι δυνατή η είσοδος μέσω ssh σε App Engine instances τύπου flexible (όχι standard). Κάποια από τα list και get δικαιώματα δεν είναι πραγματικά απαραίτητα.

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

appengine.applications.update, appengine.operations.get

Νομίζω ότι αυτό απλώς αλλάζει το background SA που θα χρησιμοποιήσει η google για να ρυθμίσει τις εφαρμογές, οπότε δεν νομίζω ότι μπορείς να το εκμεταλλευτείς για να κλέψεις το service account.

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

appengine.versions.getFileContents, appengine.versions.update

Δεν είμαι σίγουρος πώς να χρησιμοποιήσω αυτά τα permissions ή αν είναι χρήσιμα (σημείωση ότι όταν αλλάζεις τον κώδικα δημιουργείται νέα έκδοση, οπότε δεν ξέρω αν μπορείς απλώς να ενημερώσεις τον κώδικα ή το IAM role μιας έκδοσης, αλλά φαντάζομαι ότι θα μπορούσες, ίσως αλλάζοντας τον κώδικα μέσα στο bucket??).

bigquery.tables.delete, bigquery.datasets.delete & bigquery.models.delete (bigquery.models.getMetadata)

Για να διαγράψετε tables, datasets ή models:

# 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>

Κατάχρηση των Scheduled Queries

Με τα δικαιώματα bigquery.datasets.get, bigquery.jobs.create, και iam.serviceAccounts.actAs, μια ταυτότητα μπορεί να ανακτήσει dataset metadata, να εκκινήσει BigQuery jobs και να τα εκτελέσει χρησιμοποιώντας ένα Service Account με υψηλότερα προνόμια.

Αυτή η επίθεση επιτρέπει κακόβουλη χρήση των Scheduled Queries για αυτοματοποίηση ερωτημάτων (που εκτελούνται υπό το επιλεγμένο Service Account), τα οποία μπορούν, για παράδειγμα, να οδηγήσουν σε ανάγνωση ευαίσθητων δεδομένων και εγγραφή τους σε άλλο table ή dataset στο οποίο ο επιτιθέμενος έχει πρόσβαση — διευκολύνοντας την έμμεση και συνεχή exfiltration χωρίς να χρειάζεται εξωτερική εξαγωγή των δεδομένων.

Μόλις ο επιτιθέμενος γνωρίζει ποιο Service Account διαθέτει τα απαραίτητα δικαιώματα για να εκτελέσει το επιθυμητό query, μπορεί να δημιουργήσει μια Scheduled Query configuration που τρέχει χρησιμοποιώντας εκείνο το Service Account και περιοδικά εγγράφει τα αποτελέσματα σε ένα dataset της επιλογής του.

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"
}'

Δικαιώματα εγγραφής στα buckets

Όπως αναφέρθηκε, οι εκδόσεις του appengine δημιουργούν κάποια δεδομένα μέσα σε ένα bucket με όνομα μορφής: staging.<project-id>.appspot.com. Σημειώστε ότι δεν είναι δυνατό να γίνει pre-takeover αυτού του bucket επειδή οι χρήστες GCP δεν έχουν εξουσιοδότηση να δημιουργούν buckets χρησιμοποιώντας το domain appspot.com.

Ωστόσο, με read & write πρόσβαση σε αυτό το bucket, είναι δυνατόν να κλιμακώσετε προνόμια προς το SA που είναι συνδεδεμένο με την έκδοση του AppEngine, παρακολουθώντας το bucket και κάθε φορά που γίνεται μια αλλαγή, τροποποιώντας όσο το δυνατόν πιο γρήγορα τον κώδικα. Με αυτόν τον τρόπο, το container που δημιουργείται από αυτόν τον κώδικα θα execute the backdoored code.

Για περισσότερες πληροφορίες και ένα PoC δείτε τις σχετικές πληροφορίες από αυτή τη σελίδα:

GCP - Storage Privesc

Δικαιώματα εγγραφής στο Artifact Registry

Παρότι το App Engine δημιουργεί docker images μέσα στο Artifact Registry, δοκιμάστηκε ότι ακόμα και αν τροποποιήσεις την image μέσα σε αυτή την υπηρεσία και αφαιρέσεις την App Engine instance (οπότε αναπτύσσεται μια νέα), ο εκτελούμενος κώδικας δεν αλλάζει.
Ίσως να είναι δυνατό ότι πραγματοποιώντας ένα Race Condition attack όπως με τα buckets μπορεί να είναι εφικτό να αντικαταστήσεις τον εκτελούμενο κώδικα, αλλά αυτό δεν δοκιμάστηκε.

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks