Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions docs/attack-techniques/GCP/gcp.impact.invoke-vertex-ai-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: Invoke a Vertex AI Model
---

# Invoke a Vertex AI Model


<span class="smallcaps w3-badge w3-blue w3-round w3-text-white" title="This attack technique can be detonated multiple times">idempotent</span>

Platform: GCP

## Mappings

- MITRE ATT&CK
- Impact



## Description


Invokes a Gemini generative AI model via the Vertex AI API. This simulates
an attacker who has obtained access to a GCP service account and abuses it
to run large language model workloads, incurring unexpected costs for the
victim organization.

Prerequisites:

- AI Platform API enabled (gcloud services enable aiplatform.googleapis.com)

<span style="font-variant: small-caps;">Detonation</span>:

- Call the Vertex AI API to generate content using a Gemini model
in the <code>us-central1</code> region

References:

- https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference
- https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.endpoints/generateContent
- https://sysdig.com/blog/llmjacking-stolen-cloud-credentials-used-in-new-ai-attack/
- https://unit42.paloaltonetworks.com/privilege-escalation-llm-model-exfil-vertex-ai/


## Instructions

```bash title="Detonate with Stratus Red Team"
stratus detonate gcp.impact.invoke-vertex-ai-model
```
## Detection


Identify unexpected Vertex AI model invocations by monitoring for
<code>google.cloud.aiplatform.v1.PredictionService.GenerateContent</code> events in
GCP Data Access audit logs, particularly from unexpected service accounts or at
unusual times/volumes.


2 changes: 2 additions & 0 deletions docs/attack-techniques/GCP/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,5 @@ Note that some Stratus attack techniques may correspond to more than a single AT

- [Create GCE Instances in Multiple Zones](./gcp.impact.create-instances-in-multiple-zones.md)

- [Invoke a Vertex AI Model](./gcp.impact.invoke-vertex-ai-model.md)

1 change: 1 addition & 0 deletions docs/attack-techniques/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ This page contains the list of all Stratus Attack Techniques.
| [Exfiltrate Compute Disk by sharing a snapshot](./GCP/gcp.exfiltration.share-compute-snapshot.md) | [GCP](./GCP/index.md) | Exfiltration |
| [Create a GCE GPU Virtual Machine](./GCP/gcp.impact.create-gpu-vm.md) | [GCP](./GCP/index.md) | Impact |
| [Create GCE Instances in Multiple Zones](./GCP/gcp.impact.create-instances-in-multiple-zones.md) | [GCP](./GCP/index.md) | Impact |
| [Invoke a Vertex AI Model](./GCP/gcp.impact.invoke-vertex-ai-model.md) | [GCP](./GCP/index.md) | Impact |
| [Steal and Use the GCE Default Service Account Token from Outside Google Cloud](./GCP/gcp.initial-access.use-compute-sa-outside-gcp.md) | [GCP](./GCP/index.md) | Credential Access, Initial Access |
| [Register SSH public key to instance metadata](./GCP/gcp.lateral-movement.add-sshkey-instance-metadata.md) | [GCP](./GCP/index.md) | Lateral Movement, Persistence |
| [Backdoor a GCP Service Account through its IAM Policy](./GCP/gcp.persistence.backdoor-service-account-policy.md) | [GCP](./GCP/index.md) | Persistence |
Expand Down
2 changes: 1 addition & 1 deletion docs/attack-techniques/mitre-attack-coverage-matrices.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ This provides coverage matrices of MITRE ATT&CK tactics and techniques currently
<tbody>
<tr><td><a href="../GCP/gcp.initial-access.use-compute-sa-outside-gcp">Steal and Use the GCE Default Service Account Token from Outside Google Cloud</a></td><td><a href="../GCP/gcp.execution.modify-gce-startup-script">Modify a GCE Instance Startup Script</a></td><td><a href="../GCP/gcp.lateral-movement.add-sshkey-instance-metadata">Register SSH public key to instance metadata</a></td><td><a href="../GCP/gcp.execution.modify-gce-startup-script">Modify a GCE Instance Startup Script</a></td><td><a href="../GCP/gcp.defense-evasion.delete-dns-logs">Delete a Cloud DNS Logging Policy</a></td><td><a href="../GCP/gcp.credential-access.secretmanager-retrieve-secrets">Retrieve a High Number of Secret Manager secrets</a></td><td><a href="../GCP/gcp.discovery.download-instance-metadata">Read GCE Instance Metadata via the Compute API</a></td><td><a href="../GCP/gcp.lateral-movement.add-sshkey-instance-metadata">Register SSH public key to instance metadata</a></td><td><a href="../GCP/gcp.exfiltration.open-port-22-ingress">Open Ingress Port 22 on a Firewall Rule</a></td><td><a href="../GCP/gcp.impact.create-gpu-vm">Create a GCE GPU Virtual Machine</a></td></tr>
<tr><td></td><td><a href="../GCP/gcp.execution.modify-vertex-notebook-startup">Inject a Malicious Startup Script into a Vertex AI Workbench Instance</a></td><td><a href="../GCP/gcp.persistence.backdoor-service-account-policy">Backdoor a GCP Service Account through its IAM Policy</a></td><td><a href="../GCP/gcp.persistence.create-admin-service-account">Create an Admin GCP Service Account</a></td><td><a href="../GCP/gcp.defense-evasion.disable-audit-logs">Disable Data Access Audit Logs for a GCP Service</a></td><td><a href="../GCP/gcp.initial-access.use-compute-sa-outside-gcp">Steal and Use the GCE Default Service Account Token from Outside Google Cloud</a></td><td><a href="../GCP/gcp.discovery.enumerate-permissions">Enumerate Permissions of a GCP Service Account</a></td><td></td><td><a href="../GCP/gcp.exfiltration.share-compute-disk">Exfiltrate Compute Disk by sharing it</a></td><td><a href="../GCP/gcp.impact.create-instances-in-multiple-zones">Create GCE Instances in Multiple Zones</a></td></tr>
<tr><td></td><td><a href="../GCP/gcp.execution.os-config-run-command">Execute Commands on GCE Instances via OS Config Agent</a></td><td><a href="../GCP/gcp.persistence.create-admin-service-account">Create an Admin GCP Service Account</a></td><td><a href="../GCP/gcp.persistence.create-service-account-key">Create a GCP Service Account Key</a></td><td><a href="../GCP/gcp.defense-evasion.remove-project-from-organization">Attempt to Remove a GCP Project from its Organization</a></td><td></td><td></td><td></td><td><a href="../GCP/gcp.exfiltration.share-compute-image">Exfiltrate Compute Image by sharing it</a></td><td></td></tr>
<tr><td></td><td><a href="../GCP/gcp.execution.os-config-run-command">Execute Commands on GCE Instances via OS Config Agent</a></td><td><a href="../GCP/gcp.persistence.create-admin-service-account">Create an Admin GCP Service Account</a></td><td><a href="../GCP/gcp.persistence.create-service-account-key">Create a GCP Service Account Key</a></td><td><a href="../GCP/gcp.defense-evasion.remove-project-from-organization">Attempt to Remove a GCP Project from its Organization</a></td><td></td><td></td><td></td><td><a href="../GCP/gcp.exfiltration.share-compute-image">Exfiltrate Compute Image by sharing it</a></td><td><a href="../GCP/gcp.impact.invoke-vertex-ai-model">Invoke a Vertex AI Model</a></td></tr>
<tr><td></td><td></td><td><a href="../GCP/gcp.persistence.create-service-account-key">Create a GCP Service Account Key</a></td><td><a href="../GCP/gcp.privilege-escalation.impersonate-service-accounts">Impersonate GCP Service Accounts</a></td><td><a href="../GCP/gcp.defense-evasion.remove-vpc-flow-logs">Disable VPC Flow Logs on a Subnet</a></td><td></td><td></td><td></td><td><a href="../GCP/gcp.exfiltration.share-compute-snapshot">Exfiltrate Compute Disk by sharing a snapshot</a></td><td></td></tr>
<tr><td></td><td></td><td><a href="../GCP/gcp.persistence.invite-external-user">Invite an External User to a GCP Project</a></td><td><a href="../GCP/gcp.execution.modify-vertex-notebook-startup">Inject a Malicious Startup Script into a Vertex AI Workbench Instance</a></td><td><a href="../GCP/gcp.defense-evasion.delete-logging-sink">Delete a GCP Log Sink</a></td><td></td><td></td><td></td><td><a href="../GCP/gcp.exfiltration.backdoor-gcs-bucket">Backdoor a GCS Bucket via Overly Permissive IAM Policy</a></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td><a href="../GCP/gcp.defense-evasion.disable-logging-sink">Disable a GCP Log Sink</a></td><td></td><td></td><td></td><td></td><td></td></tr>
Expand Down
7 changes: 7 additions & 0 deletions docs/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,13 @@ GCP:
- Impact
platform: GCP
isIdempotent: false
- id: gcp.impact.invoke-vertex-ai-model
name: Invoke a Vertex AI Model
isSlow: false
mitreAttackTactics:
- Impact
platform: GCP
isIdempotent: true
Initial Access:
- id: gcp.initial-access.use-compute-sa-outside-gcp
name: Steal and Use the GCE Default Service Account Token from Outside Google Cloud
Expand Down
5 changes: 5 additions & 0 deletions v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ toolchain go1.24.2
require (
cloud.google.com/go/compute v1.31.1
cloud.google.com/go/secretmanager v1.14.4
cloud.google.com/go/vertexai v0.12.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.5.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6 v6.1.0
Expand Down Expand Up @@ -59,10 +61,13 @@ require (
)

require (
cloud.google.com/go v0.118.0 // indirect
cloud.google.com/go/aiplatform v1.70.0 // indirect
cloud.google.com/go/auth v0.14.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
cloud.google.com/go/compute/metadata v0.6.0 // indirect
cloud.google.com/go/iam v1.3.1 // indirect
cloud.google.com/go/longrunning v0.6.4 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.3.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions v2/go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.118.0 h1:tvZe1mgqRxpiVa3XlIGMiPcEUbP1gNXELgD4y/IXmeQ=
cloud.google.com/go v0.118.0/go.mod h1:zIt2pkedt/mo+DQjcT4/L3NDxzHPR29j5HcclNH+9PM=
cloud.google.com/go/aiplatform v1.70.0 h1:vnqsPkgcwlDEpWl9t6C3/HLfHeweuGXs2gcYTzH6dMs=
cloud.google.com/go/aiplatform v1.70.0/go.mod h1:1cewyC4h+yvRs0qVvlCuU3V6j1pJ41doIcroYX3uv8o=
cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM=
cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A=
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
Expand All @@ -11,8 +13,12 @@ cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
cloud.google.com/go/iam v1.3.1 h1:KFf8SaT71yYq+sQtRISn90Gyhyf4X8RGgeAVC8XGf3E=
cloud.google.com/go/iam v1.3.1/go.mod h1:3wMtuyT4NcbnYNPLMBzYRFiEfjKfJlLVLrisE7bwm34=
cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg=
cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs=
cloud.google.com/go/secretmanager v1.14.4 h1:SMWQMsUcACsdIuVhIBAw+QfKY4Xseiaa8qDnunjmhcM=
cloud.google.com/go/secretmanager v1.14.4/go.mod h1:pjwFw8+A6B4AcWrVXruLfz1QykkpMr8T/VT+zXB91iw=
cloud.google.com/go/vertexai v0.12.0 h1:zTadEo/CtsoyRXNx3uGCncoWAP1H2HakGqwznt+iMo8=
cloud.google.com/go/vertexai v0.12.0/go.mod h1:8u+d0TsvBfAAd2x5R6GMgbYhsLgo3J7lmP4bR8g2ig8=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package gcp

import (
"context"
"fmt"
"log"
"strings"

"cloud.google.com/go/vertexai/genai"
"github.com/datadog/stratus-red-team/v2/pkg/stratus"
"github.com/datadog/stratus-red-team/v2/pkg/stratus/mitreattack"
)

// candidateModels is tried in order until one succeeds. Uses stable aliases
// (no version suffix) so GCP automatically resolves them to the current supported
// version — aliases don't have retirement dates, unlike pinned version IDs.
// Ordered cheapest first.
var candidateModels = []string{
"gemini-2.5-flash-lite",
"gemini-2.5-flash",
"gemini-2.5-pro",
}

func init() {
stratus.GetRegistry().RegisterAttackTechnique(&stratus.AttackTechnique{
ID: "gcp.impact.invoke-vertex-ai-model",
FriendlyName: "Invoke a Vertex AI Model",
Description: `
Invokes a Gemini generative AI model via the Vertex AI API. This simulates
an attacker who has obtained access to a GCP service account and abuses it
to run large language model workloads, incurring unexpected costs for the
victim organization.

Prerequisites:

- AI Platform API enabled (gcloud services enable aiplatform.googleapis.com)

Detonation:

- Call the Vertex AI API to generate content using a Gemini model
in the <code>us-central1</code> region

References:

- https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference
- https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.endpoints/generateContent
- https://sysdig.com/blog/llmjacking-stolen-cloud-credentials-used-in-new-ai-attack/
- https://unit42.paloaltonetworks.com/privilege-escalation-llm-model-exfil-vertex-ai/
`,
Detection: `
Identify unexpected Vertex AI model invocations by monitoring for
<code>google.cloud.aiplatform.v1.PredictionService.GenerateContent</code> events in
GCP Data Access audit logs, particularly from unexpected service accounts or at
unusual times/volumes.
`,
Platform: stratus.GCP,
IsIdempotent: true,
MitreAttackTactics: []mitreattack.Tactic{mitreattack.Impact},
Detonate: detonate,
})
}

func detonate(_ map[string]string, providers stratus.CloudProviders) error {
gcp := providers.GCP()
projectId := gcp.GetProjectId()
ctx := context.Background()

client, err := genai.NewClient(ctx, projectId, "us-central1", gcp.Options())
if err != nil {
return fmt.Errorf("failed to create Vertex AI client: %w", err)
}
defer client.Close()

for _, modelName := range candidateModels {
log.Printf("Invoking Vertex AI model %s in project %s\n", modelName, projectId)
resp, err := client.GenerativeModel(modelName).GenerateContent(
ctx,
genai.Text("Tell me a joke about cloud security."),
)
if err != nil {
if isNotFound(err) {
log.Printf("Model %s not available in this project, trying next\n", modelName)
continue
}
return fmt.Errorf("failed to invoke Vertex AI model: %w", err)
}

if len(resp.Candidates) == 0 || len(resp.Candidates[0].Content.Parts) == 0 {
return fmt.Errorf("received empty response from Vertex AI model %s", modelName)
}

log.Printf("Successfully invoked Vertex AI model %s. Response: %v\n",
modelName, resp.Candidates[0].Content.Parts[0])
return nil
}

return fmt.Errorf("no Vertex AI model available in project %s (tried: %s) — ensure the Vertex AI API is enabled",
projectId, strings.Join(candidateModels, ", "))
}

// isNotFound returns true when the gRPC error indicates the model does not exist
// or is not accessible in this project.
func isNotFound(err error) bool {
msg := err.Error()
return strings.Contains(msg, "NOT_FOUND") ||
strings.Contains(msg, "code = NotFound") ||
strings.Contains(msg, "was not found")
}
1 change: 1 addition & 0 deletions v2/internal/attacktechniques/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import (
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/exfiltration/share-compute-image"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/exfiltration/share-compute-snapshot"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/impact/create-gpu-vm"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/impact/invoke-vertex-ai-model"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/impact/create-instances-in-multiple-zones"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/initial-access/use-compute-sa-outside-gcp"
_ "github.com/datadog/stratus-red-team/v2/internal/attacktechniques/gcp/lateral-movement/add-sshkey-instance-metadata"
Expand Down