# GCP <--> Workspace ピボット

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

## **GCP から GWS へ**

### **ドメイン全体の委任の基本**

Google Workspace のドメイン全体の委任は、**外部アプリ**（Google Workspace Marketplace から）または内部の **GCP サービスアカウント** のいずれかのアイデンティティオブジェクトが、**ユーザーに代わって Workspace 全体のデータにアクセスする**ことを可能にします。

> [!NOTE]
> これは基本的に、**GCP プロジェクト内のサービスアカウント**が、同じ組織の **Workspace ユーザー**（または異なる組織のユーザー）を**なりすます**ことができる可能性があることを意味します。

これがどのように機能するかの詳細については、次を確認してください：

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

### 既存の委任の侵害

攻撃者が **GCP 上のアクセスを侵害し**、会社の有効な Workspace ユーザーのメールアドレス（できれば **スーパ管理者**）を**知っている**場合、彼は **アクセスできるすべてのプロジェクトを列挙し**、**プロジェクトのすべての SA を列挙し**、**アクセスできるサービスアカウントを確認し**、**なりすますことができる各 SA でこれらのステップを繰り返す**ことができます。\
彼が **アクセスできるすべてのサービスアカウントのリスト**と **Workspace** **メールのリスト**を持っていれば、攻撃者は **各サービスアカウントでユーザーをなりすます**ことを試みることができます。

> [!CAUTION]
> ドメイン全体の委任を構成する際には、Workspace ユーザーは必要ないため、**有効なユーザーが1人いれば十分で、なりすましに必要です**。\
> ただし、**なりすましたユーザーの権限が使用される**ため、スーパ管理者であればすべてにアクセスできるようになります。アクセス権がない場合は無意味になります。

#### [GCP 生成委任トークン](https://github.com/carlospolop/gcp_gen_delegation_token)

このシンプルなスクリプトは、**委任されたユーザーとして OAuth トークンを生成**し、その後 `gcloud` の有無にかかわらず他の Google API にアクセスするために使用できます：
```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"
```
#### [**DelePwn**](https://github.com/n0tspam/delepwn)

以下のDeleFriendツールに基づいていますが、ドメイン、ドライブ、Gmail、カレンダーを列挙し、他の操作を実行する機能などの追加があります。

#### [**DeleFriend**](https://github.com/axon-git/DeleFriend)

これは、次の手順に従って攻撃を実行できるツールです：

1. **GCPプロジェクトを列挙**します。Resource Manager APIを使用します。
2. 各プロジェクトリソースを反復処理し、初期IAMユーザーがアクセスできる**GCPサービスアカウントリソースを列挙**します。_GetIAMPolicy_を使用します。
3. **各サービスアカウントロールを反復処理**し、ターゲットサービスアカウントリソースに対して_**serviceAccountKeys.create**_権限を持つ組み込み、基本、およびカスタムロールを見つけます。Editorロールは本質的にこの権限を持っていることに注意が必要です。
4. IAMポリシーで関連する権限が見つかった各サービスアカウントリソースに対して**新しい`KEY_ALG_RSA_2048`**プライベートキーを作成します。
5. **各新しいサービスアカウントを反復処理し、`JWT`** **オブジェクト**を作成します。これはSAプライベートキーの資格情報とOAuthスコープで構成されます。新しい_JWT_オブジェクトを作成するプロセスは、**oauth_scopes.txt**リストからのすべての既存のOAuthスコープの組み合わせを反復処理し、すべての委任の可能性を見つけます。リスト**oauth_scopes.txt**は、Workspaceアイデンティティを悪用するために関連性があると見なされたすべてのOAuthスコープで更新されます。
6. `_make_authorization_grant_assertion`メソッドは、DWDの下でJWTを生成するために**ターゲットワークスペースユーザー**を宣言する必要性を明らかにします。これは_subject_として言及されます。特定のユーザーが必要に見えるかもしれませんが、**DWDはドメイン内のすべてのアイデンティティに影響を与える**ことを理解することが重要です。したがって、**任意のドメインユーザー**のためにJWTを作成することは、そのドメイン内のすべてのアイデンティティに影響を与え、組み合わせ列挙チェックと一致します。要するに、有効なWorkspaceユーザー1人で進むことができます。\
このユーザーはDeleFriendの_config.yaml_ファイルで定義できます。ターゲットワークスペースユーザーが既に知られていない場合、ツールはGCPプロジェクトで役割を持つドメインユーザーをスキャンすることによって有効なワークスペースユーザーの自動識別を促進します。再度重要な点は、JWTはドメイン固有であり、すべてのユーザーのために生成されるわけではないため、自動プロセスはドメインごとに1つのユニークなアイデンティティをターゲットにします。
7. **各JWTのために新しいベアラートークンを列挙して作成**し、tokeninfo APIに対してトークンを検証します。

#### [GitlabのPythonスクリプト](https://gitlab.com/gitlab-com/gl-security/threatmanagement/redteam/redteam-public/gcp_misc/-/blob/master/gcp_delegation.py)

Gitlabは、ユーザーディレクトリをリストし、SA資格情報と偽装するユーザーを示すjsonを指定しながら新しい管理アカウントを作成できる[このPythonスクリプト](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_misc/blob/master/gcp_delegation.py)を作成しました。使用方法は次のとおりです：
```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
```
### 新しい委任を作成する (持続性)

**ドメイン全体の委任を確認することが可能です** [**https://admin.google.com/u/1/ac/owl/domainwidedelegation**](https://admin.google.com/u/1/ac/owl/domainwidedelegation)**.**

**GCPプロジェクトでサービスアカウントを作成する能力**と**GWSに対するスーパー管理者権限を持つ攻撃者は、SAsがいくつかのGWSユーザーを偽装できる新しい委任を作成することができます:**

1. **新しいサービスアカウントと対応するキー ペアの生成:** GCPでは、新しいサービスアカウントリソースは、コンソールを介して対話的に、または直接API呼び出しやCLIツールを使用してプログラム的に生成できます。これには、**`iam.serviceAccountAdmin`**の役割または**`iam.serviceAccounts.create`** **権限**を持つカスタムロールが必要です。サービスアカウントが作成されると、**関連するキー ペア**を生成します（**`iam.serviceAccountKeys.create`**権限）。
2. **新しい委任の作成:** **Google Workspaceでグローバルなドメイン全体の委任を設定できるのはスーパー管理者ロールのみであることを理解することが重要です**。ドメイン全体の委任は**プログラム的に設定できず、**Google Workspaceの**コンソール**を通じて手動で作成および調整する必要があります。
- ルールの作成は、**APIコントロール → Google Workspace管理コンソールでのドメイン全体の委任の管理**のページにあります。
3. **OAuthスコープ権限の添付:** 新しい委任を構成する際、GoogleはクライアントID（**GCPサービスアカウント**リソースの**OAuth ID**）と、委任が必要とするAPI呼び出しを定義する**OAuthスコープ**の2つのパラメータのみを要求します。
- **OAuthスコープの完全なリスト**は[**こちら**](https://developers.google.com/identity/protocols/oauth2/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`
4. **ターゲットアイデンティティの代理として行動する:** この時点で、GWSに機能する委任オブジェクトがあります。今、**GCPサービスアカウントの秘密鍵を使用してAPI呼び出しを行うことができ**（OAuthスコープパラメータで定義されたスコープ内で）、**Google Workspaceに存在する任意のアイデンティティの代理として行動することができます**。サービスアカウントは、そのニーズに応じて、REST APIアプリケーションに対する権限に従ってアクセストークンを生成します。
- この委任を使用するための**ツール**については**前のセクション**を確認してください。

#### 組織間委任

OAuth SA IDはグローバルであり、**組織間委任**に使用できます。クロスグローバル委任を防ぐための制限は実装されていません。簡単に言えば、**異なるGCP組織のサービスアカウントを使用して、他のWorkspace組織でドメイン全体の委任を構成することができます**。これにより、**Workspaceへのスーパー管理者アクセスのみが必要となり、同じGCPアカウントへのアクセスは不要です**。攻撃者は、自身が管理するGCPアカウントでサービスアカウントと秘密鍵を作成できます。

### Workspaceを列挙するためのプロジェクトの作成

**デフォルトで**、Workspace **ユーザー**は**新しいプロジェクトを作成する権限**を持っており、新しいプロジェクトが作成されると、**作成者はそのプロジェクトに対してオーナー権限を取得します**。

したがって、ユーザーは**プロジェクトを作成し、**新しいプロジェクトでWorkspaceを列挙するために**APIを有効にし、列挙を試みることができます**。

> [!CAUTION]
> ユーザーがWorkspaceを列挙できるようにするには、十分なWorkspace権限も必要です（すべてのユーザーがディレクトリを列挙できるわけではありません）。
```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>
```
チェック **さらなる列挙について**:

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

### Gcloud資格情報の悪用

`gcloud`のログインフローに関する詳細情報は以下で確認できます:

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

そこで説明されているように、gcloudは**`https://www.googleapis.com/auth/drive`**のスコープを要求することができ、これによりユーザーのドライブにアクセスすることが可能になります。\
攻撃者として、もしあなたがユーザーのコンピュータを**物理的に**侵害し、**ユーザーがまだ**自分のアカウントでログインしている場合、次のコマンドを使用してドライブへのアクセス権を持つトークンを生成してログインすることができます:
```bash
gcloud auth login --enable-gdrive-access
```
攻撃者がユーザーのコンピュータを侵害した場合、`google-cloud-sdk/lib/googlecloudsdk/core/config.py`ファイルを変更し、**`CLOUDSDK_SCOPES`**にスコープ**`'https://www.googleapis.com/auth/drive'`**を追加することができます。

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

> [!WARNING]
> したがって、ユーザーが次回ログインすると、攻撃者がドライブにアクセスするために悪用できる**ドライブへのアクセス権を持つトークン**が作成されます。もちろん、ブラウザは生成されたトークンがドライブへのアクセス権を持つことを示しますが、ユーザーが自ら**`gcloud auth login`**を呼び出すため、彼はおそらく**何も疑わないでしょう。**
>
> ドライブファイルをリストするには: **`curl -H "Authorization: Bearer $(gcloud auth print-access-token)" "https://www.googleapis.com/drive/v3/files"`**

## GWSからGCPへ

### 特権GCPユーザーへのアクセス

攻撃者がGWSに完全にアクセスできる場合、GCPに対して特権アクセスを持つグループやユーザーにアクセスできるため、GWSからGCPへの移行は通常「簡単」です。なぜなら、**GWSのユーザーはGCPに対して高い特権を持っているからです**。

### Googleグループの特権昇格

デフォルトでは、ユーザーは**組織のWorkspaceグループに自由に参加できます**。これらのグループには**GCPの権限**が割り当てられている可能性があります（[https://groups.google.com/](https://groups.google.com/)でグループを確認してください）。

**google groups privesc**を悪用することで、GCPに対して何らかの特権アクセスを持つグループに昇格できるかもしれません。

### 参考文献

- [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}}
