Skip to navigation

Threat reportCloud SecurityTL-2026-1648

GCP Cross-Project Compute Image Exfiltration via Compromised Developer Credentials

highACTIVE

A demonstrated GCP attack chain shows how an attacker who phishes a developer's credentials and bypasses MFA can abuse overly broad cross-project IAM roles (compute.imageUser, compute.admin, storage.admin) to copy a confidential compute image into an attacker-pivot project, convert it to a Cloud Storage object via the Cloud Build API, and exfiltrate it with gsutil to an externally-controlled bucket in a separate GCP organization.

Key facts for GCP cross-project image exfiltration

IdentifiersTL-2026-1648
Also known asGCP Compute Image Exfiltration Tutorial, Monstera-to-Cactus Exfiltration Chain
SeverityHIGH
Exploitation statusPublic proof-of-concept exploit
Affected productsGoogle Google Cloud Platform - Compute Engine Images; Google Google Cloud Platform - Cloud Build; Google Google Cloud Storage
Weaknesses (CWE)CWE-269, CWE-284, CWE-732
Toolsgcloud CLI, gsutil
MITRE ATT&CK techniquesT1020 Automated Exfiltration, T1069.003 Cloud Groups, T1078.004 Cloud Accounts, T1111 Multi-Factor Authentication Interception, T1119 Automated Collection, T1526 Cloud Service Discovery, T1530 Data from Cloud Storage, T1537 Transfer Data to Cloud Account, T1548 Abuse Elevation Control Mechanism, T1550 Use Alternate Authentication Material, T1565 Data Manipulation, T1566 Phishing and 4 more in the attack flow
MotivationUNKNOWN
Target sectorstechnology, cloud-hosted-workloads, software-development
Target regionsGlobal
Detection rules9 (1 shown free)
Sources9 cited sources

Detection coverage for GCP cross-project image exfiltration

As of 2026-07-23, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1648 across Splunk SPL, Microsoft KQL and Sigma, covering 18 indicator(s) of compromise. The whole corpus is readable without an account. Every threat comes with one complete detection in Splunk SPL, Microsoft KQL and Sigma, free for everyone; a free account adds daily TL Creds to unlock the rest. Paid plans add a larger daily allowance, correlation and the MCP server. Threadlinqs MCP server · View plans.

Free detection: GCP Cross-Organization Storage Object Write to External Bucket

Detects the final exfiltration step: a storage.objects.create (or gsutil cp -r-driven write) targeting a bucket whose IAM policy grants access to a principal outside the source GCP organization, following storage.objects.list/get enumeration of the source object — the final stage of the Monstera-to-Cactus cross-organization image exfiltration chain.

  • Languages: Splunk SPL, Microsoft KQL, Sigma
  • ATT&CK: T1537, T1567.002, T1020
  • Data sources: gcp_cloudaudit_data_access, gcp_iam_bucket_policy_reference
  • Severity: critical
  • Confidence: high

Splunk SPL

index=gcp sourcetype="google:gcp:pubsub:audit" data.protoPayload.methodName IN ("storage.objects.list","storage.objects.get","storage.buckets.get","storage.objects.create")
| eval bucket=mvindex(split(data.protoPayload.resourceName, "/"), 1)
| lookup gcp_bucket_org_lookup bucket OUTPUT bucket_org
| eval principal=data.protoPayload.authenticationInfo.principalEmail
| lookup gcp_principal_org_lookup principal OUTPUT principal_org
| where isnotnull(bucket_org) AND isnotnull(principal_org) AND bucket_org!=principal_org AND data.protoPayload.methodName="storage.objects.create"
| table _time, principal, principal_org, bucket, bucket_org, data.protoPayload.resourceName

Microsoft KQL

GCPAuditLogs
| where TimeGenerated > ago(24h)
| where OperationName == "storage.objects.create"
| extend Bucket = tostring(split(tostring(parse_json(ProtoPayload).resourceName), "/")[1])
| extend Principal = tostring(parse_json(ProtoPayload).authenticationInfo.principalEmail)
| join kind=inner (GCPBucketOrgReference) on Bucket
| join kind=inner (GCPPrincipalOrgReference) on Principal
| where BucketOrg != PrincipalOrg
| project TimeGenerated, Principal, PrincipalOrg, Bucket, BucketOrg, ResourceName = tostring(parse_json(ProtoPayload).resourceName)

Sigma

title: GCP Cross-Organization Storage Object Write to External Bucket
id: 8e2a1e2a-1648-4b2e-9f1a-tl20261648003
status: experimental
description: Detects a storage.objects.create write to a bucket whose IAM binding includes a principal from a different GCP organization than the source project, indicating the final cross-organization exfiltration step of the Monstera-to-Cactus chain.
references:
    - https://www.mitiga.io/blog/google-cloud-platform-exfiltration-a-threat-hunting-guide
author: AII-Detector — ThreadLinqs Intelligence
date: 2026-07-23
tags:
    - attack.exfiltration
    - attack.t1537
    - attack.t1567.002
    - attack.t1020
    - attack.collection
    - attack.t1530
detection:
    selection:
        gcp.audit.method_name: 'storage.objects.create'
        bucket_iam_binding: 'external_organization'
    condition: selection
falsepositives:
    - Approved partner data-sharing buckets with documented cross-org IAM grants (maintain an allowlist)
level: critical
logsource:
    product: gcp
    service: cloudaudit

Known false positives:

  • Approved partner data-sharing buckets with documented cross-org IAM grants — maintain an allowlist of sanctioned partner org IDs and bucket names

Tuning notes: Requires maintaining an org-ID reference lookup mapping bucket names and principal domains to their owning GCP organization; without it this detection cannot reliably distinguish cross-org writes from same-org writes, so populate/refresh the lookup via Cloud Asset Inventory exports.

8 more detection rules (Splunk SPL, Microsoft KQL, Sigma) · unlock with TL Creds. Sign up free to unlock the detection rules or query them with the Threadlinqs MCP server (Purple)
  • GCP Cross-Project Compute Image Copy — Sentinel Detection · unlock with TL Creds
  • GCP Cloud Build Default Service Account Abuse for Image Export — Sentinel · unlock with TL Creds
  • GCP Storage Metadata-Read Immediately Followed by External-Org Bucket Enumeration · unlock with TL Creds
  • GCP Cross-Project Compute Image Copy — Sigma Rule · unlock with TL Creds
  • GCP Cloud Build API Enabled Then Immediately Used for Image Export — Sigma Rule · unlock with TL Creds
  • GCP IAM Grant of [indicator] to External-Organization Bucket for a [indicator] Principal · unlock with TL Creds
  • GCP Cross-Project Compute Image Copy — sourceImage/resourceName Project Mismatch · unlock with TL Creds
  • GCP Cloud Build API Enable Immediately Followed by Image Export · unlock with TL Creds

Indicators of compromise for GCP cross-project image exfiltration

As of 2026-07-23, Threadlinqs Intelligence tracks 18 indicators of compromise for TL-2026-1648.

18 indicators of compromise · unlock with TL Creds. Compare plans

How GCP cross-project image exfiltration works

Mitiga published a threat-hunting guide walking through a controlled-environment (proof-of-concept) exfiltration chain against Google Cloud Platform using a fictional victim developer ('Bob') and attacker ('Eve'). Eve first phishes Bob and bypasses his two-factor authentication to obtain valid GCP credentials scoped to the 'Aloe Vera' organization. Enumeration of Bob's IAM bindings reveals he holds compute.imageUser and project.viewer on a 'Monstera Project' containing a sensitive compute image, and compute.admin, storage.admin, roles/servicemanagement.serviceConsumer, and serviceusage.services.enable on a separate 'Cactus Project' that Bob can use as a pivot.

Because Bob lacks storage permissions in Monstera Project directly, Eve instead runs `gcloud compute images create` to copy the target compute image cross-project into Cactus Project, which logs as a `v1.compute.images.insert` event where the sourceImage path and the destination resourceName path point to two different projects -- the single highest-value detection signal in the whole chain. Eve then enables the Cloud Build API in Cactus Project (`google.api.serviceusage.v1.ServiceUsage.EnableService`) and issues `gcloud compute images export`, which causes the `cloudbuild` service account to call `compute.images.get` and `storage.objects.create` to convert the raw compute image into a GCS object inside a Cactus Project bucket -- resourceName strings for these objects typically contain 'log' or 'daisy' artifacts from the underlying Daisy image-export workflow.

For final exfiltration, Eve provisions an attacker-owned Google Cloud Storage bucket in a completely separate GCP organization, grants Bob's compromised account storage.object.admin (or equivalent legacy ACL) on that external bucket, and runs `gsutil cp -r` to recursively copy the exported image object out of Cactus Project into the external bucket. Mitiga notes a key visibility gap: GCP logs metadata-read operations on a storage object (storage.objects.get for metadata) identically to full object downloads, and destination-bucket write operations performed cross-organization do not appear in the source organization's audit logs -- meaning defenders monitoring only the source org will see reads/lists but never confirm the transfer completed, or vice versa depending on which side is monitored.

Although this is a documented tutorial rather than an observed in-the-wild intrusion, and there is no associated CVE, the underlying primitives it chains -- IAM over-permissioning across projects, Cloud Build default service-account abuse (cf. the related 'Bad.Build'/ConfusedFunction design flaw class publicly reported by Orca Security), and gsutil-based cross-organization bucket-to-bucket transfer -- are all live, exploitable misconfiguration classes in production GCP estates and map directly to MITRE ATT&CK Cloud techniques for valid cloud account abuse, cloud-to-cloud data transfer, and permission-groups discovery.

MITRE ATT&CK techniques by tactic:

Exfiltration

T1020 Automated Exfiltration; T1537 Transfer Data to Cloud Account; T1567.002 Exfiltration to Cloud Storage

Discovery

T1069.003 Cloud Groups; T1526 Cloud Service Discovery; T1580 Cloud Infrastructure Discovery

Initial Access

T1078.004 Cloud Accounts; T1566 Phishing

Privilege Escalation

T1078.004 Cloud Accounts; T1548 Abuse Elevation Control Mechanism

Defense Evasion

T1078.004 Cloud Accounts

Credential Access

T1111 Multi-Factor Authentication Interception; T1621 Multi-Factor Authentication Request Generation

Collection

T1119 Automated Collection; T1530 Data from Cloud Storage

lateral-movement

T1550 Use Alternate Authentication Material

Impact

T1565 Data Manipulation

Resource Development

T1583.007 Serverless

Remediation for GCP cross-project image exfiltration

Patches

  • No vendor patch applicable; Google addressed the related Cloud Build default-service-account design flaw by changing the default to the Compute Engine service account and allowing custom scoped service accounts for builds

Immediate actions

  • Audit and revoke unnecessary cross-project IAM bindings, especially compute.admin, storage.admin, and compute.imageUser granted to individual developer accounts spanning multiple projects
  • Enable and review Cloud Audit Logs (Admin Activity + Data Access) for v1.compute.images.insert events where sourceImage and resourceName reference different project IDs
  • Alert on serviceusage.services.enable calls that turn on the Cloud Build API in projects where it was previously disabled
  • Restrict gsutil/storage.objects egress to known-good destination buckets via VPC Service Controls perimeters
  • Enforce phishing-resistant MFA (FIDO2 security keys) for all developer accounts with cross-project IAM grants

Workarounds

  • Disable automatic Cloud Build API enablement in projects that do not require it, and monitor EnableService calls
  • Remove storage.objects.create/get and storage.buckets.get permissions from developer roles that only need compute image access
  • Apply organization policy constraints (e.g. constraints/compute.storageResourceUseRestrictions, constraints/iam.allowedPolicyMemberDomains) to block cross-organization IAM bindings on storage buckets

Longer-term hardening

  • Adopt least-privilege, project-scoped custom IAM roles instead of broad predefined roles (compute.admin, storage.admin) for developers
  • Deploy Cloud Identity-Aware Proxy and context-aware access policies to restrict where privileged GCP sessions can originate
  • Implement CIEM (Cloud Infrastructure Entitlement Management) tooling to continuously detect toxic combinations of cross-project permissions
  • Migrate Cloud Build deployments off the legacy default (Compute Engine / Cloud Build) service account to scoped custom service accounts
  • Deploy VPC Service Controls org-wide perimeters and egress access levels to block unauthorized cross-organization data movement

Affected and fixed versions

  • Google — Google Cloud Platform - Compute Engine Images
    Vulnerable versions: all versions using cross-project IAM with over-broad compute.imageUser/compute.admin grants
    Fixed in: N/A - misconfiguration class, not a software version issue
  • Google — Google Cloud Platform - Cloud Build
    Vulnerable versions: projects using default Cloud Build service account with project-editor-equivalent permissions (pre-2024 default behavior)
    Fixed in: projects configured to use custom scoped service accounts or the reduced-privilege Compute Engine default service account for Cloud Build, per Google's 2024 default-behavior change
  • Google — Google Cloud Storage
    Vulnerable versions: buckets without VPC Service Controls perimeters restricting cross-organization IAM bindings
    Fixed in: N/A - mitigated via VPC Service Controls / org policy, not a patch

Timeline of GCP cross-project image exfiltration

  • Rhino Security Labs documents 'Working-As-Intended' RCE-to-IAM privilege escalation via GCP Cloud Build, establishing Cloud Build as a known privilege-escalation vector referenced by the exfiltration chain.
  • Praetorian publishes research cataloguing GCP service-account-based privilege escalation paths relevant to the locked-ioc-14/locked-ioc-15 pivot used in this chain.
  • Mitiga publishes 'locked-ioc-7 Exfiltration: A Threat Hunting Guide' detailing the fictional Eve-vs-Bob cross-project compute image exfiltration walkthrough.
  • Orca Security discloses 'Bad.Build' (ConfusedFunction), a critical design flaw in the default GCP Cloud Build service account enabling privilege escalation and supply-chain code tampering.
  • CSO Online and Dark Reading report on the Bad.Build Cloud Build flaw and its implications for build-pipeline abuse in GCP environments.
  • Google begins rolling out (through June 2024) a change to Cloud Build's default service account behavior: new projects running their first build now use the reduced-privilege Compute Engine default service account instead of the legacy Cloud Build service account with broad project-editor-equivalent permissions; existing projects that had already run builds remain on the legacy account unless migrated.
  • wagov/wasocshared publishes a community security advisory summarizing the GCP Cloud Build privilege-escalation vulnerability class for SOC consumption.
  • PwnedLabs publishes 'Exploiting GCP Cloud Build for Privilege Escalation', detailing how write access to a linked source repository lets an attacker modify cloudbuild.yaml to exfiltrate the build service account's OAuth token via the metadata endpoint and pivot to cloudbuild.builds.create-based trigger abuse -- a related Cloud Build service-account abuse primitive referenced by this exfiltration chain.
  • TL-Intel-Harness ingests the Mitiga guide via RSS hunt phase and opens TL-2026-1648 as a detection-focused threat skeleton (no CVE, PoC tutorial, no confirmed in-the-wild campaign).

Sources cited for GCP cross-project image exfiltration

Drafted by the Threadlinqs research pipeline from 9 sources; published ; last updated —.

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level

Latest Threats