# GCP - IAM, Principals & Org Unauthenticated Enum

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

## Iam & GCP Principals

For more information check:

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

### Is domain used in Workspace?

1. **Check DNS records**

If it has a **`google-site-verification`** record it's probable that it's (or it was) using Workspace:

```
dig txt hacktricks.xyz

[...]
hacktricks.xyz.		3600	IN	TXT	"google-site-verification=2mWyPXMPXEEy6QqWbCfWkxFTcQhyYdwHrOxee1Yeo-0"
hacktricks.xyz.		3600	IN	TXT	"google-site-verification=C19PtLcZ1EGyzUYYJTX1Tp6bOGessxzN9gqE-SVKhRA"
hacktricks.xyz.		300	IN	TXT	"v=spf1 include:usb._netblocks.mimecast.com include:_spf.google.com include:_spf.psm.knowbe4.com include:_spf.salesforce.com include:spf.mandrillapp.com ~all"
```

If something like **`include:_spf.google.com`** also appears it confirms it (note that if it doesn't appear it doesn't denies it as a domain can be in Workspace without using gmail as mail provider).

2. **Try to setup a Workspace with that domain**

Another option is to try to setup a Workspace using the domain, if it **complains that the domain is already used** (like in the image), you know it's already used!

To try to setup a Workspace domain follow: [https://workspace.google.com/business/signup/welcome](https://workspace.google.com/business/signup/welcome)

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

3. **Try to recover the password of an email using that domain**

If you know any valid email address being use din that domain (like: admin@email.com or info@email.com) you can try to **recover the account** in [https://accounts.google.com/signin/v2/recoveryidentifier](https://accounts.google.com/signin/v2/recoveryidentifier), and if try doesn't shows an error indicating that Google has no idea about that account, then it's using Workspace.

### Enumerate emails and service accounts

It's possible to **enumerate valid emails of a Workspace domain and SA emails** by trying to assign them permissions and checking the error messages. For this you just need to have permissions to assign permission to a project (which can be just owned by you).

Note that to check them but even if they exist not grant them a permission you can use the type **`serviceAccount`** when it's an **`user`** and **`user`** when it's a **`SA`**:

```bash
# Try to assign permissions to user 'unvalid-email-34r434f@hacktricks.xyz'
# but indicating it's a service account
gcloud projects add-iam-policy-binding <project-controlled-by-you> \
  --member='serviceAccount:unvalid-email-34r434f@hacktricks.xyz' \
  --role='roles/viewer'
## Response:
ERROR: (gcloud.projects.add-iam-policy-binding) INVALID_ARGUMENT: User unvalid-email-34r434f@hacktricks.xyz does not exist.

# Now try with a valid email
gcloud projects add-iam-policy-binding <project-controlled-by-you> \
  --member='serviceAccount:support@hacktricks.xyz' \
  --role='roles/viewer'
# Response:
ERROR: (gcloud.projects.add-iam-policy-binding) INVALID_ARGUMENT: Principal support@hacktricks.xyz is of type "user". The principal should appear as "user:support@hacktricks.xyz". See https://cloud.google.com/iam/help/members/types for additional documentation.
```

A faster way to enumerate Service Accounts in know projects is just to try to access to the URL: `https://iam.googleapis.com/v1/projects/<project-id>/serviceAccounts/<sa-email>`\
For examlpe: `https://iam.googleapis.com/v1/projects/gcp-labs-3uis1xlx/serviceAccounts/appengine-lab-1-tarsget@gcp-labs-3uis1xlx.iam.gserviceaccount.com`

If the response is a 403, it means that the SA exists. But if the answer is a 404 it means that it doesn't exist:

```json
// Exists
{
  "error": {
    "code": 403,
    "message": "Method doesn't allow unregistered callers (callers without established identity). Please use API Key or other form of API consumer identity to call this API.",
    "status": "PERMISSION_DENIED"
  }
}

// Doesn't exist
{
  "error": {
    "code": 404,
    "message": "Unknown service account",
    "status": "NOT_FOUND"
  }
}
```

Note how when the user email was valid the error message indicated that they type isn't, so we managed to discover that the email support@hacktricks.xyz exists without granting it any privileges.

You can so the **same with Service Accounts** using the type **`user:`** instead of **`serviceAccount:`**:

```bash
# Non existent
gcloud projects add-iam-policy-binding <project-controlled-by-you> \
  --member='serviceAccount:<invalid-sa-name>@<proj-uniq-name>.iam.gserviceaccount.com' \
  --role='roles/viewer'
# Response
ERROR: (gcloud.projects.add-iam-policy-binding) INVALID_ARGUMENT: User <invalid-sa-name>@<proj-uniq-name>.iam.gserviceaccount.com does not exist.

# Existent
gcloud projects add-iam-policy-binding <project-controlled-by-you> \
  --member='serviceAccount:<sa-name>@<proj-uniq-name>.iam.gserviceaccount.com' \
  --role='roles/viewer'
# Response
ERROR: (gcloud.projects.add-iam-policy-binding) INVALID_ARGUMENT: Principal testing@digital-bonfire-410512.iam.gserviceaccount.com is of type "serviceAccount". The principal should appear as "serviceAccount:testing@digital-bonfire-410512.iam.gserviceaccount.com". See https://cloud.google.com/iam/help/members/types for additional documentation.
```

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



