Translated ['', 'src/pentesting-cloud/gcp-security/gcp-unauthenticated-e

This commit is contained in:
Translator
2026-06-16 13:39:58 +00:00
parent 3933ce4643
commit 6d269dfcae
@@ -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}}