🐺Kubernetes ATT&CK

识别容器
首先是Docker再判断是否为K8s
/run/secrets/kubernetes.io/serviceaccount文件是为Pod中的进程和外部用户提供身份信息
主要包含了三个内容
namespace指定了pod所在的namespace
CA用于验证apiserver的证书
token用作身份验证
env环境变量
初始访问
容器内应用漏洞
常用Web应用,由K8s编排Docker部署的Web应用,存在SQL注入、命令执行等,获取到Webshell权限,这时候就拿到了Pod节点权限,通过Pod节点逃逸、横向渗透。
护网中常见的是Shiro拿到权限之后是由K8s部署的,在无法逃逸的情况下,利用Pod节点作为入口点,对内网横向渗透获取其它机器权限。
API Server未授权访问
API Server作为中心组件,通常使用kubectl来访问apiserver,也可以通过Kubernetes各个语言的client库来访问kube-apiserver 同时提供 https(默认监听在 6443 端口)和 http API(默认监听在 127.0.0.1 的 8080 端口)访问。
如运维人员配置不当,将默认监听127.0.0.1更改为0.0.0.0,或者添加了--enable-skip-login选项,将会导致未授权访问。
由于鉴权配置不当,将"system:anonymous"用户绑定到"cluster-admin"用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。
可通过命令查看:
配置有未授权
利用链:
可以通过cdk中的kcurl模块进行利用
查看Pods -> 创建特权容器 -> 执行命令 -> 逃逸完成。
YAML描述文件
提示!
执行
问题原因:
curl/postman不支持从http升级到websocket因此错误
kubelet未授权访问
每个Node节点上都运行一个 Kubelet 服务进程,默认监听 10250 端口,接收并执行 Master 发来的指令,管理 Pod 及 Pod 中的容器。在缺少对TLS身份验证,而在一些默认配置中启用了,--anonymous-auth 默认为true允许匿名身份访问API。
案例:
修改未授权选项:
攻击方式:
新版的k8s认证方式authorization mode默认为webhook,需要 Kubelet 通过 Api Server 进行授权。这样只是将authentication的anonymous改为true也无法利用
利用工具:
etcd获取敏感信息
2379(用于客户端与ectd通信)在默认配置当中是可以直接访问获取些敏感信息。
本地127.1可免认证访问,其他地址要带--endpoint参数和cert进行认证。
通过某搜索引擎:

通过命令方式访问
Dashboard面板暴露
由于鉴权配置不当如添加了--enable-skip-login选项,从而使Dashboard允许匿名用户以管理员权限向集群内部下发指令。

之后进入到终端,进入到/host通过chroot进行切换bash
K8s configfile 泄露
K8s configfile作为K8s集群的管理凭证,其中包含有关K8s集群的详细信息(API Server、登录凭证)。
K8s本身并不维护这类帐户信息,它不会存储到API Server上,仅用于检测用户是否有权限执行所请求的操作。
如办公网机器被入侵、运维电脑存有并且能够访问得到API Server就能够直接接管K8s。
用户凭证保存在kubeconfig 文件中,而kubectl执行命令时会通过以下顺序来找到 kubeconfig 文件:
如果提供了--kubeconfig参数,就使用提供的 kubeconfig 文件。
如果没有提供--kubeconfig 参数,但设置了环境变量 $KUBECONFIG,则使用该环境变量提供的 kubeconfig 文件。
如果以上两种情况都没有,kubectl 就使用默认的 kubeconfig 文件 $HOME/.kube/config。
K8s有两种用户类型:
User Account
Service Account 简称SA
完整利用流程:
K8s configfile --> 创建后门Pod/挂载主机路径 --> 通过Kubectl进入容器 --> 利用挂载目录逃逸。
User Account
Service Account
K8s集群创建的Pod中,容器内部默认携带K8s Service Account的认证凭据(/run/secrets/kubernetes.io/serviceaccount/token),CDK将利用该凭据尝试认证K8s api-server服务器并访问高权限接口,如果执行成功意味着该账号拥有高权限,您可以直接利用Service Account管理K8s集群。
k8s集群部署的时候默认会在每个pod容器中挂载token文件到
/run/secrets/kubernetes.io/serviceaccount/token
在Kubernetes中,授权有ABAC(基于属性的访问控制)、RBAC(基于角色的访问控制)、Webhook、Node、AlwaysDeny(一直拒绝)和AlwaysAllow(一直允许)这6种模式。从1.6版本起,Kubernetes 默认启用RBAC访问控制策略。从1.8开始,RBAC已作为稳定的功能。
BASH利用方式

使用恶意镜像
使用恶意的镜像会危害到集群,例如在Docker Hub拉取不受信任的镜像,可能存在后门以及应用程序版本较低产生的漏洞。
私有镜像仓库
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由VMware开源。配置文件默认密码为:harbor_admin_password: Harbor12345
Harbor 1.8.3前版前本存在: CVE-2019-1609-任意管理员注册
危害:攻击者上传构造好的后门镜像,获取镜像中源代码。
执行
创建后门容器
比如创建:DS、RS、Deployments
最常见的是反弹Shell
利用Service Account
CURL方式请求
kubectl方式请求
持久化
挂载主机路径
Deployments
通过创建容器启用DaemonSets、Deployments,使子容器被清理掉了会恢复
ReplicationController(RC)
ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态。
Replication Set(RS)
Replication Set简称RS,官方已经推荐我们使用RS和Deployment来代替RC了,实际上RS和RC的功能基本一致,目前唯一的一个区别就是RC只支持基于等式的selector
Deployment
主要职责和RC一样的都是保证Pod的数量和健康,二者大部分功能都是完全一致的,我们可以看成是一个升级版的RC控制器
官方组件kube-dns、kube-proxy也都是使用的Deployment来管理
这里使用Deployments来部署后门
Shadow API Server
部署一个shadow apiserver,该apiserver具有和集群中现存的apiserver一致的功能,同时开启了全部K8s管理权限,接受匿名请求且不保存审计日志。便于攻击者无痕迹的管理整个集群以及下发后续渗透行动。
利用链:
1. 拥有master node权限
2. 在攻入的pod内部查找API-server访问地址和凭据
3. 连接apiserver判断权限
4. 获取apiserver原有配置
5. 修改配置
6. 重新部署shadow apiserver
配置文件:
Rootkit
https://github.com/Metarget/k0otkit
DaemonSet和Secret资源(快速持续反弹、资源分离)
利用DaemonSet资源持续反弹,并且创建特权容器。
利用容器名称相似度伪装
利用Meterpreter替代反弹Shell
将Payload隐藏在Secret资源中
kube-proxy镜像(就地取材)
动态容器注入(高隐蔽性)
查找DaemonSet容器,在已启动的容器中添加后门
Meterpreter(流量加密)
无文件攻击(高隐蔽性)
利用memfd_create无文件攻击
cronjob持久化
Job负责处理任务,即仅执行一次的任务
CronJob则就是在Job上加上了时间调度。
权限提升
特权容器逃逸
Docker Socket
Docker漏洞
内核漏洞
Linux Capabilities逃逸
Procfs目录挂载逃逸
Docker Daemon 未授权
K8s漏洞提权
K8s Rolebinding添加用户权限(Cluster-admin binding)
访问集群外资源(Access cloud resources)
探测
内网扫描
K8s常用端口探测
集群内部网络
Cluster内网扫描
集群内网扫描
Kubernetes的网络中存在4种主要类型的通信
同一Pod内的容器间通信
各Pod彼此间通信
Pod与Service间的通信
集群外部的流量与Service间的通信。
所以和常规内网渗透无区别,nmap、masscan等扫描
10/172/192
K8s常用端口探测

集群内部网络
Flannel网络插件默认使用10.244.0.0/16网络
Calico默认使用192.168.0.0/16网络
整体攻击思路
拿到容器
逃逸成功
获取Kubeconfig、执行kubectl控制集群
逃逸失败
Serviceaccount
通过curl、kubectl创建特权容器
逃逸成功,进行控制
探测网络
扫描网段发现控制面板,SSH服务等
API Server
Etcd等
未授权
搞其它的Pod、容器
查找容器中serviceaccount等进行逃逸
横向移动
容器逃逸
通过Service Account访问K8s API
Dashboard面板
ConfigMap
污点(Taint)横向渗透
第三方组件风险
DNS投毒(CoreDNS poisoning)
ARP投毒和IP欺骗(ARP poisoning and IP spoofing)
ConfigMap
提供了向容器中注入配置信息的能力,不仅可以用来保存单个属性,也可以用来保存整个配置文件
一般情况下ConfigMap是用来存储一些非安全的配置信息
污点(Taint)横向渗透
污点是K8s高级调度的特性,用于限制哪些Pod可以被调度到某一个节点。
一般主节点包含一个污点,这个污点是阻止Pod调度到主节点上面,除非有Pod能容忍这个污点。
而通常容忍这个污点的Pod都是系统级别的Pod,例如kube-system
控制Pod创建时候的污点来向集群内的节点进行喷射创建。

第三方组件风险
供应层
自动化和配置:Chef、Puppet、Ansible、Terraform、KubeEdge
镜像仓库:Docker Hub、Harbor、artifactory
运行时层
容器运行时:Containerd、CRI-O、Kata、gVisor、Firecracker
云原生网络:Calico、Weave Net、Flannel、Antrea、NSX-T
编排管理层
编排和调度:Kubernetes、Docker Swarm、Mesos
协调和服务发现:CoreDNS、Etcd、Zookeeper、Eureka
API网关:Kong、Mulesoft、Ambassador
服务网格:lstio、Linkerd、Consul
应用程序定义和开发层
数据库:Postgres、MySQL、Redis
数据流和消息传递:Spark、Kafka、RabbitMQ、Nats
应用程序定义和镜像构建:Helm、Buildpacks、Tilt、Okteto
持续集成和持续交付:Argo、Flagger、Spinnaker、Jenkins
平台层
其它k8s发行版:AgorKube、Canonical、OpenShift
托管Kubernetes:Azure、Alibaba Cloud
监控监测
监控:Prometheus、Cortex、Thanos、Grafana
Last updated
Was this helpful?