# GCP Cross-Project Compute Image Exfiltration via Compromised Developer Credentials

> 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.

- **Published:** 2026-07-23T00:00:00Z
- **Last reviewed:** 2026-07-23T00:00:00Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-1648
- **Card image:** https://intel.threadlinqs.com/og/threat/threat-intel-gcp-cross-project-image-exfiltration-tl-2026-1648.webp?v=ca46f380 (Threadlinqs threat intel: GCP Compute Image Exfiltration Chain: Detection & IOCs (TL-2026-1648) — High severity, 18 IOCs, 9 detection rules.)
- **ID:** TL-2026-1648
- **Severity:** HIGH
- **Category:** CLOUD
- **Status:** ACTIVE
- **Detections:** 9 (1 shown free below) · **IOCs:** 18

## Description

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

- T1566 Phishing
- T1078.004 Cloud Accounts
- T1111 Multi-Factor Authentication Interception
- T1621 Multi-Factor Authentication Request Generation
- T1069.003 Cloud Groups
- T1526 Cloud Service Discovery
- T1580 Cloud Infrastructure Discovery
- T1078.004 Cloud Accounts
- T1548 Abuse Elevation Control Mechanism
- T1078.004 Cloud Accounts
- T1550 Use Alternate Authentication Material
- T1530 Data from Cloud Storage
- T1119 Automated Collection
- T1537 Transfer Data to Cloud Account
- T1567.002 Exfiltration to Cloud Storage
- T1020 Automated Exfiltration
- T1565 Data Manipulation
- T1583.007 Serverless

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**GCP Cross-Organization Storage Object Write to External Bucket** (`TL-2026-1648-SPL-003`)

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

```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

```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

```yaml
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

- GCP Cross-Project Compute Image Copy — Sentinel Detection (locked: unlock with TL Creds)
- GCP Cloud Build Default Service Account Abuse for Image Export — Sentinel (locked: unlock with TL Creds)
- GCP Storage Metadata-Read Immediately Followed by External-Org Bucket Enumeration (locked: unlock with TL Creds)
- GCP Cross-Project Compute Image Copy — Sigma Rule (locked: unlock with TL Creds)
- GCP Cloud Build API Enabled Then Immediately Used for Image Export — Sigma Rule (locked: unlock with TL Creds)
- GCP IAM Grant of [indicator] to External-Organization Bucket for a [indicator] Principal (locked: unlock with TL Creds)
- GCP Cross-Project Compute Image Copy — sourceImage/resourceName Project Mismatch (locked: unlock with TL Creds)
- GCP Cloud Build API Enable Immediately Followed by Image Export (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sources

- [Google Cloud Platform Exfiltration: A Threat Hunting Guide](https://www.mitiga.io/blog/google-cloud-platform-exfiltration-a-threat-hunting-guide)
- [Transfer Data to Cloud Account, Technique T1537 - Enterprise | MITRE ATT&CK](https://attack.mitre.org/techniques/T1537/)
- [Valid Accounts: Cloud Accounts, Sub-technique T1078.004 - Enterprise | MITRE ATT&CK](https://attack.mitre.org/techniques/T1078/004/)
- [Bad.Build: A Critical Privilege Escalation Design Flaw in Google Cloud Build Enables a Supply Chain Attack](https://orca.security/resources/blog/bad-build-google-cloud-build-potential-supply-chain-attack-vulnerability/)
- [Exploiting GCP Cloud Build for Privilege Escalation](https://blog.pwnedlabs.io/exploiting-gcp-cloud-build-for-privilege-escalation)
- [Google Cloud Build Flaw Enables Privilege Escalation, Code Tampering](https://www.darkreading.com/application-security/design-flaw-in-google-cloud-build-enables-privilege-escalation-code-tampering)
- [Attackers can abuse Google Cloud Build to poison production environments](https://www.csoonline.com/article/646616/attackers-can-abuse-google-cloud-build-to-poison-production-environments.html)
- [Google Cloud Platform (GCP) Service Account-based Privilege Escalation paths](https://www.praetorian.com/blog/google-cloud-platform-gcp-service-account-based-privilege-escalation-paths/)
- [Working-As-Intended: RCE to IAM Privilege Escalation in GCP Cloud Build](https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-1648
