mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-23 07:29:04 -08:00
Recreating repository history for branch master
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
# GCP <--> Workspace Pivoting
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
## **From GCP to GWS**
|
||||
|
||||
### **Domain Wide Delegation basics**
|
||||
|
||||
Google Workspace's Domain-Wide delegation allows an identity object, either an **external app** from Google Workspace Marketplace or an internal **GCP Service Account**, to **access data across the Workspace on behalf of users**.
|
||||
|
||||
{% hint style="info" %}
|
||||
This basically means that **service accounts** inside GCP projects of an organization might be able to i**mpersonate Workspace users** of the same organization (or even from a different one).
|
||||
{% endhint %}
|
||||
|
||||
For more information about how this exactly works check:
|
||||
|
||||
{% content-ref url="gcp-understanding-domain-wide-delegation.md" %}
|
||||
[gcp-understanding-domain-wide-delegation.md](gcp-understanding-domain-wide-delegation.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Compromise existing delegation
|
||||
|
||||
If an attacker **compromised some access over GCP** and **known a valid Workspace user email** (preferably **super admin**) of the company, he could **enumerate all the projects** he has access to, **enumerate all the SAs** of the projects, check to which **service accounts he has access to**, and **repeat** all these steps with each SA he can impersonate.\
|
||||
With a **list of all the service accounts** he has **access** to and the list of **Workspace** **emails**, the attacker could try to **impersonate user with each service account**.
|
||||
|
||||
{% hint style="danger" %}
|
||||
Note that when configuring the domain wide delegation no Workspace user is needed, therefore just know **one valid one is enough and required for the impersonation**.\
|
||||
However, the **privileges of the impersonated user will be used**, so if it's Super Admin you will be able to access everything. If it doesn't have any access this will be useless.
|
||||
{% endhint %}
|
||||
|
||||
#### [GCP Generate Delegation Token](https://github.com/carlospolop/gcp_gen_delegation_token)
|
||||
|
||||
This simple script will **generate an OAuth token as the delegated user** that you can then use to access other Google APIs with or without `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)
|
||||
|
||||
This is a tool that can perform the attack following these steps:
|
||||
|
||||
1. **Enumerate GCP Projects** using Resource Manager API.
|
||||
2. Iterate on each project resource, and **enumerate GCP Service account resources** to which the initial IAM user has access using _GetIAMPolicy_.
|
||||
3. Iterate on **each service account role**, and find built-in, basic, and custom roles with _**serviceAccountKeys.create**_ permission on the target service account resource. It should be noted that the Editor role inherently possesses this permission.
|
||||
4. Create a **new `KEY_ALG_RSA_2048`** private key to each service account resource which is found with relevant permission in the IAM policy.
|
||||
5. Iterate on **each new service account and create a `JWT`** **object** for it which is composed of the SA private key credentials and an OAuth scope. The process of creating a new _JWT_ object will **iterate on all the existing combinations of OAuth scopes** from **oauth\_scopes.txt** list, in order to find all the delegation possibilities. The list **oauth\_scopes.txt** is updated with all of the OAuth scopes we’ve found to be relevant for abusing Workspace identities.
|
||||
6. The `_make_authorization_grant_assertion` method reveals the necessity to declare a t**arget workspace user**, referred to as _subject_, for generating JWTs under DWD. While this may seem to require a specific user, it's important to realize that **DWD influences every identity within a domain**. Consequently, creating a JWT for **any domain user** affects all identities in that domain, consistent with our combination enumeration check. Simply put, one valid Workspace user is adequate to move forward.\
|
||||
This user can be defined in DeleFriend’s _config.yaml_ file. If a target workspace user is not already known, the tool facilitates the automatic identification of valid workspace users by scanning domain users with roles on GCP projects. It's key to note (again) that JWTs are domain-specific and not generated for every user; hence, the automatic process targets a single unique identity per domain.
|
||||
7. **Enumerate and create a new bearer access token** for each JWT and validate the token against tokeninfo API.
|
||||
|
||||
#### [Gitlab's Python script](https://gitlab.com/gitlab-com/gl-security/threatmanagement/redteam/redteam-public/gcp_misc/-/blob/master/gcp_delegation.py)
|
||||
|
||||
Gitlab've created [this Python script](https://gitlab.com/gitlab-com/gl-security/gl-redteam/gcp_misc/blob/master/gcp_delegation.py) that can do two things - list the user directory and create a new administrative account while indicating a json with SA credentials and the user to impersonate. Here is how you would use it:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### Create a new delegation (Persistence)
|
||||
|
||||
It's possible to **check Domain Wide Delegations in** [**https://admin.google.com/u/1/ac/owl/domainwidedelegation**](https://admin.google.com/u/1/ac/owl/domainwidedelegation)**.**
|
||||
|
||||
An attacker with the ability to **create service accounts in a GCP project** and **super admin privilege to GWS could create a new delegation allowing SAs to impersonate some GWS users:**
|
||||
|
||||
1. **Generating a New Service Account and Corresponding Key Pair:** On GCP, new service account resources can be produced either interactively via the console or programmatically using direct API calls and CLI tools. This requires the **role `iam.serviceAccountAdmin`** or any custom role equipped with the **`iam.serviceAccounts.create`** **permission**. Once the service account is created, we'll proceed to generate a **related key pair** (**`iam.serviceAccountKeys.create`** permission).
|
||||
2. **Creation of new delegation**: It's important to understand that **only the Super Admin role possesses the capability to set up global Domain-Wide delegation in Google Workspace** and Domain-Wide delegation **cannot be set up programmatically,** It can only be created and adjusted **manually** through the Google Workspace **console**.
|
||||
* The creation of the rule can be found under the page **API controls → Manage Domain-Wide delegation in Google Workspace Admin console**.
|
||||
3. **Attaching OAuth scopes privilege**: When configuring a new delegation, Google requires only 2 parameters, the Client ID, which is the **OAuth ID of the GCP Service Account** resource, and **OAuth scopes** that define what API calls the delegation requires.
|
||||
* The **full list of OAuth scopes** can be found [**here**](https://developers.google.com/identity/protocols/oauth2/scopes), but here is a recommendation: `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. **Acting on behalf of the target identity:** At this point, we have a functioning delegated object in GWS. Now, **using the GCP Service Account private key, we can perform API calls** (in the scope defined in the OAuth scope parameter) to trigger it and **act on behalf of any identity that exists in Google Workspace**. As we learned, the service account will generate access tokens per its needs and according to the permission he has to REST API applications.
|
||||
* Check the **previous section** for some **tools** to use this delegation.
|
||||
|
||||
#### Cross-Organizational delegation
|
||||
|
||||
OAuth SA ID is global and can be used for **cross-organizational delegation**. There has been no restriction implemented to prevent cross-global delegation. In simple terms, **service accounts from different GCP organizations can be used to configure domain-wide delegation on other Workspace organizations**. This would result in **only needing Super Admin access to Workspace**, and not access to the same GCP account, as the adversary can create Service Accounts and private keys on his personally controlled GCP account.
|
||||
|
||||
### Creating a Project to enumerate Workspace
|
||||
|
||||
By **default** Workspace **users** have the permission to **create new projects**, and when a new project is created the **creator gets the Owner role** over it.
|
||||
|
||||
Therefore, a user can **create a project**, **enable** the **APIs** to enumerate Workspace in his new project and try to **enumerate** it.
|
||||
|
||||
{% hint style="danger" %}
|
||||
In order for a user to be able to enumerate Workspace he also needs enough Workspace permissions (not every user will be able to enumerate the directory).
|
||||
{% endhint %}
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```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>
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Check **more enumeration in**:
|
||||
|
||||
{% content-ref url="../gcp-services/gcp-iam-and-org-policies-enum.md" %}
|
||||
[gcp-iam-and-org-policies-enum.md](../gcp-services/gcp-iam-and-org-policies-enum.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Abusing Gcloud credentials
|
||||
|
||||
You can find further information about the `gcloud` flow to login in:
|
||||
|
||||
{% content-ref url="../gcp-persistence/gcp-non-svc-persistance.md" %}
|
||||
[gcp-non-svc-persistance.md](../gcp-persistence/gcp-non-svc-persistance.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
As explained there, gcloud can request the scope **`https://www.googleapis.com/auth/drive`** which would allow a user to access the drive of the user.\
|
||||
As an attacker, if you have compromised **physically** the computer of a user and the **user is still logged** with his account you could login generating a token with access to drive using:
|
||||
|
||||
```bash
|
||||
gcloud auth login --enable-gdrive-access
|
||||
```
|
||||
|
||||
If an attacker compromises the computer of a user he could also modify the file `google-cloud-sdk/lib/googlecloudsdk/core/config.py` and add in the **`CLOUDSDK_SCOPES`** the scope **`'https://www.googleapis.com/auth/drive'`**:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (342).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="warning" %}
|
||||
Therefore, the next time the user logs in he will create a **token with access to drive** that the attacker could abuse to access the drive. Obviously, the browser will indicate that the generated token will have access to drive, but as the user will call himself the **`gcloud auth login`**, he probably **won't suspect anything.**
|
||||
|
||||
To list drive files: **`curl -H "Authorization: Bearer $(gcloud auth print-access-token)" "https://www.googleapis.com/drive/v3/files"`**
|
||||
{% endhint %}
|
||||
|
||||
## From GWS to GCP
|
||||
|
||||
### Access privileged GCP users
|
||||
|
||||
If an attacker has complete access over GWS he will be able to access groups with privilege access over GCP or even users, therefore moving from GWS to GCP is usually more "simple" just because **users in GWS have high privileges over GCP**.
|
||||
|
||||
### Google Groups Privilege Escalation
|
||||
|
||||
By default users can **freely join Workspace groups of the Organization** and those groups **might have GCP permissions** assigned (check your groups in [https://groups.google.com/](https://groups.google.com/)).
|
||||
|
||||
Abusing the **google groups privesc** you might be able to escalate to a group with some kind of privileged access to GCP.
|
||||
|
||||
### References
|
||||
|
||||
* [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)
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
@@ -0,0 +1,54 @@
|
||||
# GCP - Understanding Domain-Wide Delegation
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
|
||||
This post is the introduction of [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) which can be accessed for more details.
|
||||
|
||||
## **Understanding Domain-Wide Delegation**
|
||||
|
||||
Google Workspace's Domain-Wide delegation allows an identity object, either an **external app** from Google Workspace Marketplace or an internal **GCP Service Account**, to **access data across the Workspace on behalf of users**. This feature, which is crucial for apps interacting with Google APIs or services needing user impersonation, enhances efficiency and minimizes human error by automating tasks. Using OAuth 2.0, app developers and administrators can give these service accounts access to user data without individual user consent.\
|
||||
\
|
||||
Google Workspace allows the creation of two main types of global delegated object identities:
|
||||
|
||||
* **GWS Applications:** Applications from the Workspace Marketplace can be set up as a delegated identity. Before being made available in the marketplace, each Workspace application undergoes a review by Google to minimize potential misuse. While this does not entirely eliminate the risk of abuse, it significantly increases the difficulty for such incidents to occur.
|
||||
* **GCP Service Account:** Learn more about [**GCP Service Accounts here**](../gcp-basic-information/#service-accounts).
|
||||
|
||||
### **Domain-Wide Delegation: Under the Hood**
|
||||
|
||||
This is how a GCP Service Account can access Google APIs on behalf of other identities in Google Workspace:
|
||||
|
||||
<figure><img src="../../../.gitbook/assets/image (58).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
1. **Identity creates a JWT:** The Identity uses the service account's private key (part of the JSON key pair file) to sign a JWT. This JWT contains claims about the service account, the target user to impersonate, and the OAuth scopes of access to the REST API which is being requested.
|
||||
2. **The Identity uses the JWT to request an access token:** The application/user uses the JWT to request an access token from Google's OAuth 2.0 service. The request also includes the target user to impersonate (the user's Workspace email), and the scopes for which access is requested.
|
||||
3. **Google's OAuth 2.0 service returns an access token:** The access token represents the service account's authority to act on behalf of the user for the specified scopes. This token is typically short-lived and must be refreshed periodically (per the application's need). It's essential to understand that the OAuth scopes specified in the JWT token have validity and impact on the resultant access token. For instance, access tokens possessing multiple scopes will hold validity for numerous REST API applications.
|
||||
4. **The Identity uses the access token to call Google APIs**: Now with a relevant access token, the service can access the required REST API. The application uses this access token in the "Authorization" header of its HTTP requests destined for Google APIs. These APIs utilize the token to verify the impersonated identity and confirm it has the necessary authorization.
|
||||
5. **Google APIs return the requested data**: If the access token is valid and the service account has appropriate authorization, the Google APIs return the requested data. For example, in the following picture, we’ve leveraged the _users.messages.list_ method to list all the Gmail message IDs associated with a target Workspace user.
|
||||
|
||||
{% hint style="success" %}
|
||||
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
||||
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Support HackTricks</summary>
|
||||
|
||||
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
|
||||
</details>
|
||||
{% endhint %}
|
||||
Reference in New Issue
Block a user