mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-28 22:51:09 -07:00
Translated ['', 'src/pentesting-cloud/gcp-security/gcp-unauthenticated-e
This commit is contained in:
+107
-16
@@ -1,30 +1,30 @@
|
||||
# GCP - Enumeración No Autenticada de Claves API
|
||||
# GCP - API Keys Unauthenticated Enum
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Claves API
|
||||
## API Keys
|
||||
|
||||
Para más información sobre las Claves API, consulta:
|
||||
Para más información sobre API Keys consulta:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Técnicas OSINT
|
||||
### OSINT techniques
|
||||
|
||||
**Las Claves API de Google son ampliamente utilizadas por cualquier tipo de aplicaciones** que las usan desde el lado del cliente. Es común encontrarlas en el código fuente de sitios web o en solicitudes de red, en aplicaciones móviles o simplemente buscando expresiones regulares en plataformas como Github.
|
||||
**Google API Keys are widely used by any kind of applications** that use del lado del cliente. Es común encontrarlas en el código fuente de sitios web o en solicitudes de red, en aplicaciones móviles o simplemente buscando regexes en plataformas como Github.
|
||||
|
||||
La expresión regular es: **`AIza[0-9A-Za-z_-]{35}`**
|
||||
La regex es: **`AIza[0-9A-Za-z_-]{35}`**
|
||||
|
||||
Búscalo, por ejemplo, en Github siguiendo: [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)
|
||||
Búscala por ejemplo en Github siguiendo: [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)
|
||||
|
||||
### Verificar el proyecto GCP de origen
|
||||
### Check origin GCP project
|
||||
|
||||
Esto es extremadamente útil para verificar **a qué proyecto GCP pertenece una clave API que has encontrado**. Tenemos diferentes opciones:
|
||||
Esto es extremadamente útil para comprobar a **qué proyecto de GCP pertenece una API key que hayas encontrado**. Tenemos diferentes opciones:
|
||||
|
||||
- Contactar `https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=<api-key>`
|
||||
- Contacta `https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=<api-key>`
|
||||
|
||||
Por brevedad, la salida fue truncada, pero en la salida completa el ID del proyecto aparece más de 5 veces.
|
||||
Por brevedad, la salida fue truncada, pero en la salida completa el ID del proyecto aparece más de 5 veces
|
||||
```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.",
|
||||
[...]
|
||||
```
|
||||
- Contacta `https://www.googleapis.com/identitytoolkit/v3/relyingparty/getProjectConfig?key=<api-key>`
|
||||
- Contacta `https://identitytoolkit.googleapis.com/v1/projects?key=<api-key>`
|
||||
|
||||
Para abreviar, la salida fue truncada, pero en la salida completa el ID del proyecto aparece más de 5 veces.
|
||||
Por brevedad, la salida fue truncada, pero en la salida completa el ID del proyecto aparece más de 5 veces
|
||||
```bash
|
||||
curl -s "https://identitytoolkit.googleapis.com/v1/projects?key=AIzaSyD[...]uE8Y"
|
||||
|
||||
@@ -46,7 +46,7 @@ curl -s "https://identitytoolkit.googleapis.com/v1/projects?key=AIzaSyD[...]uE8Y
|
||||
"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.",
|
||||
[...]
|
||||
```
|
||||
- [¡Este ya no funciona!] `apikeys.keys.lookup`
|
||||
- [¡Esta ya no funciona!] `apikeys.keys.lookup`
|
||||
```bash
|
||||
# If you have permissions
|
||||
gcloud services api-keys lookup AIzaSyD[...]uE8Y
|
||||
@@ -69,8 +69,99 @@ resource: projects/89123452509
|
||||
service: cloudresourcemanager.googleapis.com
|
||||
reason: AUTH_PERMISSION_DENIED
|
||||
```
|
||||
### Fuerza Bruta en endpoints de API
|
||||
### Recon de API impulsado por discovery-document
|
||||
|
||||
Como es posible que no sepas qué APIs están habilitadas en el proyecto, sería interesante ejecutar la herramienta [https://github.com/ozguralp/gmapsapiscanner](https://github.com/ozguralp/gmapsapiscanner) y verificar **a qué puedes acceder con la clave de API.**
|
||||
Una vez que tengas una clave válida, no te limites a probar las APIs públicas obvias. En entornos de Google, los **discovery documents** pueden funcionar como un mapa de attack-surface legible por máquina que expone **resources, methods, paths, HTTP verbs, parameters y request/response schemas**.
|
||||
|
||||
Targets útiles:
|
||||
```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:
|
||||
|
||||
- Compare the document size and method count with and without labels such as `GOOGLE_INTERNAL`.
|
||||
- A **true nonexistent method** usually returns an **HTML 404**. A **JSON 404** with `Method not found.` can indicate that the method exists but the **API key project is missing a required visibility label**.
|
||||
- Some first-party APIs are easier to reach via `*.clients6.google.com` or undocumented `*-pa.googleapis.com` hosts than via the public API explorer.
|
||||
|
||||
Esto es especialmente útil para enumerar **internal/admin APIs accidentalmente expuestas a Internet** y para construir fuzzers personalizados a partir del schema en lugar de adivinar campos JSON manualmente.
|
||||
|
||||
### Key ownership filtering at scale
|
||||
|
||||
Si recopilas muchas Google API keys de APKs, tráfico del navegador, IPAs o binaries, quizá quieras identificar rápidamente **qué project es dueño de cada key** y si pertenece a la empresa objetivo.
|
||||
|
||||
Un truco práctico es llamar intencionalmente a una API que **no esté habilitada** para la key. Google a menudo filtra el **project number** subyacente en el error:
|
||||
```bash
|
||||
curl -s 'https://protos.googleapis.com/$discovery/rest?key=<api-key>'
|
||||
```
|
||||
Busca mensajes como:
|
||||
```text
|
||||
Protos API has not been used in project 244648151629 before or it is disabled
|
||||
```
|
||||
Ese número de proyecto luego puede correlacionarse con otros endpoints, leaked metadata o lógica interna de mapeo de la empresa para separar **in-scope first-party keys** de proyectos de clientes / terceros.
|
||||
|
||||
### Maneja las restricciones de las keys antes de descartar una key
|
||||
|
||||
Una key restringida no es necesariamente inútil. Conserva el contexto donde se encontró la key y vuelve a reproducir las requests con los headers correspondientes:
|
||||
```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'
|
||||
```
|
||||
Clases comunes de restricción:
|
||||
|
||||
- **HTTP Referer**
|
||||
- **iOS bundle ID** (`X-Ios-Bundle-Identifier`)
|
||||
- **Android package + signing cert** (`X-Android-Package` + `X-Android-Cert`)
|
||||
- Restricciones por **Server IP**, que generalmente no se pueden bypass remotamente
|
||||
|
||||
### Pistas de auth / origin whitelist de first-party
|
||||
|
||||
Algunas Google web APIs aceptan una mezcla de **session cookie + first-party authorization headers** y están alojadas en `*.clients6.google.com`. Al probar estas APIs:
|
||||
|
||||
- Mantén `Origin` y `Referer` compatibles con el producto que normalmente usa la API.
|
||||
- Un `401` con `reason: SESSION_COOKIE_INVALID` en realidad puede significar que el **origin no está en la whitelist**, no que la cookie sea mala.
|
||||
- Las APIs accesibles públicamente que solo aceptan internal origins como `*.corp.google.com` son candidatas de alto valor para revisar broken access control.
|
||||
|
||||
### APIs con brute force habilitado y fuzz de métodos documentados
|
||||
|
||||
Como puede que no sepas qué APIs están habilitadas en el proyecto, sería interesante ejecutar la herramienta [https://github.com/ozguralp/gmapsapiscanner](https://github.com/ozguralp/gmapsapiscanner) y comprobar **a qué puedes acceder con la API key.**
|
||||
|
||||
Después de identificar los servicios alcanzables, prioriza **schema-driven fuzzing** sobre adivinar a ciegas:
|
||||
|
||||
- Genera requests directamente desde los discovery docs
|
||||
- Reproduce la misma request con **todas las keys válidas conocidas**
|
||||
- Normaliza los errores para que puedas distinguir **invalid input** de fallos de **visibility-label / auth / restriction**
|
||||
- Para identificadores numéricos de objetos, prueba valores cercanos como `ID-1`, `ID+1`, `1`, `2`, `100`, `1000`
|
||||
- Reporta solo cuando confirmes **cross-user data access** u otro fallo real de authorization; la simple enumeration normalmente no basta por sí sola
|
||||
|
||||
### Patrón común de vuln: unauthenticated direct-object reference
|
||||
|
||||
Un patrón de bug recurrente es una **internal/admin API** que acepta un identificador controlado por la víctima (por ejemplo `gaiaId`) y solo valida que la request lleve una API key utilizable, pero **nunca comprueba si el caller está autorizado para acceder a ese objeto específico**.
|
||||
```bash
|
||||
curl 'https://gfibervoice-pa.googleapis.com/v1/BssGetVoiceSettings?gaiaId=<victim_gaia_id>' \
|
||||
-H 'X-Goog-Api-Key: <api-key>'
|
||||
```
|
||||
Si el endpoint devuelve el número de teléfono, la dirección de correo electrónico, la configuración u otros campos privados de otro usuario, trátalo como un clásico problema de **IDOR / broken access control**.
|
||||
|
||||
## Referencias
|
||||
|
||||
- [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