【云攻防系列】从攻击者视角聊聊K8S集群安全(上)

news2024/11/24 14:54:12

前言

作为云原生管理与编排系统的代表,Kubernetes(简称K8S)正受到越来越多的关注,有报告[1]显示,96% 的组织正在使用或评估
K8S,其在生产环境下的市场占有率可见一斑。

K8S 的功能十分强大,其系统复杂性也同样较高,一般而言,程序越复杂则越容易存在安全问题,自然而然地,K8S 集群也同样面临着严重的安全威胁,如 K8S
组件的未授权访问、容器逃逸和横向攻击等。我们说攻和防是相互促进、相伴而生的,作为相关安全人员首先应该从整体上把握业务架构可能面临的安全威胁才有可能做好防护。
本文就以攻击者的视角来聊一聊在 K8S 集群架构下可能存在哪些可攻击的点。

根据以往的渗透测试经验,我们梳理了 K8S 集群架构下可能存在的安全问题,并在如图1的 K8S 集群基础架构图中标注了潜在的攻击点:

图1- K8S集群攻击点

本文将从图 1 出发,在介绍图中标注的攻击点的同时,总结一些在对 K8S 集群进行实际渗透测试的过程中常用的攻击方法。

本文共分为上、下两篇,本篇为上篇,主要介绍对 K8S 组件、节点对外服务、业务 pod
的攻击,以及容器逃逸,即对应图1的攻击点1~7。其余内容将在下篇介绍。

K8S集群攻击点(1~7)

1. 攻击点 1~4:攻击K8S组件

K8S 组件的问题主要是指各组件的不安全配置,攻击点1~4罗列了4个比较有代表性的组件问题,即 API Server 未授权访问、etcd
未授权访问、kubelet 未授权访问、kube-proxy 不安全配置。

除此之外,还有很多组件都存在着类似的安全问题,比如 dashboard、docker 等组件也存在未授权访问的隐患,这些都是 K8S
集群的重要系统组件,一旦被攻击成功,都是可以直接获得相应集群、节点或容器的权限的。

表1搜集了各个组件存在隐患的默认端口,供参考:

组件名称

|

默认端口

—|—

api server

|

8080/6443

dashboard

|

8001

kubelet

|

10250/10255

etcd

|

2379

kube-proxy

|

8001

docker

|

2375

kube-scheduler

|

10251

kube-controller-manager

|

10252

表1- K8S 各组件默认端口

2. 攻击点5:攻击节点对外服务

除了正常的对外业务,可能还会有一些“隐藏”的对外开放服务,这些服务本不该暴露在外网,这种情况或是管理员疏忽所致,亦或是为了方便管理而故意留的一些接口,总之也是一个潜在的攻击点。

比如笔者之前遇到过 Mysql 对外服务存在弱口令登录的问题:目标系统的其中一个节点通过 NodePort 对外映射了 Mysql
服务端口,且经过尝试,通过弱口令可登录。这种情况就属于是管理员的安全意识不足。

说到对 Mysql 的攻击,我们在之前的渗透测试过程中总结了三条 Mysql 的攻击路径可供参考,如图2:

图2- Mysql 攻击路径

1. 通过 NodePort 等对外暴露的接口直接访问 Mysql,并通过弱口令登录数据库;(对应图2中步骤1)

2. 攻击应用程序,获取 pod 的 shell,在 pod 内通过环境变量发现 Mysql
服务的内网地址,然后尝试通过弱口令登录;(对应图2中步骤2-1、2-2)

3. 攻击应用程序,获取 pod 的 shell,并成功逃逸到节点,利用 docker inspect 查看或直接进入当前节点运行的Mysql
容器,可以看到其环境变量保存着数据库名、root密码和数据库的登录地址等信息(前提是 Mysql
容器要和应用容器部署在同一节点上,另外环境变量中是否会保存数据库密码等敏感信息取决于 Mysql 容器的具体配置)。(对应图2中步骤3-1、3-2、3-3)

3. 攻击点6:攻击业务 pod

在云原生环境下,上层应用程序对攻击者来说就像是集群的一个个入口,攻击应用程序的目标就是突破入口,拿到业务环境也就是业务所在 pod 的 shell。

Web安全发展这么多年,可利用的漏洞非常之多,远的不说,就比如 2021 年年底曝出的 Log4j2-RCE
漏洞(CVE-2021-44228)以及前不久的 Spring-RCE漏洞(CVE-2022-22965),其危害非常之大,且其利用也很简单(比如
Log4j2 漏洞,虽然在高版本和低版本的JDK环境下利用方法不同,但网上都已经分别有非常多的现成EXP可用),一旦成功利用即可以完全接管整个业务pod。

尽管进入 pod
后的权限仍然是受限的,但总算是进入了集群内部,接下来可以通过尝试更多攻击手法,比如横向、逃逸等,逐步扩大战果,直至控制整个集群。在那之前,我们对 pod
本地也可以实施一些攻击,如信息搜集、提权、拒绝服务。

3.1 信息搜集

进入一个新 pod 中,首先要做的应该是搜集当前环境的信息。

一是搜集环境信息 ,为后续攻击做准备。如下是一些比较有价值的信息,可供参考:

  • OS、Kernel、User 基本信息

  • 可用的 Capabilities

  • 可用的 Linux 命令

  • 挂载情况

  • 网络情况

  • 云厂商的 metadata API 信息

二是敏感服务发现和敏感信息扫描。 敏感服务发现可以通过扫描内网指定网段的端口,除了 K8S 组件的端口外,还有如下的常见服务端口:

  • ssh:22

  • http:80/8080

  • https:443/8443

  • mysql:3306

  • cAdvisor:4194

  • nodeport-service:30000-32767

敏感信息则包括业务相关的敏感文件(比如代码、数据库、业务涉及的 AK/secret 或者重要的配置文件等)、环境变量(可能暴露一些敏感服务信息)、K8S
的ServiceAccount 信息(默认保存在 /run/secrets/kubernetes.io/serviceaccount/
目录下)、进程信息(有无敏感服务)等。

3.2 提权

K8S 中有两种提权,一种是 pod 内提权,一种是 K8S 提权。

(一)Pod 内提权

pod 内提权和传统 Linux 提权差不多,就是将 pod 内普通用户的 shell 提升为 root 权限的 shell。一般来讲,即使拿到了 pod
的 shell 也只能拥有普通用户的权限,此时能做的事情依旧十分有限,所以需要利用提权漏洞拿到 root 权限。提权的方式有很多,比如内核漏洞提权、sudo
提权、suid 提权、cronjob 提权等。

值得一提的是,有些内核漏洞也可以用于容器逃逸,比如著名的 DirtyCow(CVE-2016-5195)、DirtyPipe(CVE-2022-0847)
等,这在下文的“容器逃逸”部分还会提到。

(二)K8S 提权

K8S 提权的方式和场景有很多,比如 RBAC 提权[2],还有一些用于 K8S 提权的 Nday,比如
CVE-2018-1002105、CVE-2020-8559 等。

3.3 拒绝服务

拒绝服务(Denial of Service,DOS)攻击可以从三个层面来看:业务、pod、集群。

对业务和 pod 的 DOS 攻击可以通过使用一些压力测试工具或方法进行,主要可从 CPU、内存、存储、网络等方面进行资源耗尽型攻击。在集群外部或 pod
内都有相应的工具或方法,读者可自行搜索。

在集群层面的 DOS 攻击主要可以利用 K8S 集群的软件漏洞,如 CVE-2019-11253、CVE-2019-9512、CVE-2019-9514
等。

4. 攻击点7:容器逃逸

在云攻防中,拿到容器/ pod 的 shell 往往只是攻击成功的第一步,因为容器本质上就是 Linux 中的一个进程,但是因为受到了 Namespace
和 Cgroup
等机制的诸多限制导致容器内的进程权限是非常低的,容器逃逸就是为了突破这些限制,所以其实容器逃逸也可以认为是一种提权。导致容器逃逸的原因总结起来可分为如下三类:容器不安全配置,相关组件漏洞和内核漏洞。

(1)容器不安全配置

容器不安全配置分为两种情况,第一种情况是赋予了容器危险权限,第二种情况是容器挂载了危险目录。具体如表2所示:

类别

|

不安全配置

—|—

危险权限

|

特权容器

|

cap_sys_admin

|

cap_dac_read_search

|

cap_sys_module

|

cap_sys_ptrace && --pid=host

危险挂载

|

挂载docker.sock

|

挂载procfs

|

挂载/、/root、/etc等文件目录

|

以rw方式挂载lxcfs

|

pod挂载/var/log

表2-容器不安全配置

危险权限指的是 privileged 权限(特权容器)和危险的Capabilities 权限(如
cap_sys_admin,cap_sys_module,cap_sys_dac_search
等),这些都可以在容器启动时通过启动参数设置。如前文所述,容器本质上是一个受限的进程,除了通过 Namespace 和
Cgroup限制了命名空间和资源外,还有 Capabilities、Apparmor、Seccomp
等安全机制限制了容器内进程的权限,如果容器被赋予了以上的危险权限,相当于限制容器的安全机制被打破,这就给攻击者打开了方便之门。

容器挂载危险目录会导致容器文件系统隔离被打破,进而获得特权。比如如果挂载了 /var/run/docker.sock,那么在容器内就能与 docker
守护进程通信,攻击者就可以创建一个特权容器然后逃逸。

这里提到的是容器逃逸攻击手法中最常见的一些不安全配置,此外 CIS Docker Benchmark[3] 针对 docker
容器提出的安全配置基准多达上百条,如此多的安全配置要求也导致了相比于漏洞防护,安全配置的问题往往更容易被忽略。而对攻击者而言,容器的不安全配置往往比下文将要提到的相关程序漏洞和内核漏洞更容易检测和利用。

(2)相关组件漏洞

容器集群环境中包含了非常多的组件程序,它们相互协作,共同构成了庞大的容器服务生态,这些组件包括但不仅限于
runc、containerd、docker、kubelet
等。任何程序都会有漏洞,容器相关的组件程序也不例外,但是这些漏洞和容器不安全配置相比,大多数利用起来都比较困难,例如 CVE-2019-5736
就需要宿主机和容器交互才会触发,而且该漏洞是 “一次性使用” 的并且容易暴露,因为它会破坏 runc。

表3 总结了一些相关组件的常见漏洞:

组件

|

漏洞

—|—

runc

|

CVE-2019-5736

|

CVE-2019-16884

|

CVE-2021-30465

containerd

|

CVE-2020-15257

|

CVE-2022-23648

CRI-O

|

CVE-2022-0811

docker

|

CVE-2018-15664

|

CVE-2019-14271

kubectl

|

CVE-2018-1002100

|

CVE-2019-1002101

|

CVE-2019-11246

|

CVE-2019-11249

|

CVE-2019-11251

kubelet

|

CVE-2017-1002101

|

CVE-2021-25741

表3-容器相关组件的常见漏洞

(3)内核漏洞

容器和虚拟机最大的不同就是容器和宿主机共享内核,如果宿主机的内核存在漏洞,那么该主机上的所有容器都会受到影响。然而并非所有的内核漏洞都可以用于容器逃逸,下面是一些目前已知的可以用于容器逃逸的内核漏洞:

  • CVE-2016-5195

  • CVE-2017-1000112

  • CVE-2017-7308

  • CVE-2020-14386

  • CVE-2021-22555

  • CVE-2022-0185

  • CVE-2022-0492

  • CVE-2022-0847

同样地,内核漏洞的 EXP 利用起来也有风险,如果盲目尝试甚至有可能会导致目标系统崩溃(如果是在内部渗透测试或对系统进行安全检查时尤其需要注意)。

总结

本篇总结和分享了在 K8S 集群中对 K8S 组件、节点对外服务、业务 pod 进行攻击时和进行容器逃逸时的方法和经验,即图1的攻击点 1~7。
在下篇中我们将继续聊一聊图1中的攻击点 8~12,包括横向攻击,以及对 K8S 管理平台、镜像库和第三方组件的攻击。

网络安全工程师企业级学习路线

这时候你当然需要一份系统性的学习路线

如图片过大被平台压缩导致看不清的话,可以在文末下载(无偿的),大家也可以一起学习交流一下。

一些我收集的网络安全自学入门书籍

一些我白嫖到的不错的视频教程:

上述资料【扫下方二维码】就可以领取了,无偿分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/169615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day38【代码随想录】动态规划之斐波那契数、爬楼梯、使用最小花费爬楼梯

文章目录前言一、斐波那契数(力扣509)二、爬楼梯(力扣70)三、使用最小花费爬楼梯(力扣746)总结前言 1、斐波那契数 2、爬楼梯 3、使用最小花费爬楼梯 一、斐波那契数(力扣509) 思路…

详解C语言预处理

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C/C】 本文目录程序的翻译环境和执行环境翻译环境(C语言程序的编译链接)执行(运行)环境…

扩展Linux根目录磁盘空间

问题:如果一开始创建虚拟机,挂载给虚拟机根目录(/)的磁盘空间太小了,所以磁盘空间很快就会填满。如果根目录的磁盘空间占用超过90%,会导致无法再新安装软件。 查看根目录磁盘空间: 可以--右键…

导入若依项目数据库脚本到mysql数据库

使用DBeaver工具连接本地mysql数据库 在之前的文章中,已经介绍过,怎么样去寻找某款软件的替代软件了,如果不知道怎么找的,可以再看看之前的文章:为大家介绍一个我常用的搜索同类替代软件的网站 大家都知道,…

day18集合

1.Map集合 1.1Map集合概述和特点【理解】 Map集合概述 interface Map<K,V> K&#xff1a;键的类型&#xff1b;V&#xff1a;值的类型Map集合的特点 双列集合,一个键对应一个值键不可以重复,值可以重复 Map集合的基本使用 public class MapDemo01 {public static void…

Linux常用命令——trap命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) trap 指定在接收到信号后将要采取的动作 补充说明 trap命令用于指定在接收到信号后将要采取的动作&#xff0c;常见的用途是在脚本程序被中断时完成清理工作。当shell接收到sigspec指定的信号时&#xff0c;ar…

数据类型(个人学习笔记)

这里写自定义目录标题数据类型浮点型数据浮点型常量浮点型变量字符串数据字符串型常量混合运算与printf()printf模型进制转换数据类型 常量&#xff1a;整形、实型&#xff08;浮点&#xff09;、字符型和字符串型 变量&#xff1a;变量名、变量值 整型数据 define 直接将字…

Windows 服务器刷题(带答案)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.刷题 前言 本章将会讲解Windows服务器刷题 一.刷题 1.[多选题]windows …

一编文章就让你明白什么是ES6

一、ES6 简介 1.什么是 ES6 ? ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。 ES6 实际上是一个泛指&#xff0c;泛指 ES2015 及后续的版本。 2.为什么使用 ES6 ? 每一次标准的诞生都意味着语言的完善&#xff0c;功能的加强。…

卷积神经网络-猫狗识别(附源码)

一&#xff0c;项目描述该项目将使用卷积神经网络算法&#xff0c;识别图片中的动物是猫还是狗数据集地址&#xff1a;https://momodel.cn/explore/5efc77dbc018c95e69fb2a81?typedataset其中&#xff0c;训练用的图片数据集在 dogs_cats/data 文件夹下&#xff0c;整个数据集…

计算机视觉Computer Vision课程学习笔记六之Fourier Analysis傅里叶分析

第六章 傅里叶分析 处理图像频率信息 图像的频率是表征图像中灰度变化剧烈程度的指标&#xff0c;是灰度在平面空间上的梯度。 从纯粹的数学意义上看&#xff0c;傅立叶变换是将一个函数转换为一系列周期函数来处理的。从物理效果看&#xff0c;傅立叶变换是将图像从空间域转换…

LinkedList链表知识点概括(一)

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主 专栏&#xff1a;数据结构 作者简介&#xff1a;大三学生&#xff0c;希望2023年迎来更优秀的自己&#xff01;希望跟大家一同进步~ 文章目录 前言 一、链表的基本概念 二、面试题实战 前言 顺序表/ArrayList:…

vue2中keepalive手动清理内存,存在子路由内存无法回收的问题

起因 近期客户经常反馈系统崩溃的问题&#xff0c;尤其是在下午最频繁&#xff0c;经过自己的自测&#xff0c;发现系统tab关闭后内存并没有回收掉&#xff0c;目前我已经处理了&#xff0c;tab页签关闭后&#xff0c;手动清理keep-alive内的缓存&#xff0c;应该不存在内存泄…

Qt+C++自定义标题栏最大最小化关闭堆叠切换美化

程序示例精选 QtC自定义标题栏最大最小化关闭堆叠切换美化 如需安装运行环境或远程调试&#xff0c;见文章底部个人微信名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<QtC自定义标题栏最大最小化关闭堆叠切换美化>>编写代码&#xff0c…

这几个办公技巧竟还不知道

技巧一&#xff1a;压缩文件大小 我们可以通过压缩文件大小的方法来减少电脑内存&#xff0c;正好Windows就有自带的压缩包可以操作。 首先我们可以用鼠标右击文件&#xff0c;选择“添加到压缩文件”&#xff0c;最后系统即可帮我们自动压缩文件大小。技巧二&#xff1a;定时清…

C++封装对MySQL的基本操作

1.环境搭建在这里&#xff0c;我将使用vscode来搭建MySQL的编程环境。首先&#xff0c;下载MySQL&#xff0c;配置好系统环境变量并运行MySQL数据库。接着&#xff0c;vscode扩展中搜索并下载MySQL与MySQL Syntax插件。安装完成后&#xff0c;在资源管理器的MySQL栏中点击号&am…

从0到1完成一个Node后端(express)项目(五、session、token)

往期 从0到1完成一个Node后端&#xff08;express&#xff09;项目&#xff08;一、初始化项目、安装nodemon&#xff09; 从0到1完成一个Node后端&#xff08;express&#xff09;项目&#xff08;二、下载数据库、navicat、express连接数据库&#xff09; 从0到1完成一个Nod…

“暗黑天使”降临:DarkAngels勒索病毒全解密

恶意文件分析 恶意文件描述 近期&#xff0c;深信服深盾终端实验室在运营工作中发现了一种 ELF 格式的勒索软件&#xff0c;该勒索软件近期开始出现&#xff0c;其释放的勒索信中的 Onion 链接似乎已关闭&#xff0c;这表明该勒索软件可能仍在开发中。 经过分析&#xff0c;…

AtCoder Beginner Contest 281 (A-F,口胡G)青大acmer 日常vp

A - Count Down 输出小于等于nnn的数 代码 B - Sandwich Number 题意 问字符串是否是第一个和最后一个字符是大小写&#xff0c;中间的字符是100000−99999100000-99999100000−99999之间的数字。 暴力模拟即可&#xff0c;需要注意的例子是A0100000AA0100000AA0100000A 代码 …

day14-常用API

1.API 1.1 API概述【理解】 什么是API ​ API (Application Programming Interface) &#xff1a;应用程序编程接口 java中的API ​ 指的就是 JDK 中提供的各种功能的 Java类&#xff0c;这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff…