mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-10 04:05:09 -08:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
ここでは、潜在的に危険なRolesおよびClusterRolesの構成を見つけることができます。\
|
||||
`kubectl api-resources`を使用して、すべてのサポートされているリソースを取得できることを忘れないでください。
|
||||
`kubectl api-resources`を使用して、サポートされているすべてのリソースを取得できることを忘れないでください。
|
||||
|
||||
## **特権昇格**
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- Kubernetesクラスター内または外部クラウドで、より良い特権を持つ他のユーザー/グループ/サービスアカウントを**なりすます**ことができる
|
||||
- Kubernetesクラスター内または外部クラウドで、より良い特権を持つサービスアカウントを**見つけたり、アタッチしたりする**ことができる**ポッドを作成/パッチ/実行**できる
|
||||
- サービスアカウントのトークンがシークレットとして保存されているため、**シークレットを読む**ことができる
|
||||
- コンテナからノードに**エスケープ**できる場合、ノード上で実行されているコンテナのすべてのシークレット、ノードの資格情報、およびノードが実行されているクラウド内でのノードの権限を盗むことができる
|
||||
- コンテナからノードに**エスケープ**できること、これによりノード上で実行されているコンテナのすべてのシークレット、ノードの資格情報、およびノードが実行されているクラウド内でのノードの権限を盗むことができる
|
||||
- 言及に値する5番目の技術は、ポッド内で**ポートフォワードを実行**する能力です。これにより、そのポッド内の興味深いリソースにアクセスできる可能性があります。
|
||||
|
||||
### 任意のリソースまたは動詞へのアクセス(ワイルドカード)
|
||||
@@ -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
|
||||
@@ -127,10 +127,10 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
|
||||
|
||||
#### ステルス
|
||||
|
||||
おそらく、あなたは**ステルス性**を高めたいと思っているでしょう。次のページでは、前のテンプレートで言及された特権の一部を有効にするだけでポッドを作成した場合にアクセスできる内容を確認できます。
|
||||
おそらく、あなたは**ステルス性**を高めたいと思っているでしょう。次のページでは、前のテンプレートで言及された特権の一部を有効にしてポッドを作成した場合にアクセスできる内容を確認できます。
|
||||
|
||||
- **特権 + hostPID**
|
||||
- **特権のみ**
|
||||
- **Privileged + hostPID**
|
||||
- **Privileged only**
|
||||
- **hostPath**
|
||||
- **hostPID**
|
||||
- **hostNetwork**
|
||||
@@ -143,17 +143,17 @@ _前述の特権ポッド構成を作成/悪用する方法の例は_ [_https://
|
||||
**ポッド**(およびオプションで**サービスアカウント**)を**作成**できる場合、**ポッドまたはサービスアカウントにクラウドロールを割り当てることによってクラウド環境で特権を取得**できるかもしれません。そして、それにアクセスします。\
|
||||
さらに、**ホストネットワーク名前空間**を持つ**ポッドを作成**できる場合、**ノード**インスタンスのIAMロールを**盗む**ことができます。
|
||||
|
||||
詳細については、次を確認してください。
|
||||
詳細については、次を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
pod-escape-privileges.md
|
||||
{{#endref}}
|
||||
|
||||
### **デプロイメント、デーモンセット、ステートフルセット、レプリケーションコントローラー、レプリカセット、ジョブ、クロンジョブの作成/パッチ**
|
||||
### **デプロイメント、デーモンセット、ステートフルセット、レプリケーションコントローラー、レプリカセット、ジョブ、Cronジョブの作成/パッチ**
|
||||
|
||||
これらの権限を悪用して、**新しいポッドを作成**し、前の例のように特権を確立することが可能です。
|
||||
|
||||
次のyamlは**デーモンセットを作成し、ポッド内のSAのトークンを抽出**します。
|
||||
次のyamlは**デーモンセットを作成し、ポッド内のSAのトークンを外部に送信**します:
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
@@ -204,19 +204,19 @@ kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||
|
||||
### 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サービスは、基本的に**コンテナの `/var/log` ファイルシステムを公開する**`/logs/`エンドポイントを公開しています。
|
||||
これは基本的に、**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"
|
||||
@@ -236,7 +236,7 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://
|
||||
<a href="lib">lib</a>
|
||||
[...]
|
||||
```
|
||||
**実験室と自動化されたエクスプロイトは** [**https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts**](https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts) **にあります。**
|
||||
**実験室と自動化されたエクスプロイトは** [**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>
|
||||
|
||||
@@ -302,12 +302,12 @@ name: task-pv-storage-vol
|
||||
|
||||
[**ユーザーのなりすまし**](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"\
|
||||
@@ -317,13 +317,13 @@ 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/
|
||||
```
|
||||
### シークレットの作成と読み取り
|
||||
### Secretsの作成と読み取り
|
||||
|
||||
**kubernetes.io/service-account-token** タイプの特別な種類のKubernetesシークレットがあり、サービスアカウントトークンを保存します。
|
||||
**kubernetes.io/service-account-token**タイプのKubernetesシークレットの特別な種類があり、サービスアカウントトークンを保存します。
|
||||
シークレットを作成および読み取る権限があり、サービスアカウントの名前も知っている場合、次のようにシークレットを作成し、そこから被害者のサービスアカウントトークンを盗むことができます:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
@@ -387,17 +387,76 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
|
||||
|
||||
### シークレットの読み取り – トークンIDのブルートフォース攻撃
|
||||
|
||||
読み取り権限を持つトークンを所持している攻撃者は、それを使用するためにシークレットの正確な名前が必要ですが、より広範な _**シークレットのリスト表示**_ 権限とは異なり、依然として脆弱性があります。システム内のデフォルトのサービスアカウントは列挙可能で、それぞれがシークレットに関連付けられています。これらのシークレットは、静的なプレフィックスの後にランダムな5文字の英数字トークン(特定の文字を除く)を持つ名前の構造を持っています。[ソースコード](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83)によると。
|
||||
読み取り権限を持つトークンを所持している攻撃者は、それを使用するためにシークレットの正確な名前が必要ですが、より広範な_**シークレットのリスト表示**_権限とは異なり、依然として脆弱性があります。システム内のデフォルトのサービスアカウントは列挙可能で、それぞれがシークレットに関連付けられています。これらのシークレットは、静的なプレフィックスの後にランダムな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)に減少します。したがって、攻撃者は数時間でトークンを推測するためのブルートフォース攻撃を実行することが現実的であり、機密性の高いサービスアカウントにアクセスすることによって特権の昇格につながる可能性があります。
|
||||
|
||||
### EncrpytionConfigurationの平文
|
||||
|
||||
この種のオブジェクト内でデータを静止状態で暗号化するための平文キーを見つけることが可能です。
|
||||
```yaml
|
||||
# From https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
|
||||
|
||||
#
|
||||
# CAUTION: this is an example configuration.
|
||||
# Do not use this for your own cluster!
|
||||
#
|
||||
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
- configmaps
|
||||
- pandas.awesome.bears.example # a custom resource API
|
||||
providers:
|
||||
# This configuration does not provide data confidentiality. The first
|
||||
# configured provider is specifying the "identity" mechanism, which
|
||||
# stores resources as plain text.
|
||||
#
|
||||
- identity: {} # plain text, in other words NO encryption
|
||||
- aesgcm:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZQ==
|
||||
- name: key2
|
||||
secret: dGhpcyBpcyBwYXNzd29yZA==
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZQ==
|
||||
- name: key2
|
||||
secret: dGhpcyBpcyBwYXNzd29yZA==
|
||||
- secretbox:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY=
|
||||
- resources:
|
||||
- events
|
||||
providers:
|
||||
- identity: {} # do not encrypt Events even though *.* is specified below
|
||||
- resources:
|
||||
- '*.apps' # wildcard match requires Kubernetes 1.27 or later
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key2
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZSwgb3IgaXMgaXQ/Cg==
|
||||
- resources:
|
||||
- '*.*' # wildcard match requires Kubernetes 1.27 or later
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key3
|
||||
secret: c2VjcmV0IGlzIHNlY3VyZSwgSSB0aGluaw==
|
||||
```
|
||||
### 証明書署名要求
|
||||
|
||||
リソース `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
|
||||
@@ -430,10 +489,10 @@ 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ノードの資格情報を生成するために悪用され、その後それを使用して秘密を盗むことで権限を昇格させます。\
|
||||
**言及された権限を持っていれば、同じことができます**。最初の例は、新しいノードがコンテナ内の秘密にアクセスするのを防ぐエラーを回避しています。なぜなら、**ノードは自分にマウントされたコンテナの秘密にしかアクセスできないからです。**
|
||||
[**この投稿**](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"
|
||||
```
|
||||
@@ -482,14 +541,14 @@ groups:
|
||||
> [!WARNING]
|
||||
> **`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に連絡します。
|
||||
> しかし、`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に連絡します。
|
||||
|
||||
### CoreDNS config map
|
||||
|
||||
`kube-system`ネームスペース内の**`coredns` configmap**を変更する権限がある場合、ドメインが解決されるアドレスを変更して、**機密情報を盗むまたは悪意のあるコンテンツを注入する**ためのMitM攻撃を実行できます。
|
||||
|
||||
必要な動詞は**`update`**と**`patch`**で、**`coredns`** configmap(またはすべてのconfig map)に対して使用します。
|
||||
必要な動詞は、**`coredns`** configmap(またはすべてのconfigmap)に対する**`update`**と**`patch`**です。
|
||||
|
||||
通常の**corednsファイル**には、次のような内容が含まれています:
|
||||
```yaml
|
||||
@@ -543,7 +602,7 @@ loadbalance
|
||||
|
||||
### サービスアカウントトークンの作成
|
||||
|
||||
**TokenRequests**(`serviceaccounts/token`)を**作成**できるプリンシパルは、K8s APIエンドポイントに話しかけるとSAs(情報は[**こちら**](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
|
||||
|
||||
@@ -557,7 +616,7 @@ loadbalance
|
||||
|
||||
### 昇格
|
||||
|
||||
次のセクションで読むことができるように: [**組み込みの特権昇格防止**](#built-in-privileged-escalation-prevention)、プリンシパルは新しい権限を持たずに役割やクラスター役割を更新または作成することはできません。**`roles`** または **`clusterroles`** に対して **`escalate` または `*`** の動詞を持っている場合を除き、そしてそれに対応するバインディングオプションが必要です。\
|
||||
次のセクションで読むことができるように: [**組み込みの特権昇格防止**](#built-in-privileged-escalation-prevention)、プリンシパルは自分自身がその新しい権限を持っていない限り、役割やクラスター役割を更新または作成することはできません。**`roles`** または **`clusterroles`** に対して **`escalate` または `*`** の動詞を持っている場合を除き、そしてそれに対応するバインディングオプションが必要です。\
|
||||
その場合、彼はより良い権限を持つ新しい役割やクラスター役割を更新/作成できます。
|
||||
|
||||
### ノードプロキシ
|
||||
@@ -570,9 +629,9 @@ loadbalance
|
||||
|
||||
[**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"}]'
|
||||
@@ -585,7 +644,7 @@ 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) による)。
|
||||
|
||||
### ノードとポッドのステータス
|
||||
|
||||
@@ -595,7 +654,7 @@ kubectl delete pods -n kube-system <privileged_pod_name>
|
||||
|
||||
Kubernetes には、特権昇格を防ぐための [組み込みメカニズム](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) があります。
|
||||
|
||||
このシステムは、**ユーザーが役割や役割バインディングを修正することで特権を昇格させることができない**ことを保証します。このルールの施行は API レベルで行われ、RBAC 認証者が非アクティブな場合でも保護を提供します。
|
||||
このシステムは、**ユーザーが役割や役割バインディングを修正することによって特権を昇格させることができない**ことを保証します。このルールの施行は API レベルで行われ、RBAC 認可者が非アクティブな場合でも保護を提供します。
|
||||
|
||||
このルールは、**ユーザーは役割を作成または更新するために、その役割が含むすべての権限を持っている必要がある**と規定しています。さらに、ユーザーの既存の権限の範囲は、作成または修正しようとしている役割の範囲と一致しなければなりません:ClusterRoles の場合はクラスター全体、Roles の場合は同じネームスペース(またはクラスター全体)に制限されます。
|
||||
|
||||
@@ -605,7 +664,7 @@ Kubernetes には、特権昇格を防ぐための [組み込みメカニズム]
|
||||
### **RoleBindings/ClusterRoleBindings の取得とパッチ**
|
||||
|
||||
> [!CAUTION]
|
||||
> **この技術は以前は機能していたようですが、私のテストによると、前のセクションで説明した理由でもはや機能していません。権限を持っていない場合、役割バインディングを作成/修正して自分自身または別の SA に特権を与えることはできません。**
|
||||
> **この技術は以前は機能していたようですが、私のテストによると、前のセクションで説明した理由でもはや機能していません。権限を持っていない場合、自分自身または別の SA に特権を与えるために rolebinding を作成/修正することはできません。**
|
||||
|
||||
Rolebindings を作成する特権は、ユーザーが **サービスアカウントに役割をバインドする** ことを可能にします。この特権は、**ユーザーが侵害されたサービスアカウントに管理者特権をバインドできるため、特権昇格につながる可能性があります。**
|
||||
|
||||
@@ -629,13 +688,13 @@ image: nginx
|
||||
image: busybox
|
||||
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||
```
|
||||
既存のポッドに新しいコンテナをバックドアするには、仕様に新しいコンテナを追加するだけです。第二のコンテナに、最初のコンテナが持たない**より多くの権限**を与えることができることに注意してください。
|
||||
既存のポッドに新しいコンテナをバックドアするには、仕様に新しいコンテナを追加するだけで済みます。第二のコンテナに対して、最初のコンテナが持たない**より多くの権限を与える**ことができることに注意してください。
|
||||
|
||||
詳細は次を参照してください: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
### 悪意のあるアドミッションコントローラー
|
||||
|
||||
アドミッションコントローラーは、オブジェクトの永続化の前にKubernetes APIサーバーへのリクエストを**傍受**しますが、**リクエストが認証**され、**承認**された後です。
|
||||
アドミッションコントローラーは、オブジェクトの永続化の前にKubernetes APIサーバーへのリクエストを**傍受**しますが、**リクエストが認証され**、**承認された後**です。
|
||||
|
||||
攻撃者が何らかの方法で**ミューテーションアドミッションコントローラーを注入**することに成功すれば、**すでに認証されたリクエストを変更**することができます。これにより、潜在的に権限昇格が可能になり、より一般的にはクラスター内に持続することができます。
|
||||
|
||||
@@ -658,7 +717,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: "
|
||||
@@ -669,7 +728,7 @@ kubectl describe po nginx | grep "Image: "
|
||||
|
||||
#### 技術的詳細
|
||||
|
||||
`./deploy.sh` スクリプトは、Kubernetes APIへのリクエストを指定された設定行に従って変更するミューテイティングウェブフックアドミッションコントローラーを確立します。これにより、観察された結果に影響を与えます:
|
||||
`./deploy.sh` スクリプトは、Kubernetes APIへのリクエストを指定された設定行に従って変更するミューテイティングウェブフックアドミッションコントローラーを確立します。これにより、観察された結果に影響を与えます。
|
||||
```
|
||||
patches = append(patches, patchOperation{
|
||||
Op: "replace",
|
||||
@@ -698,7 +757,7 @@ Value: "rewanthtammana/malicious-image",
|
||||
|
||||
### **クラスター全体のロールよりも名前空間特有のロールを使用する**
|
||||
|
||||
- **ロールと ClusterRoles**: クラスター全体に適用される ClusterRoles および ClusterRoleBindings よりも、名前空間特有の権限には Roles および RoleBindings を使用することを推奨します。このアプローチは、より細かい制御を提供し、権限の範囲を制限します。
|
||||
- **ロールとクラスター ロール**: クラスター全体に適用される ClusterRoles および ClusterRoleBindings よりも、名前空間特有の権限には Roles および RoleBindings を使用することを推奨します。このアプローチは、より細かい制御を提供し、権限の範囲を制限します。
|
||||
|
||||
### **自動化ツールを使用する**
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
Kubernetesでは、デフォルトの動作により、**同じノードに存在するすべてのコンテナ間での接続が許可される**ことが観察されています。これは、名前空間の区別に関係なく適用されます。このような接続は、**Layer 2**(イーサネット)まで拡張されます。したがって、この構成はシステムを脆弱性にさらす可能性があります。具体的には、**悪意のあるコンテナ**が同じノードにある他のコンテナに対して**ARPスプーフィング攻撃**を実行する可能性を開きます。この攻撃中、悪意のあるコンテナは、他のコンテナに向けられたネットワークトラフィックを欺いて傍受または変更することができます。
|
||||
Kubernetesでは、デフォルトの動作により、**同じノードに存在するすべてのコンテナ間で接続が確立される**ことが許可されています。これは、名前空間の区別に関係なく適用されます。このような接続は、**Layer 2**(イーサネット)まで拡張されます。したがって、この構成はシステムを脆弱性にさらす可能性があります。具体的には、**悪意のあるコンテナ**が同じノードにある他のコンテナに対して**ARPスプーフィング攻撃**を実行する可能性を開きます。この攻撃中、悪意のあるコンテナは、他のコンテナ向けのネットワークトラフィックを欺いて傍受または変更することができます。
|
||||
|
||||
ARPスプーフィング攻撃は、**攻撃者がローカルエリアネットワーク上で偽のARP**(アドレス解決プロトコル)メッセージを送信することを含みます。これにより、**攻撃者のMACアドレスがネットワーク上の正当なコンピュータまたはサーバーのIPアドレスにリンクされます**。このような攻撃が成功裏に実行された後、攻撃者はデータを傍受、変更、または停止することさえできます。この攻撃はOSIモデルのLayer 2で実行されるため、Kubernetesにおけるこのレイヤーでのデフォルトの接続性はセキュリティ上の懸念を引き起こします。
|
||||
ARPスプーフィング攻撃は、**攻撃者がローカルエリアネットワーク上で偽のARP**(アドレス解決プロトコル)メッセージを送信することを含みます。これにより、**攻撃者のMACアドレスがネットワーク上の正当なコンピュータまたはサーバーのIPアドレスにリンクされます**。このような攻撃が成功裏に実行された後、攻撃者はデータを傍受、変更、または停止することができます。この攻撃はOSIモデルのLayer 2で実行されるため、Kubernetesにおけるこのレイヤーでのデフォルトの接続性はセキュリティ上の懸念を引き起こします。
|
||||
|
||||
シナリオでは、4台のマシンが作成されます:
|
||||
|
||||
- ubuntu-pe: ノードに逃げてメトリクスを確認するための特権マシン(攻撃には必要ありません)
|
||||
- **ubuntu-attack**: **悪意のある**コンテナ、デフォルトの名前空間に存在
|
||||
- **ubuntu-victim**: **被害者**マシン、kube-system名前空間に存在
|
||||
- **mysql**: **被害者**マシン、デフォルトの名前空間に存在
|
||||
- ubuntu-pe: ノードにエスケープしてメトリクスを確認するための特権マシン(攻撃には必要ありません)
|
||||
- **ubuntu-attack**: **悪意のある**コンテナ(デフォルトの名前空間内)
|
||||
- **ubuntu-victim**: **被害者**マシン(kube-system名前空間内)
|
||||
- **mysql**: **被害者**マシン(デフォルトの名前空間内)
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -98,13 +98,13 @@ kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; ba
|
||||
```
|
||||
## 基本的なKubernetesネットワーキング
|
||||
|
||||
ここで紹介されているネットワーキングのトピックについての詳細は、参考文献を参照してください。
|
||||
ここで紹介されているネットワーキングのトピックについての詳細は、リファレンスを参照してください。
|
||||
|
||||
### ARP
|
||||
|
||||
一般的に言えば、**ノード内のポッド間ネットワーキング**は、すべてのポッドを接続する**ブリッジ**を介して利用可能です。このブリッジは「**cbr0**」と呼ばれます。(一部のネットワークプラグインは独自のブリッジをインストールします。)**cbr0はARP**(アドレス解決プロトコル)解決も処理できます。cbr0に到着した受信パケットは、ARPを使用して宛先MACアドレスを解決できます。
|
||||
|
||||
この事実は、デフォルトでは、**同じノードで実行されているすべてのポッド**が、**同じノード内の他のポッドと通信**できることを意味します(名前空間に関係なく)イーサネットレベル(レイヤー2)で。
|
||||
この事実は、デフォルトでは、**同じノードで実行されているすべてのポッド**が、**同じノード内の他のポッド**(名前空間に関係なく)とイーサネットレベル(レイヤー2)で**通信**できることを意味します。
|
||||
|
||||
> [!WARNING]
|
||||
> したがって、**同じノード内のポッド間でARPスプーフィング攻撃を実行することが可能です。**
|
||||
@@ -136,7 +136,7 @@ Port: metrics 9153/TCP
|
||||
TargetPort: 9153/TCP
|
||||
Endpoints: 172.17.0.2:9153
|
||||
```
|
||||
前の情報では興味深いことが見られます。**サービスのIP**は**10.96.0.10**ですが、**サービスを実行しているポッドのIP**は**172.17.0.2**です。
|
||||
前の情報には興味深いことが見られます。**サービスのIP**は**10.96.0.10**ですが、**サービスを実行しているポッドのIP**は**172.17.0.2**です。
|
||||
|
||||
任意のポッド内でDNSアドレスを確認すると、次のようなものが見つかります:
|
||||
```
|
||||
@@ -156,7 +156,7 @@ nameserver 10.96.0.10
|
||||
|
||||
## 同じノード内のポッドにおけるARPスプーフィング
|
||||
|
||||
私たちの目標は、**ubuntu-victimからmysqlへの通信を少なくとも盗む**ことです。
|
||||
私たちの目標は、**ubuntu-victimからmysqlへの通信を少なくとも盗むこと**です。
|
||||
|
||||
### Scapy
|
||||
```bash
|
||||
@@ -233,11 +233,11 @@ arpspoof -t 172.17.0.9 172.17.0.10
|
||||
```
|
||||
## DNS Spoofing
|
||||
|
||||
既に述べたように、もしあなたが**DNSサーバーポッドと同じノードのポッドを侵害**した場合、**MitM**を使用して**ARPSpoofing**で**ブリッジとDNS**ポッドを介して**すべてのDNSレスポンスを変更**することができます。
|
||||
既に述べたように、もしあなたが**DNSサーバーポッドと同じノードのポッドを侵害**した場合、**ARPSpoofing**を使用して**ブリッジとDNS**ポッドを**MitM**し、**すべてのDNSレスポンスを変更**することができます。
|
||||
|
||||
あなたには、これをテストするための素晴らしい**ツール**と**チュートリアル**があります [**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
あなたには、これをテストするための素晴らしい**ツール**と**チュートリアル**があります:[**https://github.com/danielsagi/kube-dnsspoof/**](https://github.com/danielsagi/kube-dnsspoof/)
|
||||
|
||||
私たちのシナリオでは、**攻撃者ポッドに**この**ツールをダウンロード**し、**スプーフィング**したい**ドメイン**を含む**`hosts`という名前のファイルを作成**します:
|
||||
私たちのシナリオでは、**攻撃者ポッドにツールをダウンロード**し、**スプーフィングしたいドメイン**を含む**`hosts`という名前のファイルを作成**します。
|
||||
```
|
||||
cat hosts
|
||||
google.com. 1.1.1.1
|
||||
@@ -260,13 +260,45 @@ dig google.com
|
||||
google.com. 1 IN A 1.1.1.1
|
||||
```
|
||||
> [!NOTE]
|
||||
> 自分のDNSスプーフィングスクリプトを作成しようとする場合、**DNS応答を変更するだけでは**、**機能しません**。なぜなら、**応答**には**悪意のある** **ポッド**のIPアドレスである**src IP**が含まれ、**受け入れられない**からです。\
|
||||
> 自分のDNSスプーフィングスクリプトを作成しようとする場合、**DNS応答を変更するだけでは**、**機能しません**。なぜなら、**応答**には**悪意のある****ポッド**の**src IP**が含まれ、**受け入れられない**からです。\
|
||||
> 被害者がDNSリクエストを送信する**DNS**の**src IP**を持つ**新しいDNSパケット**を生成する必要があります(これは172.16.0.2のようなもので、10.96.0.10ではありません。これはK8s DNSサービスのIPであり、DNSサーバーのIPではありません。詳細はイントロダクションで説明します)。
|
||||
|
||||
## coreDNS configmapを介したDNSスプーフィング
|
||||
|
||||
kube-system名前空間のconfigmap `coredns`に対する書き込み権限を持つユーザーは、クラスターのDNS応答を変更できます。
|
||||
|
||||
この攻撃に関する詳細情報は以下を確認してください:
|
||||
|
||||
{{#ref}}
|
||||
abusing-roles-clusterroles-in-kubernetes/README.md
|
||||
{{/ref}}
|
||||
|
||||
## 公開されたKubernetes管理サービスの悪用
|
||||
|
||||
Apache NiFi、Kubeflow、Argo Workflows、Weave Scope、Kubernetesダッシュボードなどのサービスは、インターネットまたはKubernetesネットワーク内に公開されていることがよくあります。Kubernetesを管理するために使用されるプラットフォームを**見つけてアクセスできた**攻撃者は、それを悪用してKubernetes APIにアクセスし、新しいポッドを作成したり、既存のポッドを変更したり、さらには削除したりすることができます。
|
||||
|
||||
## Kubernetesネットワークポリシーの列挙
|
||||
|
||||
構成された**networkpolicies**を取得します:
|
||||
```bash
|
||||
kubectl get networkpolicies --all-namespaces
|
||||
```
|
||||
**Callico** ネットワークポリシーを取得する:
|
||||
```bash
|
||||
kubectl get globalnetworkpolicy --all-namespaces
|
||||
```
|
||||
**Cillium** ネットワークポリシーを取得する:
|
||||
```bash
|
||||
kubectl get ciliumnetworkpolicy --all-namespaces
|
||||
```
|
||||
ネットワークプラグインやセキュリティソリューションによってインストールされた他のポリシー関連のCRDを取得します:
|
||||
```bash
|
||||
kubectl get crd | grep -i policy
|
||||
```
|
||||
## トラフィックのキャプチャ
|
||||
|
||||
ツール[**Mizu**](https://github.com/up9inc/mizu)は、Kubernetes用のシンプルでありながら強力なAPI **トラフィックビューワー**で、マイクロサービス間の**すべてのAPI通信**を**表示**し、デバッグや回帰のトラブルシューティングを支援します。\
|
||||
選択したポッドにエージェントをインストールし、そのトラフィック情報を収集してウェブサーバーに表示します。ただし、これには高いK8s権限が必要です(あまりステルスではありません)。
|
||||
ツール [**Mizu**](https://github.com/up9inc/mizu) は、Kubernetes 用のシンプルでありながら強力な API **トラフィックビューワー**で、マイクロサービス間のすべての API 通信を **表示**し、デバッグや回帰のトラブルシューティングを支援します。\
|
||||
選択したポッドにエージェントをインストールし、トラフィック情報を収集してウェブサーバーに表示します。ただし、これには高い K8s 権限が必要で(あまりステルスではありません)。
|
||||
|
||||
## 参考文献
|
||||
|
||||
|
||||
Reference in New Issue
Block a user