mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-10 04:05:09 -08:00
Migrate to using mdbook
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# GCP - Unauthenticated Enum & Access
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Public Assets Discovery
|
||||
|
||||
One way to discover public cloud resources that belongs to a company is to scrape their webs looking for them. Tools like [**CloudScraper**](https://github.com/jordanpotti/CloudScraper) will scrape the web an search for **links to public cloud resources** (in this case this tools searches `['amazonaws.com', 'digitaloceanspaces.com', 'windows.net', 'storage.googleapis.com', 'aliyuncs.com']`)
|
||||
|
||||
Note that other cloud resources could be searched for and that some times these resources are hidden behind **subdomains that are pointing them via CNAME registry**.
|
||||
|
||||
## Public Resources Brute-Force
|
||||
|
||||
### Buckets, Firebase, Apps & Cloud Functions
|
||||
|
||||
- [https://github.com/initstring/cloud_enum](https://github.com/initstring/cloud_enum): This tool in GCP brute-force Buckets, Firebase Realtime Databases, Google App Engine sites, and Cloud Functions
|
||||
- [https://github.com/0xsha/CloudBrute](https://github.com/0xsha/CloudBrute): This tool in GCP brute-force Buckets and Apps.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,52 @@
|
||||
# GCP - API Keys Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Keys
|
||||
|
||||
For more information about API Keys check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### OSINT techniques
|
||||
|
||||
**Google API Keys are widely used by any kind of applications** that uses from the client side. It's common to find them in for websites source code or network requests, in mobile applications or just searching for regexes in platforms like Github.
|
||||
|
||||
The regex is: **`AIza[0-9A-Za-z_-]{35}`**
|
||||
|
||||
Search it for example in Github following: [https://github.com/search?q=%2FAIza%5B0-9A-Za-z\_-%5D%7B35%7D%2F\&type=code\&ref=advsearch](https://github.com/search?q=%2FAIza%5B0-9A-Za-z_-%5D%7B35%7D%2F&type=code&ref=advsearch)
|
||||
|
||||
### Check origin GCP project - `apikeys.keys.lookup`
|
||||
|
||||
This is extremely useful to check to **which GCP project an API key that you have found belongs to**:
|
||||
|
||||
```bash
|
||||
# If you have permissions
|
||||
gcloud services api-keys lookup AIzaSyD[...]uE8Y
|
||||
name: projects/5[...]6/locations/global/keys/28d[...]e0e
|
||||
parent: projects/5[...]6/locations/global
|
||||
|
||||
# If you don't, you can still see the project ID in the error msg
|
||||
gcloud services api-keys lookup AIzaSy[...]Qbkd_oYE
|
||||
ERROR: (gcloud.services.api-keys.lookup) PERMISSION_DENIED: Permission 'apikeys.keys.lookup' denied on resource project.
|
||||
Help Token: ARD_zUaNgNilGTg9oYUnMhfa3foMvL7qspRpBJ-YZog8RLbTjCTBolt_WjQQ3myTaOqu4VnPc5IbA6JrQN83CkGH6nNLum6wS4j1HF_7HiCUBHVN
|
||||
- '@type': type.googleapis.com/google.rpc.PreconditionFailure
|
||||
violations:
|
||||
- subject: ?error_code=110002&service=cloudresourcemanager.googleapis.com&permission=serviceusage.apiKeys.getProjectForKey&resource=projects/89123452509
|
||||
type: googleapis.com
|
||||
- '@type': type.googleapis.com/google.rpc.ErrorInfo
|
||||
domain: apikeys.googleapis.com
|
||||
metadata:
|
||||
permission: serviceusage.apiKeys.getProjectForKey
|
||||
resource: projects/89123452509
|
||||
service: cloudresourcemanager.googleapis.com
|
||||
reason: AUTH_PERMISSION_DENIED
|
||||
```
|
||||
|
||||
### Brute Force API endspoints
|
||||
|
||||
As you might not know which APIs are enabled in the project, it would be interesting to run the tool [https://github.com/ozguralp/gmapsapiscanner](https://github.com/ozguralp/gmapsapiscanner) and check **what you can access with the API key.**
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# GCP - App Engine Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## App Engine
|
||||
|
||||
For more information about App Engine check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Brute Force Subdomains
|
||||
|
||||
As mentioned the URL assigned to App Engine web pages is **`<project-uniq-name>.appspot.com`** and if a service name is used it'll be: **`<servicename>-dot-<project-uniq-name>.appspot.com`**.
|
||||
|
||||
As the **`project-uniq-name`** can be set by the person creating the project, they might be not that random and **brute-forcing them could find App Engine web apps exposed by companies**.
|
||||
|
||||
You could use tools like the ones indicated in:
|
||||
|
||||
{{#ref}}
|
||||
./
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,21 @@
|
||||
# GCP - Artifact Registry Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Artifact Registry
|
||||
|
||||
For more information about Artifact Registry check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-artifact-registry-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Dependency Confusion
|
||||
|
||||
Check the following page:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-persistence/gcp-artifact-registry-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,42 @@
|
||||
# GCP - Cloud Build Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud Build
|
||||
|
||||
For more information about Cloud Build check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-build-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### cloudbuild.yml
|
||||
|
||||
If you compromise write access over a repository containing a file named **`cloudbuild.yml`**, you could **backdoor** this file, which specifies the **commands that are going to be executed** inside a Cloud Build and exfiltrate the secrets, compromise what is done and also compromise the **Cloud Build service account.**
|
||||
|
||||
> [!NOTE]
|
||||
> Note that GCP has the option to allow administrators to control the execution of build systems from external PRs via "Comment Control". Comment Control is a feature where collaborators/project owners **need to comment “/gcbrun” to trigger the build** against the PR and using this feature inherently prevents anyone on the internet from triggering your build systems.
|
||||
|
||||
For some related information you could check the page about how to attack Github Actions (similar to this):
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-ci-cd/github-security/abusing-github-actions/
|
||||
{{#endref}}
|
||||
|
||||
### PR Approvals
|
||||
|
||||
When the trigger is PR because **anyone can perform PRs to public repositories** it would be very dangerous to just **allow the execution of the trigger with any PR**. Therefore, by default, the execution will only be **automatic for owners and collaborators**, and in order to execute the trigger with other users PRs an owner or collaborator must comment `/gcbrun`.
|
||||
|
||||
<figure><img src="../../../images/image (339).png" alt="" width="563"><figcaption></figcaption></figure>
|
||||
|
||||
> [!CAUTION]
|
||||
> Therefore, is this is set to **`Not required`**, an attacker could perform a **PR to the branch** that will trigger the execution adding the malicious code execution to the **`cloudbuild.yml`** file and compromise the cloudbuild execution (note that cloudbuild will download the code FROM the PR, so it will execute the malicious **`cloudbuild.yml`**).
|
||||
|
||||
Moreover, it's easy to see if some cloudbuild execution needs to be performed when you send a PR because it appears in Github:
|
||||
|
||||
<figure><img src="../../../images/image (340).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!WARNING]
|
||||
> Then, even if the cloudbuild is not executed the attacker will be able to see the **project name of a GCP project** that belongs to the company.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,77 @@
|
||||
# GCP - Cloud Functions Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud Functions
|
||||
|
||||
More information about Cloud Functions can be found in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-functions-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Brute Force URls
|
||||
|
||||
**Brute Force the URL format**:
|
||||
|
||||
- `https://<region>-<project-gcp-name>.cloudfunctions.net/<func_name>`
|
||||
|
||||
It's easier if you know project names.
|
||||
|
||||
Check this page for some tools to perform this brute force:
|
||||
|
||||
{{#ref}}
|
||||
./
|
||||
{{#endref}}
|
||||
|
||||
### Enumerate Open Cloud Functions
|
||||
|
||||
With the following code [taken from here](https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_misc/-/blob/master/find_open_functions.sh) you can find Cloud Functions that permit unauthenticated invocations.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
############################
|
||||
# Run this tool to find Cloud Functions that permit unauthenticated invocations
|
||||
# anywhere in your GCP organization.
|
||||
# Enjoy!
|
||||
############################
|
||||
|
||||
for proj in $(gcloud projects list --format="get(projectId)"); do
|
||||
echo "[*] scraping project $proj"
|
||||
|
||||
enabled=$(gcloud services list --project "$proj" | grep "Cloud Functions API")
|
||||
|
||||
if [ -z "$enabled" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
for func_region in $(gcloud functions list --quiet --project "$proj" --format="value[separator=','](NAME,REGION)"); do
|
||||
# drop substring from first occurence of "," to end of string.
|
||||
func="${func_region%%,*}"
|
||||
# drop substring from start of string up to last occurence of ","
|
||||
region="${func_region##*,}"
|
||||
ACL="$(gcloud functions get-iam-policy "$func" --project "$proj" --region "$region")"
|
||||
|
||||
all_users="$(echo "$ACL" | grep allUsers)"
|
||||
all_auth="$(echo "$ACL" | grep allAuthenticatedUsers)"
|
||||
|
||||
if [ -z "$all_users" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "[!] Open to all users: $proj: $func"
|
||||
fi
|
||||
|
||||
if [ -z "$all_auth" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "[!] Open to all authenticated users: $proj: $func"
|
||||
fi
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,59 @@
|
||||
# GCP - Cloud Run Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud Run
|
||||
|
||||
For more information about Cloud Run check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enumerate Open Cloud Run
|
||||
|
||||
With the following code [taken from here](https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_misc/-/blob/master/find_open_cloudrun.sh) you can find Cloud Run services that permit unauthenticated invocations.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
############################
|
||||
# Run this tool to find Cloud Run services that permit unauthenticated
|
||||
# invocations anywhere in your GCP organization.
|
||||
# Enjoy!
|
||||
############################
|
||||
|
||||
for proj in $(gcloud projects list --format="get(projectId)"); do
|
||||
echo "[*] scraping project $proj"
|
||||
|
||||
enabled=$(gcloud services list --project "$proj" | grep "Cloud Run API")
|
||||
|
||||
if [ -z "$enabled" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
for run in $(gcloud run services list --platform managed --quiet --project $proj --format="get(name)"); do
|
||||
ACL="$(gcloud run services get-iam-policy $run --platform managed --project $proj)"
|
||||
|
||||
all_users="$(echo $ACL | grep allUsers)"
|
||||
all_auth="$(echo $ACL | grep allAuthenticatedUsers)"
|
||||
|
||||
if [ -z "$all_users" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "[!] Open to all users: $proj: $run"
|
||||
fi
|
||||
|
||||
if [ -z "$all_auth" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "[!] Open to all authenticated users: $proj: $run"
|
||||
fi
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# GCP - Cloud SQL Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud SQL
|
||||
|
||||
For more infromation about Cloud SQL check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-sql-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Brute Force
|
||||
|
||||
If you have **access to a Cloud SQL port** because all internet is permitted or for any other reason, you can try to brute force credentials.
|
||||
|
||||
Check this page for **different tools to burte-force** different database technologies:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.xyz/generic-methodologies-and-resources/brute-force
|
||||
{{#endref}}
|
||||
|
||||
Remember that with some privileges it's possible to **list all the database users** via GCP API.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# GCP - Compute Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Compute
|
||||
|
||||
For more information about Compute and VPC (Networking) check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-compute-instances-enum/
|
||||
{{#endref}}
|
||||
|
||||
### SSRF - Server Side Request Forgery
|
||||
|
||||
If a web is **vulnerable to SSRF** and it's possible to **add the metadata header**, an attacker could abuse it to access the SA OAuth token from the metadata endpoint. For more info about SSRF check:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery
|
||||
{{#endref}}
|
||||
|
||||
### Vulnerable exposed services
|
||||
|
||||
If a GCP instance has a vulnerable exposed service an attacker could abuse it to compromise it.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,110 @@
|
||||
# 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}}
|
||||
@@ -0,0 +1,20 @@
|
||||
# GCP - Source Repositories Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Source Repositories
|
||||
|
||||
For more information about Source Repositories check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-source-repositories-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Compromise External Repository
|
||||
|
||||
If an external repository is being used via Source Repositories an attacker could add his malicious code to the repository and:
|
||||
|
||||
- If someone uses Cloud Shell to develop the repository it could be compromised
|
||||
- if this source repository is used by other GCP services, they could get compromised
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,73 @@
|
||||
# GCP - Storage Unauthenticated Enum
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Storage
|
||||
|
||||
For more information about Storage check:
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-services/gcp-storage-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Public Bucket Brute Force
|
||||
|
||||
The **format of an URL** to access a bucket is **`https://storage.googleapis.com/<bucket-name>`.**
|
||||
|
||||
The following tools can be used to generate variations of the name given and search for miss-configured buckets with that names:
|
||||
|
||||
- [https://github.com/RhinoSecurityLabs/GCPBucketBrute](https://github.com/RhinoSecurityLabs/GCPBucketBrute)
|
||||
|
||||
**Also the tools** mentioned in:
|
||||
|
||||
{{#ref}}
|
||||
../
|
||||
{{#endref}}
|
||||
|
||||
If you find that you can **access a bucket** you might be able to **escalate even further**, check:
|
||||
|
||||
{{#ref}}
|
||||
gcp-public-buckets-privilege-escalation.md
|
||||
{{#endref}}
|
||||
|
||||
### Search Open Buckets in Current Account
|
||||
|
||||
With the following script [gathered from here](https://gitlab.com/gitlab-com/gl-security/security-operations/gl-redteam/gcp_misc/-/blob/master/find_open_buckets.sh) you can find all the open buckets:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
############################
|
||||
# Run this tool to find buckets that are open to the public anywhere
|
||||
# in your GCP organization.
|
||||
#
|
||||
# Enjoy!
|
||||
############################
|
||||
|
||||
for proj in $(gcloud projects list --format="get(projectId)"); do
|
||||
echo "[*] scraping project $proj"
|
||||
for bucket in $(gsutil ls -p $proj); do
|
||||
echo " $bucket"
|
||||
ACL="$(gsutil iam get $bucket)"
|
||||
|
||||
all_users="$(echo $ACL | grep allUsers)"
|
||||
all_auth="$(echo $ACL | grep allAuthenticatedUsers)"
|
||||
|
||||
if [ -z "$all_users" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "[!] Open to all users: $bucket"
|
||||
fi
|
||||
|
||||
if [ -z "$all_auth" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "[!] Open to all authenticated users: $bucket"
|
||||
fi
|
||||
done
|
||||
done
|
||||
```
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,31 @@
|
||||
# GCP - Public Buckets Privilege Escalation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Buckets Privilege Escalation
|
||||
|
||||
If the bucket policy allowed either “allUsers” or “allAuthenticatedUsers” to **write to their bucket policy** (the **storage.buckets.setIamPolicy** permission)**,** then anyone can modify the bucket policy and grant himself full access.
|
||||
|
||||
### Check Permissions
|
||||
|
||||
There are 2 ways to check the permissions over a bucket. The first one is to ask for them by making a request to `https://www.googleapis.com/storage/v1/b/BUCKET_NAME/iam` or running `gsutil iam get gs://BUCKET_NAME`.
|
||||
|
||||
However, if your user (potentially belonging to allUsers or allAuthenticatedUsers") doesn't have permissions to read the iam policy of the bucket (storage.buckets.getIamPolicy), that won't work.
|
||||
|
||||
The other option which will always work is to use the testPermissions endpoint of the bucket to figure out if you have the specified permission, for example accessing: `https://www.googleapis.com/storage/v1/b/BUCKET_NAME/iam/testPermissions?permissions=storage.buckets.delete&permissions=storage.buckets.get&permissions=storage.buckets.getIamPolicy&permissions=storage.buckets.setIamPolicy&permissions=storage.buckets.update&permissions=storage.objects.create&permissions=storage.objects.delete&permissions=storage.objects.get&permissions=storage.objects.list&permissions=storage.objects.update`
|
||||
|
||||
### Escalating
|
||||
|
||||
In order to grant `Storage Admin` to `allAuthenticatedUsers` it's possible to run:
|
||||
|
||||
```bash
|
||||
gsutil iam ch allAuthenticatedUsers:admin gs://BUCKET_NAME
|
||||
```
|
||||
|
||||
Another attack would be to **remove the bucket an d recreate it in your account to steal th ownership**.
|
||||
|
||||
## References
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/google-cloud-platform-gcp-bucket-enumeration/](https://rhinosecuritylabs.com/gcp/google-cloud-platform-gcp-bucket-enumeration/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user