当前位置:网站首页 > 黑客培训 > 正文

手把手搭建 k8s docker 漏洞环境

freebuffreebuf 2022-05-12 307 0

本文来源:

一、前言

此环境为复现 docker 以及 k8s 容器逃逸的集成漏洞环境。

涉及以下漏洞:

1、docker privileged 特权模式

2、参数SYS_ADMIN导致cgroup逃逸

3、proc挂载

4、docker remote api 未授权

5、挂载sock文件

6、脏牛内核逃逸(此条划掉,没符合漏洞版本的linux,而且在实战中这个漏洞也很少遇到,大家直接靶场lampiao复现一下这个洞就可以)

7、1day runc

8、k8s鉴权配置不当

9、k8s日志挂载

10、k8s账户权限配置不当

二、准备工作

使用huawei欧拉服务器V2.0 SP5

https://euleros2019.obs.cn-north-1.myhuaweicloud.com/ict/site-euleros/euleros/repo/yum/2.5/os/x86_64/iso/EulerOS-V2.0SP5-x86_64-dvd.iso

准备两台服务器(虚拟机)

master主服务器 192.168.88.180 k8s-master

node节点服务器 192.168.88.181 k8s-node

集群服务器至少2h2g30G

注意事项:

1、查看hostname如果是localhost,请使用以下命令进行修改

hostnamectl set-hostname test101

2、两台服务器的/etc/hosts文件中需添加如下配置

master主机IP 主机名

node节点IP 主机名

3、保持两台机器时间同步

利用date命令查看,不一致使用命令进行同步

ntpdate ntp1.aliyun.com

若更新源没问题,则进行第三步:安装,若有问题则看第四步:遇到的问题及解决方案。

三、安装

1、安装依赖

yum install go

yum install git

yum -y install gcc automake autoconf libtool make

把container-selinux-2.107-3.el7.noarch.rpm、runc.sh、privileged.sh放到两台机器上

http://ftp.riken.jp/Linux/cern/centos/7/extras/x86_64/Packages/container-selinux-2.107-3.el7.noarch.rpm

#runc.sh #!/bin/bash #sunian echo "查找原有libseccomp进行删除" results=`yum list installed|grep libseccomp` if test ! -z "$results";then 	yum -y remove $results 	echo "删除完毕" else  echo "已删除,进行下一步" fi `mkdir -p /home/runc` `cd /home/runc` `wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libseccomp-2.3.1-4.el7.x86_64.rpm` rpm -ivh libseccomp-2.3.1-4.el7.x86_64.rpm `wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libseccomp-devel-2.3.1-4.el7.x86_64.rpm` rpm -ivh libseccomp-devel-2.3.1-4.el7.x86_64.rpm `mkdir -p $HOME/go/src/github.com` `go get github.com/opencontainers/runc` cd $HOME/go/src/github.com/opencontainers/runc git checkout v1.0.0-rc5 echo -e "\033[31m `git status` \033[0m" make make install echo -e "\033[31m `runc -v` \033[0m" 

注释:查找原有libseccomp进行删除,从官网下载所需libseccomp和libseccomp-devel进行rpm安装,利用go从github下载带有漏洞版本的runc v1.0.0-rc5并编译。

#privileged.sh #!/bin/bash #sunian echo "查找原有docker进行删除" results=`yum list installed|grep docker` if test ! -z "$results";then 	yum -y remove $results 	echo "删除完毕" else  echo "已删除,进行下一步" fi #开始安装存在漏洞版本docker echo "创建并安装docker的依赖" echo "安装在/home/privileged目录下" mkdir -p /home/privileged mv /root/container-selinux-2.107-3.el7.noarch.rpm /home/privileged cd /home/privileged rpm --force --nodeps -ivh container-selinux-2.107-3.el7.noarch.rpm `wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-18.06.0.ce-3.el7.x86_64.rpm` rpm -ivh docker-ce-18.06.0.ce-3.el7.x86_64.rpm `service docker start` echo `docker version` echo -e "\033[31m `docker images` \033[0m" 

注释:删除原有的docker,安装docker的依赖 即container-selinux,安装存在漏洞版本的docker,执行docker images并输出,查看是否安装成功。

2、配置k8s及安装

(1)系统设置:

安装nfs以及wget

yum install -y nfs-utils

yum install -y wget

关闭防火墙

systemctl stop firewalld

systemctl disable firewalld

关闭selinux

setenforce 0

sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

关闭swap分区

swapoff -a

yes | cp /etc/fstab /etc/fstab_bak

cat /etc/fstab_bak |grep -v swap > /etc/fstab

将桥接的IPv4 IPv6流量传递到iptables的链(直接shell脚本):

# 如果有配置,则修改 sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g"  /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g"  /etc/sysctl.conf sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g"  /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g"  /etc/sysctl.conf sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g"  /etc/sysctl.conf sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g"  /etc/sysctl.conf sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g"  /etc/sysctl.conf # 可能没有,追加 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf echo "net.ipv6.conf.all.forwarding = 1"  >> /etc/sysctl.conf # 执行命令以应用 sysctl -p 

(2)配置k8s源

cat < /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg        http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF 

(3)安装k8s

yum remove -y kubelet kubeadm kubectl

yum install -y kubelet-1.18.2 kubeadm-1.18.2 kubectl-1.18.2

sudo systemctl daemon-reload

sudo systemctl enable docker

sudo systemctl restart docker

systemctl enable kubelet && systemctl start kubelet

(到此两台机器都有runc、docker、k8s工具(kubeadm kubectl kubelet))

(4)接下来开始初始化服务器master节点(node服务器无需操作)

# 只在 master 节点执行 # export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令 export MASTER_IP=192.168.88.180 # 替换 apiserver.demo 为 您想要的 dnsName export APISERVER_NAME=apiserver.demo # Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中 export POD_SUBNET=172.18.0.1/16 echo "${MASTER_IP}    ${APISERVER_NAME}" >> /etc/hosts 

创建init_master.sh

#!/bin/bash # 脚本出错时终止执行 set -e  if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then   echo -e "\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m"   echo 当前POD_SUBNET=$POD_SUBNET   echo 当前APISERVER_NAME=$APISERVER_NAME   exit 1 fi   # 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2 rm -f ./kubeadm-config.yaml cat < ./kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration kubernetesVersion: v1.18.2 imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers controlPlaneEndpoint: "${APISERVER_NAME}:6443" networking:   serviceSubnet: "10.96.0.0/16"   podSubnet: "${POD_SUBNET}"   dnsDomain: "cluster.local" EOF  # kubeadm init # 根据您服务器网速的情况,您需要等候 3 - 10 分钟 kubeadm init --config=kubeadm-config.yaml --upload-certs  # 配置 kubectl rm -rf /root/.kube/ mkdir /root/.kube/ cp -i /etc/kubernetes/admin.conf /root/.kube/config  # 安装 calico 网络插件 # 参考文档 https://docs.projectcalico.org/v3.13/getting-started/kubernetes/self-managed-onprem/onpremises echo "安装calico-3.13.1" rm -f calico-3.13.1.yaml wget https://kuboard.cn/install-script/calico/calico-3.13.1.yaml kubectl apply -f calico-3.13.1.yaml 

加权限执行进行初始化,预检有点慢,等一等

之后执行如下命令,直到所有的容器组处于 Running 状态

watch kubectl get pod -n kube-system -o wide

节点初始化状态为ready

kubectl get nodes -o wide

至此主机服务器安装完成

(5)配置node节点

在master服务器上获取join命令

kubeadm token create --print-join-command

node节点服务器执行该命令

# 只在 node 节点执行 # 192.168.88.180 为 master 节点的内网 IP export MASTER_IP=192.168.88.180 # 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME export APISERVER_NAME=apiserver.demo echo "${MASTER_IP}   ${APISERVER_NAME}" >> /etc/hosts 执行master服务器获取的join命令 

最后master服务器执行命令

kubectl get nodes -o wide

查看node节点服务器直到ready,至此安装完成

四、遇到的问题及解决方案

1、若无更新源或源有问题(如 无想要的包),可使用以下更新源

Makefile 在/etc/yum.repos.d/目录下,创建文件EulerOS.repo  [base] name=EulerOS-2.0SP5 base baseurl=http://repo.huaweicloud.com/euler/2.5/os/x86_64/ enabled=1 gpgcheck=1 gpgkey=http://repo.huaweicloud.com/euler/2.5/os/RPM-GPG-KEY-EulerOS  执行yum clean all清除原有yum缓存。 执行yum makecache生成新的缓存。 yum update更新 

2、go版本的问题,1.16以下的go版本不支持io/fs,但是该报错不影响后续运行

3、若使用centos,期间可能出现的问题:

网络问题,主要是go下载runc时请求github网络问题,解决方案:临时环境变量,使用aliyun go源

export GOPROXY=https://mirrors.aliyun.com/goproxy/

4、如果docker未启动

service docker start

5、10250端口占用

[ERROR Port-10250]: Port 10250 is in use

解决方法:

kubeadm reset

6、修改docker为cgroups或systemd驱动

cat > /etc/docker/daemon.json <{  "exec-opts": ["native.cgroupdriver=systemd"],  "log-driver": "json-file",  "log-opts": {    "max-size": "100m"  },  "storage-driver": "overlay2",  "storage-opts": [    "overlay2.override_kernel_check=true"  ] } EOF 

systemctl daemon-reload && systemctl restart docker

7、rpm安装docker缺少依赖

报错如下

libcgroup is needed by docker-ce-18.06.0.ce-3.el7.x86_64

libltdl.so.7()(64bit) is needed by docker-ce-18.06.0.ce-3.el7.x86_64

解决方案:

http://mirror.centos.org/centos/7/os/x86_64/Packages/ 安装以下依赖

libcgroup-0.41-21.el7.x86_64.rpm

libtool-ltdl-2.4.2-22.el7_3.x86_64.rpm

8、nodeRegistration.name: Invalid value

hostname或dnsname不能用下划线,只能用'-'或'.'。

转载请注明来自网盾网络安全培训,本文标题:《手把手搭建 k8s docker 漏洞环境》

标签:k8sdocker漏洞

关于我

欢迎关注微信公众号

关于我们

网络安全培训,黑客培训,渗透培训,ctf,攻防

标签列表