云安全
https://wiki.teamssix.com
云服务安全
云服务,顾名思义就是云上的服务,简单的来说就是在云厂商(例如 AWS、阿里云)那里买的服务
云服务
- S3 对象存储
Simple Storage Service
,简单的说就是一个类似网盘的东西,当然跟网盘是有一定区别的 - EC2 即弹性计算服务
Elastic Compute Cloud
,简单的说就是在云上的一台虚拟机 - RDS 云数据库
Relational Database Service
,简单的说就是云上的一个数据库 - IAM 身份和访问管理
Identity and Access Management
,简单的说就是云控制台上的一套身份管理服务,可以用来管理每个子账号的权限
EC2
EC2 所面临的风险
凭证泄漏
云场景下的凭证泄露可以分成以下几种:
- 控制台账号密码泄露,例如登录控制台的账号密码
- 临时凭证泄露
- 访问密钥泄露,即 AccessKeyId、SecretAccessKey 泄露
- 实例登录凭证泄露,例如 AWS 在创建 EC2 生成的证书文件遭到泄露
对于这类凭证信息的收集,一般可以通过以下几种方法进行收集:
- Github 敏感信息搜索
- 反编译目标 APK、小程序
- 目标网站源代码泄露
https://wiki.teamssix.com/CloudService/EC2/
云原生安全
docker
Docker 所面临的风险
判断当前机器是否为 Docker 容器环境
Metasploit 中的 checkcontainer 模块、(判断是否为虚拟机,checkvm 模块)该模块其实进行了如下操作
-
检查根目录下是否存在
.dockerenv
文件
检查/proc/1/cgroup
是否存在含有 docker 字符串
检查是否存在 container 环境变量
通过env
\PATH
来检查是否有docker相关的环境变量,来进一步判断 -
其他检测方式
如检测mount、fdisk -l 查看硬盘 、判断PID 1的进程名等也可用来辅助判
1、容器镜像存在的风险
#不安全的第三方组件
例如开发者在代码中引入了存在漏洞版本的 log4j2 组件,然后将其打包成了业务镜像。这样即使代码没有漏洞,但因为引入了不安全的第三方组件也变得有漏洞了。
再比如开发者在 Django 镜像的基础上,编写了自己的 Python 代码,然后将其打包成镜像。这样如果在 Django 镜像里引用了不安全的第三方组件或者 Django 自身存在漏洞,自己打包的镜像也同样会受到影响。
#不安全的镜像
在公共镜像仓库比如 Docker Hub 里,会存在一些有漏洞的镜像或者恶意镜像,如果使用了这些镜像那就存在风险了。
#敏感信息泄露
如果开发者为了开发、调试方便,可能会将数据库账号密码、云服务密钥之类的敏感数据打包到了镜像里,那别人获取到这个镜像后,就会导致敏感信息泄露了。
2、活动中的容器存在的风险
#不安全的容器应用
在使用容器时,往往会需要进行端口映射,比如把 MySQL 的 3306 端口映射出来,如果 MySQL 被配置了弱密码,那就存在被利用的风险了。
除此之外,如果一个 Web 服务端口被映射出来,同时这个 Web 服务存在漏洞,那么也同样是存在风险的。
#不受限制的资源共享
容器运行在宿主机上,容器必然要使用宿主机的各种 CPU、内存等资源,如果没有对容器进行资源使用限制,那么就存在宿主机被资源耗尽的风险。
#不安全的配置与挂载
如果为容器设定了不安全的配置,会导致容器本身的隔离机制失效,容器的两大隔离机制如下:
Linux 命名空间(NameSpace):实现文件系统、网络、进程、主机名等方面的隔离
Linux 控制组(cgroups):实现 CPU、内存、硬盘等方面的隔离
如果设定了以下配置就会导致相应的隔离机制失效:
–privileged:使容器内的 root 权限和宿主机上的 root 权限一致,权限隔离被打破
–net=host:使容器与宿主机处于同一网络命名空间,网络隔离被打破
–pid=host:使容器与宿主机处于同一进程命令空间,进程隔离被打破
–volume /:/host:宿主机根目录被挂载到容器内部,文件系统隔离被打破
3、容器管理程序接口的风险
Docker 守护进程主要监听 UNIX socket 和 TCP socket,默认情况下,Docker 只会监听 UNIX socket
#UNIX socket
UNIX socket 的风险主要在于 Docker 守护进程默认以宿主机的 root 权限运行,因此就可以借助这点进行提权或者容器逃逸。
这类风险主要有两个利用场景:
普通用户被加到 Docker 用户组内
如果普通用户被加入到 Docker 用户组内,那么普通用户也将有权限访问 Docker UNIX socket,如果攻击者获得了这个普通用户权限,就可以借助 Docker 提权到 root 用户权限。
具体的做法可以简单描述为:使用普通用户创建一个 privileged 为 true 的容器,在该容器内挂载宿主机硬盘并写入定时任务,然后将宿主机的 root 权限反弹回来,后期将详细介绍这种方法的使用。
UNIX socket 挂载到容器内部
有时为了实现容器内部管理容器,可能会将 Docker UNIX socket 挂载到容器内部,那么如果该容器被入侵,RT 就可以借助这个 socket 进行容器逃逸获得宿主机 root 权限。
#TCP socket
现在 Docker 守护进程默认不会监听 TCP socket,不过有时可能用户会因为方便开启 TCP socket 的监听,一般默认监听端口是 2375
默认情况下,Docker 守护进程 TCP socket 是无加密无认证的,因此如果发现宿主机 Docker 开放了 TCP socket,就可以直接使用 docker -H 接管目标的容器
4、其他风险
#容器网络风险
虽然默认情况下,容器内部的网络与宿主机是隔离的,但是每个容器之间是彼此互相连通的,理论上在容器之间是存在内网横向的风险的。
#宿主机操作系统风险
容器通常与宿主机共享内核,也就是说如果宿主机内核存在漏洞,意味着容器可能也会存在相同的漏洞。
例如如果宿主机存在脏牛漏洞,那么拿到容器权限后,使用脏牛漏洞就可以获得宿主机权限,实现容器逃逸。
#软件自身的漏洞
Docker 自身存在的一些漏洞,比如 CVE-2019-14271、CVE-2019-5736 等都可以导致容器逃逸,这些也都是风险点,后面会对这些漏洞进行尝试复现。
Docker逃逸
Docker 逃逸相关总结
https://xz.aliyun.com/t/8558
Docker 逃逸相关总结
-
危险的配置导致Docker 逃逸
Docker 已经将容器运行时的 Capabilities 黑名单机制改为如今的默认禁止所有 Capabilities,再以白名单方式赋予容器运行所需的最小权限
Docker Remote API 未授权访问
启动一个容器,并将宿主机的 /etc 目录挂载到容器中,便可以任意读写文件了。我们可以将命令写入 crontab 配置文件,进行反弹 shell
-
危险挂载导致 Docker 逃逸
在 docker 容器中调用和执行宿主机的 docker,将 docker 宿主机的 docker 文件和 docker.sock 文件挂载到容器中,在新容器的目录下,就可以访问到宿主机的全部资源,接下来就是写入 SSH 密钥或者写入计划任务,获取 shell
-
程序漏洞导致 Docker 逃逸
Docker cp 命令容器逃逸攻击漏洞 CVE-2019-14271
**漏洞描述:**当 Docker 宿主机使用 cp 命令时,会调用辅助进程 docker-tar,该进程没有被容器化,且会在运行时动态加载一些 libnss.so 库。黑客可以通过在容器中替换 libnss.so 等库,将代码注入到 docker-tar 中。当 Docker 用户尝试从容器中拷贝文件时将会执行恶意代码,成功实现 Docker 逃逸,获得宿主机root权限
**影响版本:**Docker 19.03.0 -
内核漏洞导致 Docker 逃逸
Docker 与宿主机共享内核,因此如果宿主机内核存在问题的话容易也存在
Dirty Cow(CVE-2016-5195)是 Linux 内核中的权限提升漏洞,通过它可实现 Docker 容器逃逸,获得 root 权限的 shell
K8s
K8s 所面临的风险
未授权问题是目前 k8s 存在最多的问题
未授权访问端口 | 功能 | 利用方式 |
---|---|---|
6443,8080 | kube-apiserver | 未授权访问获取kube-system的token,通过kubectl使用kube-system的token获取pod列表。之后可进一步创建pod或控制已有pod进行命令执行等操作。 |
10250,10255 | kubelet | kubeletctl批量获取pod等信息,尝试获取pod内/var/run/secrets/kubernetes.io/serviceaccoun/的token |
2379 | etcd | 导出全量etcd配置,获取k8s认证证书等关键信息,进而通过kubectl创建恶意pod或控制已有pod,后续可尝试逃逸至宿主机 |
30000以上 | dashboard | 配置问题导致可跳过认证进入后台 |
2375 | docker | Docker daemon默认监听2375端口且未鉴权,我们可以利用API来完成Docker客户端能做的所有事情。 |
1、组件接口存在的风险
API Server
API Server 默认服务端口为 8080 和 6443,8080 端口提供 HTTP 服务,没有认证与授权机制,而 6443 提供 HTTP 服务,支持认证和授权服务。
默认情况下 8080 端口不启动,但如果用户开启了该服务,就会造成 API Server 的未授权访问,从而控制整个集群。
Kubelet
与 API Server 类似,Kubelet 也运行着 API 服务,默认服务端口为 10250 和 10248
Kubelet 存在的风险主要也是未授权访问,如果 Kubelet 存在未授权访问,就可以控制所在节点的权限。
Dashboard
Dashboard 默认端口为 8001,从 1.10.1 版本起,Dashboard 默认禁用了跳过按钮,但如果用户为了方便或者其他原因,开启了相关功能,就会导致 Dashboard 的未授权访问。
etcd
etcd 默认监听 2379、2380 端口,前者用于客户端连接,后者用于多个 etcd 实例之间的通信。
默认情况下,etcd 提供的两个端口都需要相应的证书才能访问,但如果 RT 窃取了证书,或者用户将 etcd 设置了允许匿名访问,那么 RT 就可以直接访问 etcd 并窃取数据。
由于 Kubernetes 集群内部的各种资源及其状态都存在 etcd 中,因此如果可以读取 etcd 的数据,就可能获得高权限,从而控制集群。
2、集群网络存在的风险
Pod 是由一个或多个容器构成的集合,在没有其他网络隔离策略和 Pod 安全策略的默认情况下,由于 Pod 与 Pod 之间可以联通,且 Pod 内的 root 用户具有 CAP_NET_RAW 权限(即允许使用原始套接字的权限),因此集群内部可能会发生内网横向的风险。
3、访问控制机制存在的风险
Kubernetes 中的访问控制机制主要由认证机制、授权机制和准入机制三个部分组成。
如果访问控制比较宽松或混乱或者允许 Kubernetes 的未授权访问,RT 可能借此直接获得集群管理员权限。
4、无法根治的软件漏洞
Kubernetes 自身也被爆出许多安全漏洞,这类自然也属于 Kubernetes 所面临的的风险。