Kubernetes网络策略绕过漏洞:已完成的Pod如何导致AWS VPC CNI控制器防火墙失效

本文详细披露了AWS EKS集群中一个关键安全漏洞:由于VPC CNI控制器在处理已完成的Pod时存在逻辑缺陷,导致网络策略规则残留,使得后续分配了相同IP地址的Pod能够继承其不应享有的网络访问权限,从而绕过Kubernetes NetworkPolicy的安全限制。

描述

亚马逊VPC CNI控制器在配置为管理网络策略(NetworkPolicy)规则时,会错误地将防火墙规则应用于已完成的(Completed)Pod,就好像这些Pod仍在运行一样。这导致这些规则被错误地应用到其他不相关的、恰好分配到相同IP地址的Pod上。

例如,假设有一个IP地址为X的Pod A,它被网络策略允许某些访问,VPC CNI控制器通过为节点上的IP地址X添加防火墙规则来实现这一策略。当Pod A完成(例如,如果它是一个Job)时,这些防火墙规则不会被移除。由于Pod已完成,其他Pod可以自由地获取相同的IP地址。如果Pod B(它未被网络策略授予任何访问权限)被分配了相同的IP地址X,那么Pod B将继承Pod A曾有的网络访问权限,直到已完成的Pod A被删除。

正确的行为应该是检查Pod是否已完成,并将Pod完成视为与Pod删除相同,在Pod完成时移除防火墙规则。

受影响版本

我在EKS 1.33版本上进行了测试,以下配置会受影响:

  • 在启用网络策略控制器的自动模式(auto mode)下
  • 在非自动模式下,使用VPC CNI附加组件 v1.19.5-eksbuild.1
  • 在非自动模式下,使用VPC CNI附加组件 v1.20.1-eksbuild.3

严格模式(Strict mode)没有影响。

概念验证(POC)

在启用自动模式或VPC CNI控制器且enableNetworkPolicy设置为true的EKS集群上,应用以下预备性Kubernetes资源:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
---
apiVersion: v1
kind: Namespace
metadata:
  name: networkpolicy-test
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  namespace: networkpolicy-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
        - name: whoami
          image: traefik/whoami:latest
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app: whoami
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ingress
  namespace: networkpolicy-test
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          test: allowed
    ports:
    - protocol: TCP
      port: 80

此网络策略配置将允许以下Job连接到Deployment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
---
apiVersion: batch/v1
kind: Job
metadata:
  name: allowed
  namespace: networkpolicy-test
spec:
  template:
    metadata:
      name: curl
      labels:
        test: allowed
    spec:
      containers:
        - name: curl
          image: "alpine/curl:latest"
          command: ["curl", "-v", "whoami.networkpolicy-test.svc.cluster.local:80"]
      restartPolicy: Never

但以下Job将被阻止并超时:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
---
apiVersion: batch/v1
kind: Job
metadata:
  name: blocked
  namespace: networkpolicy-test
spec:
  template:
    metadata:
      name: curl
      labels:
        test: blocked
    spec:
      containers:
        - name: curl
          image: "alpine/curl:latest"
          command: ["curl", "-v", "whoami.networkpolicy-test.svc.cluster.local:80"]
      restartPolicy: Never

但是,如果存在一个处于Completed状态的允许的Job,那么被阻止的Pod有可能接收到与该已完成的允许Pod相同的IP地址。当这种情况发生时,被阻止的Pod将能够访问Deployment,这违反了网络策略。 为了方便重现,建议应用所附的█████████文件来创建20个允许的Job。等待所有20个Job完成,然后应用所附的██████████文件来创建20个被阻止的Job。几乎可以肯定的是,一些被阻止的Pod将被分配与已完成的允许Pod相匹配的IP地址,因此将能够成功连接到Deployment并退出。一些被阻止的Pod将被分配不同的IP地址,因此将正确地无法连接到Deployment、挂起然后报错。

影响

摘要:在依赖Kubernetes网络策略规则来限制网络访问的EKS集群中,存在被允许某些访问的已完成Pod将导致其他Pod获得相同的访问权限。

更详细的步骤说明

如果没有已配置为管理网络策略的VPC CNI控制器的现有Kubernetes集群,设置环境的最简单方法是创建一个启用自动模式的新EKS集群。

分步指南

  1. 创建一个启用自动模式的EKS集群:参考AWS指南(链接)。如果通过AWS控制台操作: 1.1 为集群命名。 1.2 使用“创建推荐角色”按钮创建集群角色(可命名)。 1.3 在集群设置页面选择创建的集群角色。 1.4 其他所有设置均可保留默认值。

  2. 集群创建完成后,配置kubectl:参考AWS指南(链接)。 2.1 使用AWS CLI最容易完成:参考指南(链接)。 2.2 然后应该可以简单地运行 aws eks update-kubeconfig --name <步骤1中创建的集群名称>

  3. 启用网络策略管理:参考AWS指南(链接)。 3.1 运行 kubectl apply -f enable-network-policy.yaml 3.2 运行 kubectl patch nodeclass default --type=merge -p '{"spec":{"networkPolicyEventLogs":"Enabled"}}' 3.3 (此步骤可能不是必需的)它可能不会对现有节点生效,所以为了以防万一,通过运行 kubectl drain -l karpenter.sh/nodepool=general-purpose --ignore-daemonsets --delete-emptydir-data 来清空所有现有节点。

  4. 通过运行 kubectl apply -f setup.yaml 设置测试Kubernetes命名空间和资源。

  5. 验证Kubernetes网络策略在集群上是否正常工作。 5.1 运行 kubectl apply -f blocked-job.yaml 5.2 使用 kubectl get pod -n networkpolicy-test -l test=blocked 检查所创建Pod的状态。最初它将显示Running状态,然后在超时后显示Error状态。存在状态为Error的Pod表明Kubernetes集群上已启用网络策略管理。存在状态为Completed的Pod表明网络策略管理未在集群上正确配置(返回步骤3)。 5.3 通过运行 kubectl delete job -n networkpolicy-test blocked 清理该Job。

  6. 创建那些旨在能够连接到whoami deployment的Job 6.1 运行 kubectl apply -f ████ 6.2 所有Job都应该启动并在没有错误的情况下完成(即显示Completed状态),可以通过 kubectl get pod -n networkpolicy-testkubectl get job -n networkpolicy-test 进行检查。

  7. 创建那些应该被网络策略阻止的Job 7.1 运行 kubectl apply -f blocked-job20.yaml 7.2 等待片刻,让所有Pod启动。

验证 8.1 使用 kubectl get pod -n networkpolicy-test -l test=blocked 检查被阻止Pod的状态。 8.2 所有被阻止的Pod都应该被配置的网络策略阻止。如果有些Pod显示Completed状态,而其他Pod显示ErrorRunning状态,则漏洞被确认。 8.3 为了进一步确认漏洞,通过运行 kubectl get pod -n networkpolicy-test -o wide 检查Pod的IP地址。所有IP地址与一个或多个允许Pod的IP地址冲突的被阻止Pod都应该显示Completed状态。任何IP地址与允许Pod不匹配的被阻止Pod都应该显示ErrorRunning状态。

影响详情

  • 摘要影响:同一Kubernetes集群上的Pod能够访问他们本应被网络策略规则阻止访问的网络端点(防火墙绕过)。具体来说,网络策略规则被随机(基于IP地址分配)错误应用。一些Pod将被授予他们不应具有的访问权限。这实际上使EKS中的网络策略规则变得无效。

  • 机密性:暴露了哪些具体数据或信息? 依赖网络控制来保护数据的EKS中运行的服务可能会暴露这些数据。

  • 完整性:系统完整性如何受到影响? 依赖网络策略规则防止未经授权访问端点的服务可能会被访问。

  • 可用性:对服务可用性有哪些潜在影响? 基本上不适用。

处理过程

报告提交后,HackerOne分析员首先要求提供更多详细信息以进行验证,报告者随后提供了详细的分步复现和验证指南。分析员确认了概念验证的有效性,并将严重性评估为中等(4.3)。AWS VDP团队确认报告后,进行了修复开发,并将修复部署到了所有EKS区域。确认修复完成后,报告被关闭并公开披露。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计