# GCP <--> Workspace Pivoting

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

## **De GCP à GWS**

### **Bases de la délégation à l'échelle du domaine**

La délégation à l'échelle du domaine de Google Workspace permet à un objet d'identité, soit une **application externe** du Google Workspace Marketplace, soit un **compte de service GCP** interne, d'**accéder aux données à travers le Workspace au nom des utilisateurs**.

> [!NOTE]
> Cela signifie essentiellement que les **comptes de service** à l'intérieur des projets GCP d'une organisation pourraient être capables d'**usurper l'identité des utilisateurs de Workspace** de la même organisation (ou même d'une autre).

Pour plus d'informations sur le fonctionnement exact de cela, consultez :

{{#ref}}
gcp-understanding-domain-wide-delegation.md
{{#endref}}

### Compromettre une délégation existante

Si un attaquant **compromettait un accès sur GCP** et **connaissait un email d'utilisateur Workspace valide** (de préférence **super admin**) de l'entreprise, il pourrait **énumérer tous les projets** auxquels il a accès, **énumérer tous les comptes de service** des projets, vérifier à quels **comptes de service il a accès**, et **répéter** toutes ces étapes avec chaque compte de service qu'il peut usurper.\
Avec une **liste de tous les comptes de service** auxquels il a **accès** et la liste des **emails Workspace**, l'attaquant pourrait essayer d'**usurper l'identité de l'utilisateur avec chaque compte de service**.

> [!CAUTION]
> Notez que lors de la configuration de la délégation à l'échelle du domaine, aucun utilisateur Workspace n'est nécessaire, donc il suffit de **connaître un valide pour l'usurpation**.\
> Cependant, les **privilèges de l'utilisateur usurpé seront utilisés**, donc s'il s'agit d'un Super Admin, vous pourrez accéder à tout. S'il n'a aucun accès, cela sera inutile.

#### [GCP Generate Delegation Token](https://github.com/carlospolop/gcp_gen_delegation_token)

Ce script simple va **générer un token OAuth en tant qu'utilisateur délégué** que vous pouvez ensuite utiliser pour accéder à d'autres API Google avec ou sans `gcloud`:
```bash
# Impersonate indicated user
python3 gen_delegation_token.py --user-email <user-email> --key-file <path-to-key-file>

# Impersonate indicated user and add additional scopes
python3 gen_delegation_token.py --user-email <user-email> --key-file <path-to-key-file> --scopes "https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/cloud-platform, https://www.googleapis.com/auth/admin.directory.group, https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.domain, https://mail.google.com/, https://www.googleapis.com/auth/drive, openid"
```
#### [**DeleFriend**](https://github.com/axon-git/DeleFriend)

Ceci est un outil qui peut effectuer l'attaque en suivant ces étapes :

1. **Énumérer les projets GCP** en utilisant l'API Resource Manager.
2. Itérer sur chaque ressource de projet, et **énumérer les ressources de compte de service GCP** auxquelles l'utilisateur IAM initial a accès en utilisant _GetIAMPolicy_.
3. Itérer sur **chaque rôle de compte de service**, et trouver les rôles intégrés, de base et personnalisés avec la permission _**serviceAccountKeys.create**_ sur la ressource de compte de service cible. Il convient de noter que le rôle d'éditeur possède intrinsèquement cette permission.
4. Créer une **nouvelle clé privée `KEY_ALG_RSA_2048`** pour chaque ressource de compte de service qui est trouvée avec la permission pertinente dans la politique IAM.
5. Itérer sur **chaque nouveau compte de service et créer un objet `JWT`** pour celui-ci qui est composé des informations d'identification de la clé privée SA et d'un champ OAuth. Le processus de création d'un nouvel objet _JWT_ **itérera sur toutes les combinaisons existantes de champs OAuth** de la liste **oauth_scopes.txt**, afin de trouver toutes les possibilités de délégation. La liste **oauth_scopes.txt** est mise à jour avec tous les champs OAuth que nous avons trouvés pertinents pour abuser des identités Workspace.
6. La méthode `_make_authorization_grant_assertion` révèle la nécessité de déclarer un **utilisateur de workspace cible**, appelé _subject_, pour générer des JWT sous DWD. Bien que cela puisse sembler nécessiter un utilisateur spécifique, il est important de réaliser que **DWD influence chaque identité au sein d'un domaine**. Par conséquent, créer un JWT pour **tout utilisateur de domaine** affecte toutes les identités dans ce domaine, conformément à notre vérification d'énumération de combinaison. En d'autres termes, un utilisateur Workspace valide est suffisant pour avancer.\
Cet utilisateur peut être défini dans le fichier _config.yaml_ de DeleFriend. Si un utilisateur de workspace cible n'est pas déjà connu, l'outil facilite l'identification automatique des utilisateurs de workspace valides en scannant les utilisateurs de domaine avec des rôles sur les projets GCP. Il est essentiel de noter (encore une fois) que les JWT sont spécifiques au domaine et ne sont pas générés pour chaque utilisateur ; par conséquent, le processus automatique cible une seule identité unique par domaine.
7. **Énumérer et créer un nouveau jeton d'accès bearer** pour chaque JWT et valider le jeton contre l'API tokeninfo.

#### [Script Python de Gitlab](https://gitlab.com/gitlab-com/gl-security/threatmanagement/redteam/redteam-public/gcp_misc/-/blob/master/gcp_delegation.py)

Gitlab a créé [ce script Python](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_misc/blob/master/gcp_delegation.py) qui peut faire deux choses - lister le répertoire des utilisateurs et créer un nouveau compte administratif tout en indiquant un json avec les informations d'identification SA et l'utilisateur à usurper. Voici comment vous l'utiliseriez :
```bash
# Install requirements
pip install --upgrade --user oauth2client

# Validate access only
./gcp_delegation.py --keyfile ./credentials.json \
--impersonate steve.admin@target-org.com \
--domain target-org.com

# List the directory
./gcp_delegation.py --keyfile ./credentials.json \
--impersonate steve.admin@target-org.com \
--domain target-org.com \
--list

# Create a new admin account
./gcp_delegation.py --keyfile ./credentials.json \
--impersonate steve.admin@target-org.com \
--domain target-org.com \
--account pwned
```
### Créer une nouvelle délégation (Persistance)

Il est possible de **vérifier les délégations à l'échelle du domaine dans** [**https://admin.google.com/u/1/ac/owl/domainwidedelegation**](https://admin.google.com/u/1/ac/owl/domainwidedelegation)**.**

Un attaquant ayant la capacité de **créer des comptes de service dans un projet GCP** et **des privilèges de super administrateur sur GWS pourrait créer une nouvelle délégation permettant aux SAs d'usurper l'identité de certains utilisateurs de GWS :**

1. **Génération d'un nouveau compte de service et d'une paire de clés correspondante :** Sur GCP, de nouvelles ressources de compte de service peuvent être produites soit de manière interactive via la console, soit de manière programmatique en utilisant des appels API directs et des outils CLI. Cela nécessite le **rôle `iam.serviceAccountAdmin`** ou tout rôle personnalisé équipé de la **permission `iam.serviceAccounts.create`**. Une fois le compte de service créé, nous procéderons à la génération d'une **paire de clés associée** (**permission `iam.serviceAccountKeys.create`**).
2. **Création d'une nouvelle délégation :** Il est important de comprendre que **seul le rôle de Super Administrateur possède la capacité de configurer une délégation à l'échelle du domaine dans Google Workspace** et que la délégation à l'échelle du domaine **ne peut pas être configurée de manière programmatique.** Elle ne peut être créée et ajustée **manuellement** via la **console** de Google Workspace.
- La création de la règle peut être trouvée sous la page **Contrôles API → Gérer la délégation à l'échelle du domaine dans la console d'administration de Google Workspace**.
3. **Attacher les privilèges des scopes OAuth :** Lors de la configuration d'une nouvelle délégation, Google nécessite seulement 2 paramètres, l'ID client, qui est l'**ID OAuth du compte de service GCP**, et les **scopes OAuth** qui définissent quels appels API la délégation nécessite.
- La **liste complète des scopes OAuth** peut être trouvée [**ici**](https://developers.google.com/identity/protocols/oauth2/scopes), mais voici une recommandation : `https://www.googleapis.com/auth/userinfo.email, https://www.googleapis.com/auth/cloud-platform, https://www.googleapis.com/auth/admin.directory.group, https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.domain, https://mail.google.com/, https://www.googleapis.com/auth/drive, openid`
4. **Agir au nom de l'identité cible :** À ce stade, nous avons un objet délégué fonctionnel dans GWS. Maintenant, **en utilisant la clé privée du compte de service GCP, nous pouvons effectuer des appels API** (dans le cadre défini dans le paramètre de scope OAuth) pour le déclencher et **agir au nom de toute identité existant dans Google Workspace**. Comme nous l'avons appris, le compte de service générera des jetons d'accès selon ses besoins et en fonction des permissions qu'il a pour les applications REST API.
- Consultez la **section précédente** pour quelques **outils** à utiliser avec cette délégation.

#### Délégation inter-organisationnelle

L'ID SA OAuth est global et peut être utilisé pour la **délégation inter-organisationnelle**. Aucune restriction n'a été mise en place pour empêcher la délégation inter-groupe. En termes simples, **les comptes de service de différentes organisations GCP peuvent être utilisés pour configurer une délégation à l'échelle du domaine sur d'autres organisations Workspace**. Cela signifierait **qu'il suffit d'un accès Super Administrateur à Workspace**, et non d'un accès au même compte GCP, car l'adversaire peut créer des comptes de service et des clés privées sur son compte GCP personnel.

### Création d'un projet pour énumérer Workspace

Par **défaut**, les **utilisateurs** de Workspace ont la permission de **créer de nouveaux projets**, et lorsqu'un nouveau projet est créé, le **créateur obtient le rôle de Propriétaire** sur celui-ci.

Par conséquent, un utilisateur peut **créer un projet**, **activer** les **API** pour énumérer Workspace dans son nouveau projet et essayer de **l'énumérer**.

> [!CAUTION]
> Afin qu'un utilisateur puisse énumérer Workspace, il a également besoin de suffisamment de permissions Workspace (tous les utilisateurs ne pourront pas énumérer le répertoire).
```bash
# Create project
gcloud projects create <uniq-projec-name> --name=proj-name
# Set project
gcloud config set project <uniq-projec-name>
# Enable svcs
gcloud services enable admin.googleapis.com
gcloud services enable cloudidentity.googleapis.com
# Get org ID
gcloud organizations list
# Get currents email user groups (at least you can check the groups and members of the groups you belong to)
gcloud identity groups memberships search-transitive-groups --member-email <email> --labels=cloudidentity.googleapis.com/groups.discussion_forum
gcloud identity groups memberships list --group-email=g<group-email>

# FROM HERE THE USER NEEDS TO HAVE ENOUGH WORKSPACE ACCESS
gcloud beta identity groups preview --customer <org-cust-id>
```
Vérifiez **plus d'énumération dans** :

{{#ref}}
../gcp-services/gcp-iam-and-org-policies-enum.md
{{#endref}}

### Abus des identifiants Gcloud

Vous pouvez trouver plus d'informations sur le flux `gcloud` pour se connecter dans :

{{#ref}}
../gcp-persistence/gcp-non-svc-persistance.md
{{#endref}}

Comme expliqué là-bas, gcloud peut demander la portée **`https://www.googleapis.com/auth/drive`** qui permettrait à un utilisateur d'accéder au drive de l'utilisateur.\
En tant qu'attaquant, si vous avez compromis **physiquement** l'ordinateur d'un utilisateur et que **l'utilisateur est toujours connecté** avec son compte, vous pourriez vous connecter en générant un jeton avec accès au drive en utilisant :
```bash
gcloud auth login --enable-gdrive-access
```
Si un attaquant compromet l'ordinateur d'un utilisateur, il pourrait également modifier le fichier `google-cloud-sdk/lib/googlecloudsdk/core/config.py` et ajouter dans le **`CLOUDSDK_SCOPES`** la portée **`'https://www.googleapis.com/auth/drive'`** :

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

> [!WARNING]
> Par conséquent, la prochaine fois que l'utilisateur se connectera, il créera un **token avec accès à drive** que l'attaquant pourrait utiliser pour accéder au drive. Évidemment, le navigateur indiquera que le token généré aura accès au drive, mais comme l'utilisateur appellera lui-même le **`gcloud auth login`**, il ne **soupçonnera probablement rien.**
>
> Pour lister les fichiers drive : **`curl -H "Authorization: Bearer $(gcloud auth print-access-token)" "https://www.googleapis.com/drive/v3/files"`**

## De GWS à GCP

### Accéder aux utilisateurs privilégiés de GCP

Si un attaquant a un accès complet à GWS, il pourra accéder à des groupes avec un accès privilégié à GCP ou même à des utilisateurs, donc passer de GWS à GCP est généralement plus "simple" simplement parce que **les utilisateurs dans GWS ont des privilèges élevés sur GCP**.

### Escalade de privilèges Google Groups

Par défaut, les utilisateurs peuvent **rejoindre librement les groupes Workspace de l'Organisation** et ces groupes **peuvent avoir des autorisations GCP** assignées (vérifiez vos groupes sur [https://groups.google.com/](https://groups.google.com/)).

En abusant de la **google groups privesc**, vous pourriez être en mesure d'escalader vers un groupe avec un certain type d'accès privilégié à GCP.

### Références

- [https://www.hunters.security/en/blog/delefriend-a-newly-discovered-design-flaw-in-domain-wide-delegation-could-leave-google-workspace-vulnerable-for-takeover](https://www.hunters.security/en/blog/delefriend-a-newly-discovered-design-flaw-in-domain-wide-delegation-could-leave-google-workspace-vulnerable-for-takeover)

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