Cyber Defense Advisors

Attackers can abuse Google Cloud Build to poison production environments

Researchers warn that a permission associated with the Google Cloud Build service in Google Cloud can be easily abused by attackers with access to a regular account to elevate their privileges and potentially poison container images used in production environments. Google Cloud Build is a CI/CD platform that allows organizations and developers to execute code building tasks on Google Cloud in a variety of programming languages. The service supports importing source code from repositories and cloud storage locations, builds the code based on a configured specification, and produces artifacts such as container images that can be deployed directly into production environments.

Cloud Build integrates with other Google Cloud services such as Artifact Registry, Google Kubernetes Engine, and App Engine. As such, it has powerful capabilities and access. Some predefined user roles in Google Cloud already include some of the permissions needed to invoke Cloud Build service features, but some of these permissions can also be individually assigned to users, groups, and service accounts.

One of these permissions that researchers from Orca Security found can be abused for privilege escalation is called cloudbuild.builds.create. As the name implies, it can be used to create new builds using the Cloud Build Service. An organization having users with this permission would be very reasonable in an environment that uses Cloud Build as the main CI/CD platform, the Orca researchers said. In fact several default roles have it, including admin-level roles but also developer-related roles such as dataflow.developer.

Privilege escalation leading to a supply chain compromise

In a supply chain attack scenario, an attacker with access to a lower privileged account would attempt to find a path that grants them access to either source code or resources, such as binary artifacts, that an organization uses to develop and build their apps before they’re deployed. According to Orca Security, the cloudbuild.builds.create permission does just that.

“By abusing this flaw that enables the impersonation of the default Cloud Build service account, an attacker can manipulate images in Google’s Artifact Registry and inject malicious code,” the Orca researchers said. “Any applications built from the manipulated images are then affected, with potential outcomes including denial-of-service (DoS) attacks, data theft, and the spread of malware. Even worse, if the malformed applications are meant to be deployed on customer’s environments (either on-premises or semi-SaaS), the risk crosses from the supplying organization’s environment to their customers’ environments, constituting a supply chain attack, similar to what happened in the SolarWinds and MOVEit incidents.”

The Orca researchers named their proof-of-concept attack vector Bad.Builds, but they actually came across it while investigating another issue. They observed that whenever the setIamPolicy API method was used to update access to a Google Cloud Platform (GCP) resource, all the project’s permissions were included in the message body and were saved in the audit log.

The researchers realized that knowing exactly who has access to what resource inside a project could be very valuable information for an attacker to have to find ways to perform privilege escalation or lateral movement inside an environment. They then wondered what roles could list and view the audit logs and were not administrative ones and one captured their attention: cloudbuild.builds.builder — the role associated with the Cloud Build service account.

From here they looked into what permission is needed to invoke the Cloud Build service and how it might be used to perform the logging.privateLogEntries.list action that is needed to read the audit log. That’s how they came across the cloudbuild.builds.create permission and the predefined roles that have it:

roles/cloudbuild.builds.builder
roles/cloudbuild.builds.editor
roles/composer.worker
roles/dataflow.admin
roles/dataflow.developer
roles/appengineflex.serviceAgent
roles/cloudbuild.serviceAgent
roles/cloudconfig.serviceAgent
roles/clouddeploy.serviceAgent
roles/cloudfunctions.serviceAgent
roles/datapipelines.serviceAgent
roles/dataprep.serviceAgent
roles/run.serviceAgent
roles/runapps.serviceAgent
roles/serverless.serviceAgent

The researchers created a service account called roin-svc for testing and assigned it the dataflow.developer role. They then leveraged the cloudbuild.builds.create permission to start a new build configuration and have the Cloud Build service use its own permissions to call setIamPolicy and then record the response as part of its build event log in a remote bucket specified as part of the build configuration.

In this way, even though the Dataflow Developer role didn’t have the permissions to read the audit log, it was able to leverage the Cloud Build service to do the job for it and receive a list of all the project’s permissions. After reporting this issue to Google, the company removed the logging.privateLogEntries.list action from the Cloud Build service so using it in this way is no longer possible.

However, leveraging the cloudbuild.builds.create permission to initiate new builds and perform any other actions that Cloud Build still has access to remains possible because this is by design. There are many powerful API calls, including to access and manipulate files in the Artifacts Registry such as container images, as well as creating, listing and deleting storage buckets and storage objects inside those buckets.

Manipulating Google Cloud artifacts

The PoC scenario that Orca developed and documented in its report focuses on the Artifact Registry. First, attackers need to obtain access to an account that has the ability to create new builds, which can be achieved through a stolen or leaked access token. Then they can impersonate the Cloud Build Service Account and escalate privileges and run API calls against the Artifact Registry.

Using the Cloud Build permissions associated with Artifact Registry attackers can locate and extract a container image that’s used inside the Google Kubernetes Engine (GKE). They can then modify it locally, inject into it malicious code such as a web shell, and upload it back to the registry. Once the malicious image is deployed automatically by GKE, the attacker can leverage the backdoor remotely and execute commands inside the Docker container as root.

“The potential impact can be diverse, and applies to all organizations that are using the Artifact Registry as their main or secondary image repository,” the researchers said. “Now that we know that the cloudbuild.builds.create permission grants all the permissions of the Cloud Build Service Account, it’s important for security teams to be very aware of which accounts are entitled to this. If one is compromised, the consequences can be immense.”

To further limit risk, Orca recommends that Google Cloud Platform users restrict the default permissions granted to the Cloud Build Service account to only the specific actions they need and use in their workflows based on the principle of least privilege.

Cloud Security, Vulnerabilities