服务器之家:专注于服务器技术及软件下载分享
分类导航

服务器资讯|IT/互联网|云计算|区块链|软件资讯|操作系统|手机数码|百科知识|免费资源|头条新闻|

服务器之家 - 新闻资讯 - 云计算 - 云原生安全-从k8s日志审计视角检测自动化工具攻击

云原生安全-从k8s日志审计视角检测自动化工具攻击

2023-05-06 18:55未知服务器之家 云计算

来源:哔哩哔哩技术 1. 前言 1.1 背景 随着云原生技术的普及,其暴露出来的攻击面也被黑客们念念不忘,相关的攻击技术也跟着被“普及”,自动化漏洞利用攻击工具更是如雨后春笋般出现在GitHub开源平台,其中比较有代表性的如

来源:哔哩哔哩技术


1. 前言


1.1 背景


随着云原生技术的普及,其暴露出来的攻击面也被黑客们念念不忘,相关的攻击技术也跟着被“普及”,自动化漏洞利用攻击工具更是如雨后春笋般出现在GitHub开源平台,其中比较有代表性的如cdk-team/CDK。其是一款为容器环境定制的渗透测试工具,在已攻陷的容器内部提供零依赖的常用命令及PoC/EXP。集成Docker/K8s场景特有的 逃逸、横向移动、持久化利用方式,插件化管理。

在漏洞利用门槛如此低廉的今天,作为企业安全的建设者(搬砖人),除了考虑部署容器层面运行时检测平台,在k8s api-server层面,启用日志审计功能,也是一个成本低廉又高效发现入侵攻击的途径。

通过对api-server的日志进行审计分析,对于攻击者的信息收集行为,部署k8s cronjob后门、利用rbac做权限提升等持久化攻击行为都能及时的发现并输出告警。


1.2 kubernetes日志审计介绍


Kubernetes 审计功能提供了与安全相关的按时间顺序排列的记录集,记录单个用户、管理员或系统其他组件影响系统的活动顺序。 它能帮助集群管理员处理以下问题:









-发生了什么?-什么时候发生的?-谁触发的?-为什么发生?-在哪观察到的?-它从哪触发的?-它将产生什么后果?


审计日志示例(图片来自参考[5]


云原生安全-从k8s日志审计视角检测自动化工具攻击


如何开启日志审计

1、api-server命令行启动时,添加如下参数








--audit-policy-file=/etc/kubernetes/audit/audit-default-policy.yaml#审计策略文件--audit-log-path=/data/log/audit/audit.log#kube-apiserver输出的审计日志文件,此处以日志文件落地的方式做日志收集--audit-log-maxbackup=10#kube-apiserver审计日志文件的最大备份数量--audit-log-format=json#日志保存格式--audit-log-maxage=10#日志最大保留时间--audit-log-maxsize=500#单个日志文件最大为500M


2、kubeadm启动时

修改api-server配置文件/etc/kubernetes/manifests/kube-apiserver.yaml,增加如下内容








--audit-policy-file=/etc/kubernetes/audit/audit-default-policy.yaml--audit-log-path=/data/log/audit/audit.log--audit-log-maxbackup=10--audit-log-format=json--audit-log-maxage=10--audit-log-maxsize=500


2. 攻击行为检测


2.1 分析流程


若攻击者通过各种手段拿到一个容器shell环境后,下一步必然是利用这个容器进行信息收集,获取更多敏感信息或机器资源,此时,CDK作为一款自动化的攻击工具,就让整个攻击过程如虎添翼,大大提高攻击效率。

作为甲方安全的守护者,从安全建设的角度,如何有效及时的发现攻击者的入侵行为,是一个无法避开的问题。本文通过观察cdk的攻击行为,从k8s日志审计的角度罗列一些入侵检测的常见规则。

目前,针对于日志的审计分析,我们落地方案的整个流程为:


云原生安全-从k8s日志审计视角检测自动化工具攻击


注:下列场景,仅限于原生的CDK行为检测,如果攻击者具备开发能力,修改对应特征,可以绕过对应的检测规则。


2.2 信息收集


CDK在容器内主要收集以下信息:


云原生安全-从k8s日志审计视角检测自动化工具攻击


工具在镜像内运行,其信息收集的结果执如下:


云原生安全-从k8s日志审计视角检测自动化工具攻击


从图上可知,信息收集的整个过程,存在与api-server交互的仅有网络探测部分,总共会向api-server发送三条请求,分别为API-server、namespace、api信息探测。


2.2.1 探测API-server


audit.log































{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","stage":"ResponseComplete","requestURI":"/","verb":"get","user":{"username":"system:anonymous","groups":["system:unauthenticated"]},"sourceIPs":["172.18.0.2"],"userAgent":"Go-http-client/1.1","responseStatus":{"metadata":{},"status":"Failure","reason":"Forbidden","code":403},"requestReceivedTimestamp":"2023-02-02T08:29:12.189459Z","stageTimestamp":"2023-02-02T08:29:12.189553Z","annotations":{"authorization.k8s.io/decision":"forbid","authorization.k8s.io/reason":""}}


2.2.2 列举namespace


audit.log








































{  "kind": "Event",  "apiVersion": "audit.k8s.io/v1",  "level": "Metadata",  "auditID": "41770e7a-1827-4a14-860f-a812d3db1647",  "stage": "ResponseComplete",  "requestURI": "/api/v1/namespaces",  "verb": "list",  "user": {    "username": "system:serviceaccount:test:default",    "uid": "63b8dd88-88dd-4426-bdd1-7966906dc0d5",    "groups": [      "system:serviceaccounts",      "system:serviceaccounts:test",      "system:authenticated"    ]  },  "sourceIPs": [    "172.18.0.2"  ],  "userAgent": "Go-http-client/1.1",  "objectRef": {    "resource": "namespaces",    "apiVersion": "v1"  },  "responseStatus": {    "metadata": {},    "status": "Failure",    "reason": "Forbidden",    "code": 403  },  "requestReceivedTimestamp": "2023-02-02T08:29:12.205422Z",  "stageTimestamp": "2023-02-02T08:29:12.205485Z",  "annotations": {    "authorization.k8s.io/decision": "forbid",    "authorization.k8s.io/reason": ""  }}


2.2.3 探测可访问的api


跟namespace类似,只不过requestURI为/apis


2.2.4 总结


综上, 上述日志中可概述为,当cdk在做信息收集时,会向api-server请求3次,分别访问/,/apis,/api/v1/namespaces,可根据这些特征做告警规则





1、userAgent:Go-http-client/1.1#CDK特定的userAgent,此时,该字段为主要特征2、responseStatus.code:403#默认serviceaccount无权限时api-server返回的状态码3、requestURI:/#访问根目录


2.3 漏洞利用


Exploit模块包含的功能:


云原生安全-从k8s日志审计视角检测自动化工具攻击


2.3.1 容器逃逸


其中,容器逃逸层面,一般是不需要与api-server做交互的,也就不会留下日志。但部分容器逃逸手段是利用错误配置的pod在创建时实施攻击。因此,容器逃逸的检测必须前置到容器创建时,记录下应用请求的权限,然后结合运行时入侵检测做进一步监控。

当一个拥有privilege、sys_admin、network、ipc等特殊权限的pod创建时,它的日志记录是这样的。


audit.json



























































































































{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"RequestResponse","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/testpods/pods","verb":"create","user":{"username":"kubernetes-admin","groups":["system:masters","system:authenticated"]},"sourceIPs":["172.18.0.1"],"userAgent":"kubectl1.16.15/v1.16.15(darwin/amd64)kubernetes/2adc8d7","objectRef":{"resource":"pods","namespace":"testpods","name":"testpod","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":201},"responseObject":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"testpod","namespace":"testpods","selfLink":"/api/v1/namespaces/testpods/pods/testpod","uid":"e717d204-7e6d-4608-998b-648a8667e8e1","resourceVersion":"13517","creationTimestamp":"2023-02-02T09:51:10Z","labels":{"creator":"zhiye","team":"teamf"}},"spec":{"volumes":[{"name":"rootfs","hostPath":{"path":"/","type":""}}],"containers":[{"name":"trpe","image":"alpine","command":["/bin/sh","-c","tail-f/dev/null"],"resources":{},"volumeMounts":[{"name":"default-token-mm6s8","readOnly":true,"mountPath":"/var/run/secrets/kubernetes.io/serviceaccount"}],"terminationMessagePath":"/dev/termination-log","terminationMessagePolicy":"File","imagePullPolicy":"Always","securityContext":{"capabilities":{"add":["SYS_ADMIN"]},"privileged":true}}],"restartPolicy":"Always","terminationGracePeriodSeconds":30,"dnsPolicy":"ClusterFirst","serviceAccountName":"default","serviceAccount":"default","hostNetwork":true,"hostPID":true,"hostIPC":true,"securityContext":{},"schedulerName":"default-scheduler","tolerations":[{"key":"node.kubernetes.io/not-ready","operator":"Exists","effect":"NoExecute","tolerationSeconds":300},{"key":"node.kubernetes.io/unreachable","operator":"Exists","effect":"NoExecute","tolerationSeconds":300}],"priority":0,"enableServiceLinks":true},"status":{"phase":"Pending","qosClass":"BestEffort"}},"requestReceivedTimestamp":"2023-02-02T09:51:10.632436Z","stageTimestamp":"2023-02-02T09:51:10.660958Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":""}}


从日志上可以看出,针对于错误配置导致的逃逸,我们可以关注以下几个日志字段,制定告警规则。










responseObject.spec.volumes#检测敏感卷,是否挂载docker.sock等responseObject.spec.containers.volumeMounts#检测敏感挂载,是否挂载docker.sock等responseObject.spec.containers.securityContext.capabilities.add#是否使用SYS_ADMIN权限,(字段嵌套这么多层,真的得吐槽responseObject.spec.containers.securityContext.privileged#检测是否为特权pod容器responseObject.spec.hostNetwork#是否使用宿主机网络responseObject.spec.hostPID#是否使用宿主机hostPIDresponseObject.spec.hostIPC#是否共享宿主机内存responseObject.spec.serviceAccount#是否使用特殊的serviceaccount默认为default


2.3.2 网络探测


此功能为端口扫描+指纹识别,不涉及与API交互,未产生日志。


2.3.3 信息窃取


与api-server交互的为secrets、config和psp,如果是自动获取的话,cdk会发送两次请求,分别使用匿名账户和当前serviceaccout做list动作。

下边列举些主要特征









requestURI:/api/v1/secrets,requestURI:/api/v1/configmapsrequestURI:/apis/policy/v1beta1/podsecuritypoliciesuserAgent:Go-http-client/1.1user.username:"system:anonymous"responseStatus.code:403"verb":"list"


2.3.4 权限提升


RBAC权限绕过

日志如下





















































{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"RequestResponse","auditID":"bfc643d6-8337-434e-9dec-ba41dd36bfa7","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/kube-system/pods","verb":"create","user":{"username":"system:serviceaccount:test:default","uid":"63b8dd88-88dd-4426-bdd1-7966906dc0d5","groups":["system:serviceaccounts","system:serviceaccounts:test","system:authenticated"]},"sourceIPs":["172.18.0.3"],"userAgent":"Go-http-client/1.1","objectRef":{"resource":"pods","namespace":"kube-system","apiVersion":"v1"},"responseStatus":{"metadata":{},"status":"Failure","reason":"Forbidden","code":403},"responseObject":{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"podsisforbidden:User\"system:serviceaccount:test:default\"cannotcreateresource\"pods\"inAPIgroup\"\"inthenamespace\"kube-system\"","reason":"Forbidden","details":{"kind":"pods"},"code":403},"requestReceivedTimestamp":"2023-02-03T09:56:24.061825Z","stageTimestamp":"2023-02-03T09:56:24.061888Z","annotations":{"authorization.k8s.io/decision":"forbid","authorization.k8s.io/reason":""}}


由上可发现如下特征:












Pod内serviceaccount无权限的情况requestURI: /api/v1/namespaces/kube-system/podsuserAgent: Go-http-client/1.1responseStatus.code: 403 
Pod内serviceaccount有权限的情况requestURI: /api/v1/namespaces/kube-system/podsresponseObject.metadata.selfLink: /api/v1/namespaces/kube-system/pods/cdk-rbac-bypass-create-pod responseObject.metadata.spec.containers.args: *cat /run/secrets/kubernetes.io/serviceaccount/token* verb: create


2.3.5 持久化


部署daemonset后门

源码是这样定义的(参考[6]):


云原生安全-从k8s日志审计视角检测自动化工具攻击


体现到日志中,有以下几个点:









objectRef.name:cdk-backdoor-daemonsetobjectRef.namespace:kube-systemresponseObject.metadata.selfLink:/apis/apps/v1/namespaces/kube-system/daemonsets/cdk-backdoor-daemonsetresponseObject.spec.template.spec.volumes.hostPath.path:/responseObject.spec.template.spec.containers.name:cdk-backdoor-podresponseObject.spec.template.spec.containers.securityContext[capabilities:ptivileged]:如图上所示responseObject.spec.template.spec.[hostNetwork|hostPID]:true


部署K8S CronJob

CDK源代码是这样定义的(参考[7]):


云原生安全-从k8s日志审计视角检测自动化工具攻击


体现在日志中,特征有以下几点:








requestURI:/apis/batch/v1beta1/namespaces/kube-system/cronjobsverb:createobjectRef.name:cdk-backdoor-cronjobresponseObject.matadata.name:cdk-backdoor-cronjobresponseObject.matadata.selfLink:/apis/batch/v1beta1/namespaces/kube-system/cronjobs/cdk-backdoor-cronjobresponseObject.spec.jobTemplate.spec.template.spec.containers.name:cdk-backdoor-cronjob-container


部署影子k8s api-server

在pod权限足够的情况下,通过创建shadow api-server做权限维持,详情见参考[4]

在非二开的情况下,通过k8s日志升级可检测以下几个字段





objectRef.name:*-shadow-*responseObject.metadata.labels.component:kube-apiservershadowresponseObject.spec.containers.command:"--secure-port=9444"


2.3.6 总结


因为漏洞利用部分,动作都普遍较大,因此可观测字段已不仅仅局限于userAgent,其特征均比较明显,极富有工具本身特色


2.4 API利用


2.4.1 Tool模块


此处需要关注的(跟api-server有交互的)为kcurl命令,此命令可借助高权限serviceaccount账户列举/使用k8s资源。

执行./cdk kcurl default get '' ,日志内容如下:


audit.log





































{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"418cafa5-2c1e-4fbf-b086-3d68e321d2bb","stage":"ResponseComplete","requestURI":"/api/v1/nodes","verb":"list","user":{"username":"system:serviceaccount:test:default","uid":"63b8dd88-88dd-4426-bdd1-7966906dc0d5","groups":["system:serviceaccounts","system:serviceaccounts:test","system:authenticated"]},"sourceIPs":["172.18.0.3"],"userAgent":"Go-http-client/1.1","objectRef":{"resource":"nodes","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2023-02-06T09:51:51.790260Z","stageTimestamp":"2023-02-06T09:51:51.791075Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC:allowedbyClusterRoleBinding\"defaultadmin\"ofClusterRole\"cluster-admin\"toServiceAccount\"default/test\""}}


日志中annotations.authorization.k8s.io/reason给出了允许执行的原因。我们可以根据如下三个字段制定告警规则:











serviceaccount有权限的情况下:annotations.authorization.k8s.io/reasonannotations.authorization.k8s.io/decisionuserAgent: Go-http-client/1.1responseStatus.code:200
无权限的情况下:userAgent: Go-http-client/1.1responseStatus.code:403


2.4.2 总结


因为tool模块需要借助高权限serviceaccount或token,因此,权限不足的情况下,api-server返回responseStatus.code: 403 的条目说明了api-server接受到了非预期请求,结合userAgent等信息便可输出可疑告警。


3. 不仅仅是CDK


3.1 CVE-2022-3172 K8S聚合

API(Aggregation API)SSRF漏洞.


聚合API实际上是在kube-apiserver中运行的,在新API注册之前,它并不会工作。如果要添加新的API,则需要创建一个APIService对象,用来申请Kubernetes中新的URL路径。注册成功后,当有发送到此路径中的请求,则会被转发到已经注册的APIService上。

APIService可以将客户端的请求转发到任意的URL上,这就有可能会导致Client发送请求时,所携带的一些认证信息可能会被发送给第三方。

通过日志审计监控responseStatus.code字段来进行判断是否有出现重定向的情况,通过检测如下字段:




responseObject.code:302responseObject.code:301


3.2 使用不合规镜像创建pod


除了cdk这种常见的攻击手法,还有一些常见的异常行为需要我们关注,比如一般企业内,pod创建使用的容器均会从企业私有的镜像仓库中拉取,此时如果日志中出现了公共仓库的镜像,则可判断为异常,可关注以下字段






verb:createlevel:RequestResponseesponseObject.kind:PodrequestObject.spec.containers.image:镜像仓库地址


3.3 pod命令执行


对于kubectl exec命令进行监控,可对如下字段进行监控,注:命令执行的后续无法通过日志审计来进一步监控,需结合运行时检测进一步分析





objectRef.subresource:execobjectRef.subresource:attachuserAgent


4. 落地实践踩过的坑


1、主要为k8s日志类型比较多,且每种类型的字段名,字段数量均不一致,导致es在存储数据时存在索引内字段类型不一致无法解析存储的问题。

解决方案为对于字段不一致的obj,选择为不做深层次解析。(或者使用hdfs等存储方式,查询时对字段进行解析

2、日志量过大,导致api-server磁盘读写io过高

持续优化audit.yaml中的日志规则,对于其中的node/status,pod/status,coordination.k8s.io/leases等不做日志记录。


5. 总结


本文从k8s日志审计的角度,分析当使用cdk等自动化攻击时,能够从日志中获取到的信息,并给出通过这些信息可监控字段的告警示例。因为这部分字段都比较固定,完全可以通过机器学习提升告警准确率。抛砖引玉,希望后续可以看到更多日志的分析防御角度。

当然,CDK作为开源工具,这些特征都可以做关键字替换。因此,笔者认为功夫应该用到平时,加强k8s的基线管控,比如避免出现高serviceaccount权限、通过准入策略限制使用的docker镜像,并部署容器运行时入侵检测平台。让安全能力覆盖每个环节,才能保证集群的安全稳定。


6. 参考


[1]

[2]

[3]

[4] https://discuss.kubernetes.io/t/security-advisory-cve-2022-3172-aggregated-api-server-can-cause-clients-to-be-redirected-ssrf/21322

[5]https://github.com/tencentyun/qcloud-documents/blob/master/product/%E5%AD%98%E5%82%A8%E4%B8%8ECDN/%E6%97%A5%E5%BF%97%E6%9C%8D%E5%8A%A1/%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/TKE%20%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97%E5%88%86%E6%9E%90.md

[6]/blob/main/pkg/exploit/k8s_backdoor_daemonset.go#LL35-L87C2

[7]/blob/main/pkg/exploit/k8s_cronjob.go#LL34-L59C2


延伸 · 阅读

精彩推荐
  • 云计算企业需要了解的十个云安全优秀实践

    企业需要了解的十个云安全优秀实践

    IT 安全社区因其共享信息和解决方案的特性而备受认可。如果企业正在迁移到云端,或者倾向于提高应用程序的安全性,可以很好地利用这一点。...

    云联壹云9592022-02-17
  • 云计算云原生开发将成为高级部署蓝图

    云原生开发将成为高级部署蓝图

    如今,有些文章介绍了云原生开发蓝图的基础和探索逻辑图,并探讨了在内部部署设施和远程容器上进行云原生开发的用例以及部署蓝图。...

    企业网D1Net2852020-07-12
  • 云计算微软与印度信实工业子公司将在云计算等领域进行合作

    微软与印度信实工业子公司将在云计算等领域进行合作

    【TechWeb】8月13日消息,据国外媒体报道,印度信实工业旗下子公司将同微软进行长期的合作,涉及云计算、人工智能等多个领域。 信实工业公司已在官网...

    Techweb3542019-08-14
  • 云计算关于云原生安全,你得关注这些事!

    关于云原生安全,你得关注这些事!

    变化是唯一不变的,也是不可避免的。一段时间以来,云技术领域的 IT 格局发生了变化。企业正在转向云原生领域和容器、Kubernetes和无服务器框架。...

    新钛云服11442021-09-28
  • 云计算使用虚拟私有云的利弊

    使用虚拟私有云的利弊

    虚拟私有云(VPC)实际上是公共云提供商的营销响应,很多提供商发现自己与多年前就已经与OpenStack等私有云竞争。一些企业并不喜欢将数据放置在公共云...

    机房3605782020-06-05
  • 云计算Kubernetes 将弃用 Docker

    Kubernetes 将弃用 Docker

    近日,Kubernetes 官方发布公告,宣布自 v1.20 起放弃对 Docker 的支持,届时用户将收到 Docker 弃用警告,并需要改用其他容器运行时。但 Docker 作为容器镜像构...

    开源中国4312020-12-03
  • 云计算Rancher 2.7.2 发布,开放的可互操作性再升级

    Rancher 2.7.2 发布,开放的可互操作性再升级

    Rancher 2.7.2 正式发布,主要提升了扩展性,以大幅强化生态能力。此外,作为 Rancher 的商用企业订阅版,Rancher Prime 进一步强化了其企业订阅价值;Rancher De...

    未知732023-05-06
  • 云计算加快边缘计算发展的十大趋势

    加快边缘计算发展的十大趋势

    在边缘计算中,数据处理发生在网络边缘而不是集中式中心。这意味着网络边缘的设备需要具有处理和存储功能。实际上,边缘计算有许多不同的形式。企...

    企业网D1Net2672020-10-20